windows 将参数传递给 powershell 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19055778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 10:56:15  来源:igfitidea点击:

Passing parameters to powershell script

windowspowershellparameterscmd

提问by desto

I'm trying to run a powershell script from the run dialog (will be used as a scheduled task), and I'm having troubles passing parameters.

我正在尝试从运行对话框运行 powershell 脚本(将用作计划任务),但在传递参数时遇到了麻烦。

The script will take in two parameters, named title and msg. The script is located in: D:\Tasks Scripts\Powershell\script.ps1

该脚本将接受两个参数,名为 title 和 msg。该脚本位于:D:\Tasks Scripts\Powershell\script.ps1

This is what I'm trying to do:

这就是我想要做的:

powershell.exe -noexit 'D:\Tasks Scripts\Powershell\script.ps1' -title 'Hello world' -msg 'This is a test message'

But it fails upon reading the parameters.

但是读取参数失败。

Running .\script.ps1 -title 'Hello world' -msg 'This is a test message'on powershell works fine.

运行.\script.ps1 -title 'Hello world' -msg 'This is a test message'在PowerShell的正常工作。

采纳答案by Nate Hekman

Use -filebefore the path to your script:

-file在脚本路径之前使用:

powershell.exe -noexit -file 'D:\Tasks Scripts\Powershell\script.ps1' etc...

回答by robert4

I usually run powershell scripts from cmd.exe because this is portable (works out-of-the-box on others' computers, like developer folks or clients): no need to worry about Set-ExecutionPolicy or associating the .ps1 extension.

我通常从 cmd.exe 运行 powershell 脚本,因为它是可移植的(在其他人的计算机上开箱即用,例如开发人员或客户端):无需担心 Set-ExecutionPolicy 或关联 .ps1 扩展名。

I create the file with .cmd extension (instead of .ps1), and copy&paste a short, constant code to the first line(s) that invokes powershell.exe and passes the rest of the file to it.
Passing arguments is tricky. I have multiple variants of the constant code because the general case is painful.

我创建了带有 .cmd 扩展名(而不是 .ps1)的文件,然后将一个简短的常量代码复制并粘贴到调用 powershell.exe 并将文件的其余部分传递给它的第一行。
传递参数很棘手。我有多个常量代码的变体,因为一般情况很痛苦。

  1. when not passing arguments, the .cmd file looks like this:

    @powershell -c ".(iex('{#'+(gc '%~f0' -raw)+'}'))" & goto :eof
    # ...arbitrary PS code here...
    write-host hello, world!
    

    This uses the -Command argument of powershell.exe. Powershell reads the .cmd file as text, puts it in a ScriptBlock with the first line commented out, and evaluates it with the '.' command. Further command line argumentscan be added to the Powershell invocation as required (e.g. -ExecutionPolicy Unrestricted, -Sta etc.)

  2. when passing arguments that do not contain spaces or are 'single-quoted' (which is non-standard in cmd.exe), the one-liner is this:

    @powershell -c ".(iex('{#'+(gc($argv0='%~f0') -raw)+'}'))" %* & goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    param()declarations could be used as well, $argsis not obligatory.
    $argv0is used to compensate for the missing $MyInvocation.PS*info.
    Examples:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1] [2] [3] [4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  3. when passing arguments that are "double-quoted" but do not contain the & and ' characters, I use a two-liner to replace all " with '

    @echo off& set A= %*& set B=@powershell -c "$argv0='%~f0';.(iex('{'
    %B%+(gc $argv0|select -skip 2|out-string)+'}'))" %A:"='%&goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    (Note that the space is important in the A= %*assignment for the argument-less case.)
    Results:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  4. the most general case passes the arguments via environment variables thus Powershell's param()declaration does not work. In this case the arguments are expected to be "double-quoted" and may contain ' or & (except for the path of the .cmd file itself):

    ;@echo off & setlocal & set A=1& set ARGV0=%~f0
    ;:loop
    ;set /A A+=1& set ARG%A%=%1& shift& if defined ARG%A% goto :loop
    ;powershell -c ".(iex('{',(gc '%ARGV0%'|?{$_ -notlike ';*'}),'}'|out-string))"
    ;endlocal & goto :eof
    for ($i,$arg=1,@(); test-path -li "env:ARG$i"; $i+=1) { $arg += iex("(`${env:ARG$i}).Trim('`"')") }
    write-host this is $env:argv0 arguments: "[$($arg -join '] [')]"
    write-host arg[5] is ($arg[5]|%{if($_){$_}else{'$null'}})
    

    (Note that in the first line A=1&must not contain space.)
    Result:

    G:\>lala.cmd "a b" "c d" "e&f" 'g' "h^j"
    this is G:\lala.cmd arguments: [a b] [c d] [e&f] ['g'] [h^j]
    arg[5] is $null
    
  1. 不传递参数时,.cmd 文件如下所示:

    @powershell -c ".(iex('{#'+(gc '%~f0' -raw)+'}'))" & goto :eof
    # ...arbitrary PS code here...
    write-host hello, world!
    

    这使用 powershell.exe 的 -Command 参数。Powershell 将 .cmd 文件作为文本读取,将其放入 ScriptBlock 并注释掉第一行,并使用“.”对其进行评估。命令。 可以根据需要将更多命令行参数添加到 Powershell 调用中(例如 -ExecutionPolicy Unrestricted、-Sta 等)

  2. 当传递不包含空格或“单引号”(在 cmd.exe 中是非标准的)的参数时,单行是这样的:

    @powershell -c ".(iex('{#'+(gc($argv0='%~f0') -raw)+'}'))" %* & goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    param()声明也可以使用,$args不是强制性的。
    $argv0用于补偿丢失的$MyInvocation.PS*信息。
    例子:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1] [2] [3] [4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  3. 当传递“双引号”但不包含 & 和 ' 字符的参数时,我使用两行将所有 " 替换为 '

    @echo off& set A= %*& set B=@powershell -c "$argv0='%~f0';.(iex('{'
    %B%+(gc $argv0|select -skip 2|out-string)+'}'))" %A:"='%&goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    (请注意,空格在A= %*无参数情况下的赋值中很重要。)
    结果:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  4. 最一般的情况是通过环境变量传递参数,因此 Powershell 的param()声明不起作用。在这种情况下,参数应该是“双引号”并且可能包含 ' 或 &(.cmd 文件本身的路径除外):

    ;@echo off & setlocal & set A=1& set ARGV0=%~f0
    ;:loop
    ;set /A A+=1& set ARG%A%=%1& shift& if defined ARG%A% goto :loop
    ;powershell -c ".(iex('{',(gc '%ARGV0%'|?{$_ -notlike ';*'}),'}'|out-string))"
    ;endlocal & goto :eof
    for ($i,$arg=1,@(); test-path -li "env:ARG$i"; $i+=1) { $arg += iex("(`${env:ARG$i}).Trim('`"')") }
    write-host this is $env:argv0 arguments: "[$($arg -join '] [')]"
    write-host arg[5] is ($arg[5]|%{if($_){$_}else{'$null'}})
    

    (注意第一行A=1&不能包含空格。)
    结果:

    G:\>lala.cmd "a b" "c d" "e&f" 'g' "h^j"
    this is G:\lala.cmd arguments: [a b] [c d] [e&f] ['g'] [h^j]
    arg[5] is $null