How to handle command-line arguments in PowerShell
处理命令行参数的"最佳"方法是什么?
似乎对于"最好"的方式有几个答案,因此,我一直坚持如何处理简单的事情,如:
1
| script.ps1 /n name /d domain |
和
1
| script.ps1 /d domain /n name. |
有没有一个插件可以更好地处理这个问题?我知道我在这里重新发明轮子。
显然,我已经拥有的并不漂亮,当然也不是"最好的",但它是有效的。而且很难看。
1 2 3 4 5 6 7 8
| 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 |
你在重新发明轮子。普通PowerShell脚本的参数以-开头,如script.ps1 -server http://devserver
然后在文件开头的param部分处理它们。
您还可以为参数分配默认值,如果不可用,则从控制台读取这些值,或者停止脚本执行:
1 2 3 4 5
| param (
[string]$server ="http://defaultserver",
[Parameter(Mandatory=$true)][string]$username,
[string]$password = $( Read-Host"Input password, please" )
) |
在脚本中,您可以简单地
因为所有参数都成为脚本范围内可用的变量。
在本例中,如果不调用脚本,则$server将获取默认值;如果省略-username参数,则脚本将停止;如果省略-password参数,则请求终端输入。
更新:您也可以向PowerShell脚本传递"flag"(布尔型真/假参数)。例如,当不使用force时,脚本可以接受"force",在这种情况下,脚本以更谨慎的模式运行。
关键字是[switch]参数类型:
1 2 3 4 5
| param (
[string]$server ="http://defaultserver",
[string]$password = $( Read-Host"Input password, please" ),
[switch]$force = $false
) |
在脚本中,您可以这样处理它:
1 2 3
| if ($force) {
//deletes a file or does something"bad"
} |
现在,在调用脚本时,您可以这样设置switch/flag参数:
1
| .\yourscript.ps1 -server"http://otherserver" -force |
如果您显式地想要声明没有设置标志,那么有一个特殊的语法来说明这一点。
1
| .\yourscript.ps1 -server"http://otherserver" -force:$false |
指向相关Microsoft文档的链接(对于PowerShell 5.0;THO版本3.0和4.0也可在链接中找到):
- 事实上,PowerShell的一大优势在于它提供了一个易于使用的标准参数解析基础结构。
- @naivists,从PowerShell 2.0而不是[string]$username = $(throw"-username is required."),强制参数有语法:[Parameter(Mandatory=$true)][string]$username。以下是关于这些技术之间差异的更多信息:blogs.technet.com/b/heyscriptingguy/archive/2011/05/22/…
- 当没有提供arg时,请注意该错误;PowerShell将从命令行中获取任何额外的文本:.yourscript.ps1-server"serv"-password"mypass"typo这将神奇地将"typo"分配给$username。
- 这太棒了!你能把这个做成文件吗?但有一个问题:如何处理没有-option标记的参数?
- 不过,使用参数块似乎还有其他意想不到的后果:stackoverflow.com/questions/409480819/…
- @她:那不是虫子!PowerShell将按给定的顺序处理和分配参数,除非使用正确的参数名称覆盖,例如,如果参数块列表:$user$pass$server,并且您执行了您的script.ps1 a b c,则A将设置为$user,B将设置为$pass,C将设置为$server,除非您指定了它们!因此,如果您说:yourscript.ps1-pass a b c,$pass将被设置为a,其余(未命名)参数将按参数块中列出的顺序用于填充缺少的参数,因此$user=b,$server=c。
- 做用户名和密码的更好方法是使用Credential类型,这将在输入和存储时注意隐藏密码作为SecureString类型。(我并没有完全按照SecureString的价值出售,但至少它降低了意外打印到输出中的风险。)