[英]How to pass command-line arguments to a PowerShell ps1 file
For years, I have used the cmd/DOS/Windows
shell and passed command-line arguments to batch files.多年来,我一直使用
cmd/DOS/Windows
shell 并将命令行参数传递给批处理文件。 For example, I have a file, zuzu.bat
and in it, I access %1
, %2
, etc. Now, I want to do the same when I call a PowerShell
script when I am in a Cmd.exe shell
.例如,我有一个
zuzu.bat
文件,我在其中访问%1
、 %2
等。现在, when I am in a Cmd.exe shell
调用PowerShell
脚本时,我想做同样的事情。 I have a script, xuxu.ps1
(and I've added PS1 to my PATHEXT variable and associated PS1 files with PowerShell).我有一个脚本
xuxu.ps1
(我已将 PS1 添加到我的 PATHEXT 变量中,并与 PowerShell 关联的 PS1 文件)。 But no matter what I do, I seem unable to get anything from the $args
variable.但无论我做什么,我似乎都无法从
$args
变量中得到任何东西。 It always has length 0.它的长度始终为 0。
If I am in a PowerShell
shell, instead of cmd.exe
, it works (of course).如果我在
PowerShell
shell 中,而不是cmd.exe
,它可以工作(当然)。 But I'm not yet comfortable enough to live in the PowerShell environment full time.但我还不够舒服,无法全职生活在 PowerShell 环境中。 I don't want to type
powershell.exe -command xuxu.ps1 p1 p2 p3 p4
.我不想输入
powershell.exe -command xuxu.ps1 p1 p2 p3 p4
。 I want to type xuxu p1 p2 p3 p4
.我想输入
xuxu p1 p2 p3 p4
。
Is this possible, and if so, how?这可能吗?如果可以,怎么做?
The sample I cannot get to work is trivial, foo.ps1:我无法开始工作的样本是微不足道的,foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
}
The results are always like this:结果总是这样:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
This article helps.这篇文章有帮助。 In particular, this section:
特别是本节:
-File
-文件
Runs the specified script in the local scope ("dot-sourced"), so that the functions and variables that the script creates are available in the current session.
在本地范围内运行指定的脚本(“dot-sourced”),以便脚本创建的函数和变量在当前会话中可用。 Enter the script file path and any parameters.
输入脚本文件路径和任何参数。 File must be the last parameter in the command, because all characters typed after the File parameter name are interpreted as the script file path followed by the script parameters.
File 必须是命令中的最后一个参数,因为在 File 参数名称之后键入的所有字符都被解释为脚本文件路径,后跟脚本参数。
ie IE
powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3
means run the file myfile.ps1 and arg1 arg2 & arg3 are the parameters for the PowerShell script.表示运行文件 myfile.ps1 和 arg1 arg2 和 arg3 是 PowerShell 脚本的参数。
After digging through the PowerShell documentation, I discovered some useful information about this issue.在深入研究 PowerShell 文档后,我发现了一些关于此问题的有用信息。 You can't use the
$args
if you used the param(...)
at the beginning of your file;如果您在文件开头使用了
param(...)
,则不能使用$args
; instead you will need to use $PSBoundParameters
.相反,您将需要使用
$PSBoundParameters
。 I copy/pasted your code into a PowerShell script, and it worked as you'd expect in PowerShell version 2 (I am not sure what version you were on when you ran into this issue).我将您的代码复制/粘贴到一个 PowerShell 脚本中,它在 PowerShell 版本 2 中可以正常工作(我不确定您遇到此问题时使用的是哪个版本)。
If you are using $PSBoundParameters
(and this ONLY works if you are using param(...)
at the beginning of your script), then it is not an array, it is a hash table, so you will need to reference it using the key / value pair.如果您使用的是
$PSBoundParameters
(并且仅当您在脚本开头使用param(...)
时才有效),那么它不是一个数组,它是一个哈希表,因此您需要使用它来引用它键/值对。
param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
$Script:args+= "`$$key=" + $PSBoundParameters["$key"] + " "
}
write-host $Script:args
And when called with...当调用...
PS> ./foo.ps1 a b c d
The result is...结果是……
Num Args: 4
$p1=a $p2=b $p3=c $p4=d
OK, so first this is breaking a basic security feature in PowerShell.好的,首先这是破坏 PowerShell 中的一个基本安全功能。 With that understanding, here is how you can do it:
有了这种理解,您可以这样做:
You may want to put a -NoProfile
argument in there too depending on what your profile does.您可能还想在其中放置一个
-NoProfile
参数,具体取决于您的配置文件的用途。
You could declare your parameters in the file, like param:您可以在文件中声明参数,例如 param:
[string]$param1
[string]$param2
And then call the PowerShell file like so .\temp.ps1 param1 param2....param10
, etc.然后像这样调用 PowerShell 文件
.\temp.ps1 param1 param2....param10
等。
Maybe you can wrap the PowerShell invocation in a .bat
file like so:也许您可以将 PowerShell 调用包装在
.bat
文件中,如下所示:
rem ps.bat
@echo off
powershell.exe -command "%*"
If you then placed this file under a folder in your PATH
, you could call PowerShell scripts like this:如果随后将此文件放在
PATH
中的文件夹下,则可以像这样调用 PowerShell 脚本:
ps foo 1 2 3
Quoting can get a little messy, though:但是,引用可能会有点混乱:
ps write-host """hello from cmd!""" -foregroundcolor green
if you want to invoke ps1 scripts from cmd and pass arguments without invoking the script like如果您想从 cmd 调用 ps1 脚本并传递参数而不调用脚本,例如
powershell.exe script.ps1 -c test
script -c test ( wont work )
you can do the following您可以执行以下操作
setx PATHEXT "%PATHEXT%;.PS1;" /m
assoc .ps1=Microsoft.PowerShellScript.1
ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*
This is assuming powershell.exe is in your path这是假设 powershell.exe 在您的路径中
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype
You may not get "xuxu p1 p2 p3 p4" as it seems.您可能不会像看起来那样得到“xuxu p1 p2 p3 p4”。 But when you are in PowerShell and you set
但是当你在 PowerShell 中并且你设置
PS > Set-ExecutionPolicy Unrestricted -Scope CurrentUser
You can run those scripts like this:您可以像这样运行这些脚本:
./xuxu p1 p2 p3 p4
or或者
.\xuxu p1 p2 p3 p4
or或者
./xuxu.ps1 p1 p2 p3 p4
I hope that makes you a bit more comfortable with PowerShell.我希望这能让您对 PowerShell 更加熟悉。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.