Passing variables through Invoke-Command

I’m trying to get better “readability” with my script by declaring variables then passing those to the command, but I’m running into a snag. I think I know why, but I thought I’d check with the community at large.

Essentially I’ve got the following:

Param ( [String[]]$ComputerName="$env:COMPUTERNAME")

ForEach ($computer in $ComputerName)
{ 
$RegKey1='HKLM:\SOFTWARE\Stuff\*'
$RegKey2='HKLM:\SOFTWARE\More\Stuff\*'
Invoke-Command -ComputerName $Computer {Get-ItemProperty -path $RegKey1, $RegKey2 | Where-Object {$_.Value} | Select-Object Field1, Field2, Field3 | Format-Table -Autosize}
}

With the above code, I get an error “Cannot bind argument to parameter ‘Path’ because it is null.” If I take out $RegKey1 and $RegKey2 and type out the values I’ve declared above, the script works fine. Is this because the $RegKey1 and $RegKey2 are trying to resolve on the remote computer where they haven’t been declared?

See https://www.penflip.com/powershellorg/the-big-book-of-powershell-gotchas/blob/master/remote-variables.txt

$Using: is your friend. Check out below slightly refactored script.

Param (

    [String[]]
    $ComputerName="$env:COMPUTERNAME"
)

$Results = foreach ($computer in $ComputerName)
{
    $RegKey1='HKLM:\SOFTWARE\Stuff\*'
    $RegKey2='HKLM:\SOFTWARE\More\Stuff\*'

    $ScriptBlock = { 
        Get-ItemProperty -Path $Using:RegKey1, $Using:RegKey2 | 
            Where-Object { $_.Value } |
                Select-Object Field1, Field2, Field3
    }

    Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock
}

$Results | Format-Table -Autosize

Thank you sirs! It works like a charm.