0

Powershell script is only returning one value from Invoke-Command not all the objects I would expect.

I am adding a property to an existing object on a remote server then returning it back.

$inventory contains application objects that look like this:

Name         : Centinel-Dev-AmazonServer
Platform     : Centinel
Type         : Windows Service
Tier         : APP
Status       : Running

Name         : Portal-QA-Walmart
Platform     : Portal
Type         : Windows Service
Tier         : APP
Status       : Running

There are many more application objects similiar to the two given when I run my script it only returns the first object not all.

function verify_workingDir {
    param($server)
    $inventory = GetInventory -Server $server
    $return_object = @()
    $return_object += Invoke-Command -ComputerName $server -ScriptBlock {
        $inventory = $args[0]

        $return_object = @()
        foreach ($Application in $inventory) {

            $applicationParamters = Get-ItemProperty -Path x:\x\x\x\$($Application.Name)\Parameters


            $verify_object = [pscustomobject] @{
                WorkingDirectory = $applicationParamters.ServiceWorkingDir
            }


            $ExpandVerifyObject = $verify_object | Select-Object -Property @{
                Name       = "MyProperties"
                Expression = {$_.WorkingDirectory }
            } | Select-Object -ExpandProperty MyProperties

            Add-Member -MemberType NoteProperty -Name WorkingDirectory -InputObject $Application -TypeName PSObject -Value $ExpandVerifyObject
            $return_object += $Application    
        }

        return $return_object

    } -ArgumentList ($inventory) #| Select Name, Platform, Type, Tier, Status, ServerName, WorkingDirectory

    return $return_object
}

Answer:
  $inventory = $args[0] ---> $inventory = $args

1 Answer 1

1

Try $inventory = $args instead of $inventory = $args[0].

Passing arrays to script blocks is not the easiest thing because $args flattens everything to a single array. If you pass -ArgumentList @(1,2,3), 4, then $Args will be a single array @(1,2,3,4) and $Args[0] will be 1.

If you ever need to pass complex arguments with -ArgumentList, pass them all as a single HashTable: -ArgumentList @{FirstArg = @(1,2,3); SecondArg = 4}.

Sign up to request clarification or add additional context in comments.

8 Comments

Passing arrays to script blocks is not the easiest thing because $args flattens everything to a single array. Can you show example of this? I am trying Invoke-Command -Command { ConvertTo-Json -InputObject $args -Compress } -ArgumentList @(1,2,3),4 and get [[1,2,3],4] as result. No flattening here.
@PetSerAl This or this must be the problem I'm thinking of. The real problem comes when you need to pass multiple arrays as parameters, because -Arg (,$Arr1),$Val1,(,$Arr2) may not work at all.
because -Arg (,$Arr1),$Val1,(,$Arr2) may not work at all. Maybe it because you should use $Arr1,$Val1,$Arr2 instead. You should not write it like this (,$Arr1) unless you are passing only one argument.
@PetSerAl "You should not write it like this" Why? This works just fine: $x=@(1,2,3); $y = @((,$x),4,(,$x)); $y[0]; $y[1]; $y[2];. The fact that with Invoke-Command you have to say $x=@(1,2,3); Invoke-Command -Command { $args[0][0]; $args[1]; $args[2][0] } -ArgumentList @((,$x),4,(,$x)) is what's anomalous. The language should behave consistently and it doesn't here because of all the background encapsulation. That's why I say: stick all your arguments in a HashTable and pass arguments that way. It's the most consistent and obvious behavior.
This works just fine: $x=@(1,2,3); $y = @((,$x),4,(,$x)); $y[0]; $y[1]; $y[2];. But $y[0].Length; $y[2].Length; will return 1 and 1, but not 3 and 3.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.