Home > Software design >  Powershell passing mandatory dynamic type variable to function
Powershell passing mandatory dynamic type variable to function

Time:12-28

I am implementing a function in Powershell which will perform REST calls. One of the parameters may differ in contents, depending on given scenarios. For instance, the body of the REST call may be a string or a hash table. How do you implement this within the CmdletBinding() declaration?

For instance

Function doRESTcall(){
[CmdletBinding()]
        param (
            [Parameter(Mandatory=$true)]
            [Hashtable]$headers
            [Parameter(Mandatory=$true)]
            [???????]$body # what type here??
        )
.
.
.
}

CodePudding user response:

To declare parameters where any type is allowed you can either not type-constrain the parameter at all or use type constraint [object] (System.Object), by doing so, no type conversion will be needed, since all objects in PowerShell inherit from this type.

It's worth mentioning that unconstrained parameters will allow $null as argument, to avoid this, [ValidateNotNull()] and / or [parameter(Mandatory)] can be used.

function Test-Type {
    param(
        [parameter(ValueFromPipeline, Mandatory)]
        [object]$Value
    )

    process
    {
        [pscustomobject]@{
            Type     = $Value.GetType().FullName
            IsObject = $Value -is [object]
        }
    }
}
PS /> 1, 'foo', (Get-Date) | Test-Type

Type            IsObject
----            --------
System.Int32        True
System.String       True
System.DateTime     True

CodePudding user response:

The correct way to tackel this is to create a ParameterSet:

Function doRESTcall(){
    [CmdletBinding()]
            param (
                [Parameter(Mandatory=$true, ParameterSetName = 'StringBody', Position = 0)]
                [Parameter(Mandatory=$true, ParameterSetName = 'HashBody', Position = 0)]
                [Hashtable]$headers,
                [Parameter(Mandatory=$true, ParameterSetName = 'StringBody', Position = 1)]
                [String]$Stringbody,
                [Parameter(Mandatory=$true, ParameterSetName = 'HashBody', Position = 1)]
                [Hashtable]$Hashbody
            )
    Write-Host 'Parameter set:' $PSCmdlet.ParameterSetName
    Write-Host 'StringBody:' $StringBody
    Write-Host 'HashBody:' $HashBody
}
doRESTcall @{a = 1} 'Test'

Yields

Parameter set: StringBody
StringBody: Test
HashBody:

Note: to accept a larger variety of dictionaries (like [Ordered]), I would use a [System.Collections.Specialized.OrderedDictionary] (rather than [Hashtable]) type for the concerned parameters.

  • Related