Search code examples
powershell

Powershell: passing different data types to function


I have a function which gets the status of a remote windows service. 2 mandatory parameters. The first one can either be a string or a hash table, and the second is always a string (windows service status name). Example:

function Get-Service-Status([Parameter(ParameterSetName=‘string’, Position=0)][string] $groupString, [Parameter(ParameterSetName=‘hash’, Position=0)][string] $groupHash, [Parameter(ParameterSetName=‘string’, Position=1)][string] $status){
    if($PSCmdlet.ParameterSet -eq ‘string’){
        $myhash= Convert-To-Hash $groupString; 
        # function just returns @{“service”=“ABC”;”hostname”=“myhost”;};
    }else{
        $myhash= $groupHash;
    }
   …
}


# example usage: 
Get-Service-Status “ABC” “Running”

$service=@{“service”=“ABC”;”hostname”=“myhost”;};
Get-Service-Status $service “Running”

However this doesn’t seem to work and it will throw an error at line 1 char 1 that A positional parameter cannot be found that accepts argument “Running”

My intent was to try and make a polymorphic function where the same function can be used when passing params of different parameter type (where the type would be resolved inside the function, in this case, use hashtable if hashtable given and convert to hashtable if string given)


Solution

  • The error you see is because -status parameter is only available for the string Parameter Set and you're trying to use it in the hash set too. If you wanted this parameter to be available on both sets, then you should add a new [Parameter(...)] declaration using the hash Parameter Set.

    Other problem is that you have -groupHash typed as [string] when it should be [hashtable], otherwise the hash table will be coerced to a string and be unusable in your function.

    function Test {
        param(
            [Parameter(ParameterSetName = 'string', Position = 0)]
            [string] $groupString,
    
            [Parameter(ParameterSetName = 'hash', Position = 0)]
            [hashtable] $groupHash,
    
            [Parameter(ParameterSetName = 'hash', Position = 1)]
            [Parameter(ParameterSetName = 'string', Position = 1)]
            [string] $status)
    
        $PSBoundParameters
    }
    
    Test 'ABC' 'Running'
    
    # Key         Value
    # ---         -----
    # groupString ABC
    # status      Running
    
    $service = @{'service' = 'ABC'; 'hostname' = 'myhost' }
    Test $service 'Running'
    
    # Key       Value
    # ---       -----
    # groupHash {[hostname, myhost], [service, ABC]}
    # status    Running