Reputation: 33
I want to pass a variable to a new console, but I don't know how.
$server = "server_name"
Start-Process Powershell {
$host.ui.RawUI.WindowTitle = “Get-Process”
Invoke-Command -ComputerName $server -ScriptBlock {
Get-Process
}
cmd /c pause
}
Error message:
Invoke-Command : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again
Upvotes: 2
Views: 1658
Reputation: 437318
Start-Process
only accepts (one or more) strings as arguments, not a script block ({ ... }
).
{
and }
), which means that $server
is retained as-is (not expanded), and the child process that runs your command doesn't have a variable by that name defined, causing Invoke-Command
to fail due not receiving a value for -ComputerName
.Therefore, in order to incorporate variable values from the caller's scope, you must use string interpolation, using an expandable (double-quoted) string ("..."
) that encodes all arguments:[1]
$server = "server_name"
# Parameters -FilePath and -ArgumentList are positionally implied.
# For the resulting powershell.exe call, -Command is implied.
Start-Process powershell "
$host.ui.RawUI.WindowTitle = 'Get-Process'
Invoke-Command -ComputerName $server -ScriptBlock { Get-Process }
pause
"
A computer name ($server
, in your case) doesn't contain spaces, but any variable values that do would require embedded enclosing quoting inside the overall "..."
string, such as \`"$someVar\`"
(`"
escapes an "
inside a "..."
string in PowerShell, and the \
is additionally needed to escape the resulting verbatim "
for the PowerShell CLI, powershell.exe
).
For full robustness, additionally enclose the entire string value (implied -Command
argument) in embedded "..."
quoting ("`"...`""
).
You can make this a bit easier by using the here-string form of an expandable string (@"<newline>...<newline>"@
), inside of which you don't need to escape "
chars.
Example of a fully robust call:
$someVar = 'A value with spaces'
Start-Process powershell @"
-NoProfile -Command "
# Echo the value of $someVar
Write-Output \"$someVar\"
pause
"
"@
Note the use of -NoProfile
before -Command
, which suppresses loading of the profile files, which can speed up the call and makes for a more predictable execution environment.
[1] Technically, -ArgumentList
accepts an array of arguments, and while passing the pass-through arguments individually may be conceptually preferable, a long-standing bug unfortunately makes it better to encode all arguments in a single string - see this answer.
Upvotes: 4
Reputation: 2571
if you want to use param-
param([type]$p1 = , [type]$p2 = , ...)
or:
param(
[string]$server
)
Write-Host $a
./Test.ps1 "your server name"
Upvotes: 0