我试图从运行对话框(将用作一个计划的任务)运行一个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工作正常。
在脚本路径之前使用-file
:
powershell.exe -noexit -file 'D:\Tasks Scripts\Powershell\script.ps1' etc...
我通常从cmd.exe运行powershell脚本,因为这是可移植的(在其他人的计算机上开箱即用,例如开发人员或客户端):无需担心Set-ExecutionPolicy或关联.ps1扩展名。
我创建了扩展名为.cmd的文件(而不是.ps1),并将一个简短的常量代码复制并粘贴到调用powershell.exe的第一行,并将文件的其余部分传递给它。
传递参数是棘手的。 我有常数的多种变体,因为一般的情况是痛苦的。
当不传递参数时,.cmd文件如下所示:
@powershell -c ".(iex('{#'+(gc '%~f0' -raw)+'}'))" & goto :eof # ...arbitrary PS code here... write-host hello, world!
这使用powershell.exe的命令参数。 Powershell将.cmd文件作为文本读取,并将其放在第一行注释掉的ScriptBlock中,并使用'。'进行评估。 命令。 更多的命令行参数可以根据需要添加到Powershell调用(例如-ExecutionPolicy Unrestricted,-Sta等)
当传递不包含空格或“单引号”(在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]
当传递“双引号”但不包含“和”字符的参数时,我使用双引号将所有“与”
@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]
最常见的情况是通过环境变量传递参数,因此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 "ab" "cd" "e&f" 'g' "h^j" this is G:\lala.cmd arguments: [ab] [cd] [e&f] ['g'] [h^j] arg[5] is $null