AndyB
AndyB

Reputation: 31

Invoke-Command won't accept -Path as a variable

I am trying to execute a simple Test-Path query to a remote computer using Invoke-Command, but I am struggling with a strange error.

This works:

Invoke-Command -ComputerName COMPUTER001 -ScriptBlock {Test-Path -Path "c:\windows\system.ini"}

This fails with "Cannot bind argument to parameter 'Path' because it is null.":

$p_FileName = "c:\windows\system.ini"
Invoke-Command -ComputerName COMPUTER001 -ScriptBlock {Test-Path -Path $p_FileName}

I have tried using both $p_FileName and $($p_FileName), but no luck.

Any suggestions, and hopefully an explanation as to what is happening?

Upvotes: 3

Views: 2422

Answers (3)

Straff
Straff

Reputation: 5759

Alternatives to @kevmar and @mjolinor (works for PS4 at least):

$p_FileName = "c:\windows\system.ini"
$sb = [scriptblock]::create("Test-Path $p_FileName")
Invoke-Command -ComputerName COMPUTER001 -ScriptBlock $sb

$p_FileName gets resolved on the local machine so COMPUTER001 receives

Test-Path c:\windows\system.ini

Upvotes: 0

kevmar
kevmar

Reputation: 808

You have a scope issue. The scope within the script block that runs on the remote server cannot access your local variables. There are several ways around this. My favorite is the $Using: scope but a lot of people do not know about it.

$p_FileName = "c:\windows\system.ini"
Invoke-Command -ComputerName COMPUTER001 -ScriptBlock {Test-Path -Path $Using:p_FileName}

For invoke command, this lets you use local variables in the script block. This was introduced for use in workflows and can also be used in DSC script blocks.

Upvotes: 2

mjolinor
mjolinor

Reputation: 68341

You have to pass local variables used in the script block through the -ArgumentList parameter:

$p_FileName = "c:\windows\system.ini"
Invoke-Command -ComputerName COMPUTER001 -ScriptBlock {Test-Path -Path $args[0]} -ArgumentList $p_FileName

Upvotes: 4

Related Questions