问题
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.
The script will take in two parameters, named title and msg.
The script is located in: 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.
回答1:
Use -file before the path to your script:
powershell.exe -noexit -file 'D:\Tasks Scripts\Powershell\script.ps1' etc...
回答2:
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.
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.
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 arguments can be added to the Powershell invocation as required (e.g. -ExecutionPolicy Unrestricted, -Sta etc.)
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]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]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
来源:https://stackoverflow.com/questions/19055778/passing-parameters-to-powershell-script