如何在PowerShell中处理命令行参数


494

处理命令行参数的“最佳”方法是什么?

关于“最佳”方式的问题似乎有几个答案,结果,我被困在如何处理简单的事情上:

script.ps1 /n name /d domain

script.ps1 /d domain /n name.

是否有可以更好地处理此问题的插件?我知道我在这里重新发明轮子。

显然,我已经不是很漂亮,而且肯定不是“最好的”,但是它可以工作..而且很丑。

for ( $i = 0; $i -lt $args.count; $i++ ) {
    if ($args[ $i ] -eq "/n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "/d"){ $strDomain=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-d"){ $strDomain=$args[ $i+1 ]}
}
Write-Host $strName
Write-Host $strDomain

Answers:


917

您正在重新发明轮子。正常的PowerShell脚本具有以开头的参数-,例如script.ps1 -server http://devserver

然后param,在文件开头的部分中处理它们。

您还可以为参数分配默认值,如果不可用,则从控制台读取默认值,或者停止脚本执行:

 param (
    [string]$server = "http://defaultserver",
    [Parameter(Mandatory=$true)][string]$username,
    [string]$password = $( Read-Host "Input password, please" )
 )

在脚本中,您可以简单地

write-output $server

因为所有参数都变为脚本作用域中可用的变量。

在此示例中,$server如果在没有脚本的情况下调用脚本,则将获取默认值;如果省略该-username参数,则脚本将停止,如果省略则要求终端输入-password

更新:您可能还希望将“ flag”(布尔值true / false参数)传递给PowerShell脚本。例如,您的脚本可能会接受“强制”,在不使用强制的情况下,脚本将以更谨慎的模式运行。

关键字是[switch]参数类型:

 param (
    [string]$server = "http://defaultserver",
    [string]$password = $( Read-Host "Input password, please" ),
    [switch]$force = $false
 )

在脚本内部,您可以像这样使用它:

if ($force) {
  //deletes a file or does something "bad"
}

现在,当调用脚本时,您可以这样设置switch / flag参数:

.\yourscript.ps1 -server "http://otherserver" -force

如果您明确要声明未设置标志,则有一种特殊的语法

.\yourscript.ps1 -server "http://otherserver" -force:$false

指向相关的Microsoft文档的链接(对于PowerShell 5.0;版本3.0和4.0也可以从链接获得):


58
确实,PowerShell的一大优点是它提供了易于使用的标准参数解析基础结构。
基思·希尔

14
@naivists,来自PowerShell 2.0,而不是[string]$username = $(throw "-username is required.")强制性参数的语法:[Parameter(Mandatory=$true)][string]$username。以下是有关这些技术之间的区别更多的信息:blogs.technet.com/b/heyscriptingguy/archive/2011/05/22/...
v.karbovnichy

7
当未提供arg时,请提防该错误;powershell将仅从命令行获取任何其他文本:。\ yourscript.ps1 -server“ serv ” -password“ mypass”错字这将神奇地将'typo'分配给$ username。
sheamus

4
使用参数块似乎还会产生其他意外后果:stackoverflow.com/questions/40940819/…–
Logan

1
@sheamus:这不是错误!Powershell将按照给定的顺序处理和分配参数,除非使用适当的参数名称覆盖,例如,如果您的参数块列出:$ user $ pass $ server,并且您执行yourscript.ps1 abc,则a将为设为$ user,b设为$ pass,c设为$ server,除非您专门为其分配!因此,如果您说:yourscript.ps1 -pass abc,则$ pass将设置为a,其余(未命名)参数将用于按参数块中列出的顺序填充缺失的参数,因此$ user = b,$ server = c。
Fernando Madruga
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.