PowerShell: Technique to Pass Array Variable as Argument

Problem:

The subtle difference between invoke-command -scriptblock {} -Args vs -ArgumentList is elusive enough to waste a coder’s time trying to understand why a forced casting of an Array type variable doesn’t behave as expected. Here’s an illustration for Google searchers who has stumbled upon this puzzle.

The Correct Method of Passing Array into Invoke-Command

$accountsToAdd='intranet\user1','intranet\user2'
$localgroup='Remote Desktop Users'

# Check on whether certain accounts exist in a local group
invoke-command -scriptblock{
            param($principleNames,$groupName)
            $results=@()
            $currentMembers=try{
                (get-localgroupmember $groupName -ea stop).Name
            }catch{
                $x=net localgroup $groupName
                $x[6..$($x.length-3)]
            }
            write-host "Current members of $groupName`:`r`n$($currentMembers|out-string)"
            foreach($principle in $principleNames){
                $results+=[pscustomobject]@{
                    computername=$env:computername
                    groupname=$groupName
                    userName=$principle
                    usernameIsMember=[bool]($principle -in $currentMembers)
                }
            }
            return $results
        } -ArgumentList $accountsToAdd,$localGroup

The Incorrect Method of Passing Array into Invoke-Command

$accountsToAdd='intranet\user1','intranet\user2'
$localgroup='Remote Desktop Users'

# Check on whether certain accounts exist in a local group
invoke-command -scriptblock{
            param($principleNames,$groupName)
            $results=@()
            $currentMembers=try{
                (get-localgroupmember $groupName -ea stop).Name
            }catch{
                $x=net localgroup $groupName
                $x[6..$($x.length-3)]
            }
            write-host "Current members of $groupName`:`r`n$($currentMembers|out-string)"
            foreach($principle in $principleNames){
                $results+=[pscustomobject]@{
                    computername=$env:computername
                    groupname=$groupName
                    userName=$principle
                    usernameIsMember=[bool]($principle -in $currentMembers)
                }
            }
            return $results
        } -Args (,$accountsToAdd),$localGroup
# Sample Output:

WARNING: Cannot convert 'intranet\user1 intranet\user2' to the type 'Microsoft.PowerShell.Commands.LocalPrincipal' required by parameter 'Member'. Specified method is not supported.
Failed to compare two elements in the array.

Leave a Reply

Your email address will not be published. Required fields are marked *