6

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

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

这就是我想要做的:

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

但它在读取参数时失败。

.\script.ps1 -title 'Hello world' -msg 'This is a test message'在 powershell 上运行可以正常工作。

4

2 回答 2

4

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

powershell.exe -noexit -file 'D:\Tasks Scripts\Powershell\script.ps1' etc...
于 2013-09-27T22:05:06.417 回答
4

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

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

  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
    
于 2013-10-01T08:49:32.533 回答