Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell: Issue with & in scriptblock

I face an issue when I run the following command

$x =  "c:\Scripts\Log3.ps1"
$remoteMachineName = "172.16.61.51"
Invoke-Command -ComputerName $remoteMachineName  -ScriptBlock {& $x}

The expression after '&' in a pipeline element produced an invalid object. It must result in a command name, script
block or CommandInfo object.
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : BadExpression
    + PSComputerName        : 172.16.61.51

Issue is not seen if I dont use $x variable

Invoke-Command -ComputerName $remoteMachineName  -ScriptBlock {& 'c:\scripts\log3.ps1'}

    Directory: C:\scripts


Mode                LastWriteTime     Length Name                                  PSComputerName
----                -------------     ------ ----                                  --------------
-a---         7/25/2013   9:45 PM          0 new_file2.txt                         172.16.61.51
like image 299
user2622678 Avatar asked Jul 26 '13 12:07

user2622678


People also ask

What is the use of @() in PowerShell?

Array subexpression operator @( )Returns the result of one or more statements as an array. The result is always an array of 0 or more objects.

What is %{ in PowerShell?

% alias for ForEach-Object. The % symbol represents the ForEach-Object cmdlet. It allows you to perform an action against multiple objects when that action normally only works on one object at a time.


2 Answers

Variables in your PowerShell session are not transferred to sessions created with Invoke-Command

You need to use the -ArgumentList parameter to send the variables your command and then use the $args array to access them in the script block so your command will look like:

Invoke-Command -ComputerName $remoteMachineName  -ScriptBlock {& $args[0]} -ArgumentList $x
like image 156
Stanley De Boer Avatar answered Sep 26 '22 16:09

Stanley De Boer


If you work with variables inside a script block you need to add the modifier using:. Otherwise Powershell would search for the var definition inside the script block.

You can use it also with the splatting technique. E.g.:@using:params

Like this:

# C:\Temp\Nested.ps1
[CmdletBinding()]
Param(
 [Parameter(Mandatory=$true)]
 [String]$Msg
)

Write-Host ("Nested Message: {0}" -f $Msg)

# C:\Temp\Controller.ps1
$ScriptPath = "C:\Temp\Nested.ps1"
$params = @{
    Msg = "Foobar"
}
$JobContent= {
    & $using:ScriptPath @using:params
}
Invoke-Command -ScriptBlock $JobContent -ComputerName 'localhost'
like image 22
OCram85 Avatar answered Sep 26 '22 16:09

OCram85