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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.