Home > Enterprise >  How to pass ArrayList to Invoke-Command which runs on remote machine
How to pass ArrayList to Invoke-Command which runs on remote machine

Time:10-22

I had a piece of code which deletes Google Chrome cache for all user profiles on remote machine.

To achieve this I had function GetMachineUserProfiles which returns ArrayList of all user profiles on remote machine. In other function I need to run Invoke-Command and loop through all user profiles given with $ListOfUserProfiles and delete Chrome cache for each profile.

But I run into a problem, $ListOfUserProfiles is empty/null inside my Invoke-Command. I tried several solutions but failed each time. My last try is shown in example:

$ListOfUserProfiles = GetMachineUserProfiles
$ListOfUserProfiles.count

Function Delete-Chrome-Temp-Files {
    WriteLog "--------------------------------`n"
    WriteLog "COMMAND: Delete Chrome temporary files"
    $diskSpaceBeforeC = Disk-Free-Space
    $ListOfUserProfiles.count
    Invoke-Command -ComputerName $machine -ArgumentList (, $ListOfUserProfiles) -ScriptBlock {
        $ListOfUserProfiles.count
            foreach ($UserProfile in $ListOfUserProfiles){
                Write-Host $UserProfile
                Get-ChildItem -Path "C:\Users\"$UserProfile"\AppData\Local\Google\Chrome\User Data" -Filter "*.tmp" | foreach { 
                Remove-Item -Path $_.FullName 
                WriteLog "INFO: Deleting $($_.FullName)"    
            }
        }
    }
Delete-Chrome-Temp-Files

There are 6 profiles on my machine, and you can see I used count method 3 times here, and they return:

6

6

0 (I expect 6 here)

CodePudding user response:

The variable $ListOfUserProfiles only exist in your local scope - when you pass $ListOfUserProfiles as part of -ArgumentList, PowerShell passes the value of the variable to the remote session, but it doesn't recreate the variable itself.

To do so, either dereference the corresponding $args item:

Invoke-Command -ComputerName $machine -ArgumentList (, $ListOfUserProfiles) -ScriptBlock {
    $ListOfUserProfiles = $args[0]
    # ... rest of scripblock as before
}

... or declare it as a positional parameter and let PowerShell bind the value for you:

Invoke-Command -ComputerName $machine -ArgumentList (, $ListOfUserProfiles) -ScriptBlock {
    param([System.Collections.ArrayList]$ListOfUserProfiles)
    # ... rest of scripblock as before
}
  • Related