简体   繁体   中英

How to pass a variable to new console window in Powershell

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

  • Start-Process only accepts (one or more) strings as arguments, not a script block ( {... } ).

    • While a script block is accepted , it is simply stringified , which results in its verbatim content being passed as the argument (sans { 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 .

if you want to use param-

info

param([type]$p1 = , [type]$p2 = , ...)

or:

info

param(
[string]$server 
)

Write-Host $a

./Test.ps1 "your server name"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM