如何将多个参数传递到PowerShell中的函数中?
如果我有一个接受多个字符串参数的函数,那么第一个参数似乎获得了分配给它的所有数据,其余的参数则作为空参数传入 快速测试脚本:如何将多个参数传递到PowerShell中的函数中?,powershell,syntax,parameter-passing,Powershell,Syntax,Parameter Passing,如果我有一个接受多个字符串参数的函数,那么第一个参数似乎获得了分配给它的所有数据,其余的参数则作为空参数传入 快速测试脚本: Function Test([string]$arg1, [string]$arg2) { Write-Host "`$arg1 value: $arg1" Write-Host "`$arg2 value: $arg2" } Test("ABC", "DEF") 生成的输出是 $arg1 value: ABC DEF $arg2 value: 正
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
生成的输出是
$arg1 value: ABC DEF
$arg2 value:
正确的输出应为:
$arg1 value: ABC
$arg2 value: DEF
在多台机器上,v1和v2之间似乎是一致的,所以很明显,我做错了什么。有人能确切指出什么吗?调用PowerShell(所有版本)中的函数时,参数是以空格分隔的,而不是以逗号分隔的。此外,括号是完全不必要的,如果
-Version 2
或更高版本处于活动状态,则会在PowerShell 2.0(或更高版本)中导致分析错误。括号内的参数仅在.NET方法中使用
function foo($a, $b, $c) {
"a: $a; b: $b; c: $c"
}
ps> foo 1 2 3
a: 1; b: 2; c: 3
调用PowerShell函数时不使用括号,也不使用逗号作为分隔符。尝试使用:
test "ABC" "DEF"
在PowerShell中,逗号(,)是一个数组运算符,例如
$a = "one", "two", "three"
它将
$a
设置为一个包含三个值的数组。我不知道您对该函数做了什么,但请看一下如何使用“param”关键字。在将参数传递到函数中时,它的功能要强大得多,并且使它更加用户友好。下面是微软关于它的一篇过于复杂的文章的链接。这并不像文章说的那么复杂
此外,以下是本网站上的一个示例:
查看它。如果您尝试:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test "ABC" "DEF"
PS > Test("ABC", "GHI") ("DEF")
PS > $var = "C"
PS > Test ("AB" + $var) "DEF"
你会得到:
$arg1 value: ABC GHI
$arg2 value: DEF
可见括号分隔了参数
如果您尝试:
PS > Test("ABC", "GHI") ("DEF")
PS > $var = "C"
PS > Test ("AB" + $var) "DEF"
你会得到:
$arg1 value: ABC
$arg2 value: DEF
现在,您可以立即发现括号的一些用处-空格不会成为下一个参数的分隔符-而是有一个eval函数。已经提供了正确的答案,但这个问题似乎非常普遍,足以为那些想要了解其微妙之处的人提供一些额外的细节 我本想添加这个作为一个注释,但我想包括一个说明——我从PowerShell函数的快速参考图表中撕下了这个。这假设函数f的签名是
f($a,$b,$c)
:
因此,可以使用空间分隔的位置参数或顺序独立的命名参数调用函数。其他缺陷表明,您需要注意逗号、括号和空格
进一步阅读,请参阅我的文章。这篇文章还包含一个指向快速参考/挂图的链接。我之前说过: 常见的问题是使用单数形式
$arg
,这是不正确的。它应该始终是复数形式,如$args
问题不是这样。事实上,$arg
可以是其他任何内容。问题在于逗号和括号的使用
我运行了以下有效的代码,输出如下:
代码:
Function Test([string]$var1, [string]$var2)
{
Write-Host "`$var1 value: $var1"
Write-Host "`$var2 value: $var2"
}
$var1 value: ABC
$var2 value: DEF
测试“ABC”“DEF”
输出:
Function Test([string]$var1, [string]$var2)
{
Write-Host "`$var1 value: $var1"
Write-Host "`$var2 value: $var2"
}
$var1 value: ABC
$var2 value: DEF
如果你是C++的爪哇/C++/Ruby/Python/PAC-A语言,你是本世纪的开发者,你想用逗号来调用你的函数,因为这是你一直以来所做的,那么你需要这样的东西:
$myModule = New-Module -ascustomobject {
function test($arg1, $arg2) {
echo "arg1 = $arg1, and arg2 = $arg2"
}
}
现在请致电:
$myModule.test("ABC", "DEF")
你会看到的
arg1 = ABC, and arg2 = DEF
您可以在函数中传递参数,如下所示:
function FunctionName()
{
Param ([string]$ParamName);
# Operations
}
如果您不知道(或不关心)将向函数传递多少个参数,也可以使用非常简单的方法,如
代码:
function FunctionName()
{
Write-Host $args
}
Function traceroute
{
Start-Process -FilePath "$env:systemroot\system32\tracert.exe" -ArgumentList $args -NoNewWindow
}
Test-Script "Hello" "World"
Test-Script -arg1 "Hello" -arg2 "World"
这将打印出所有的参数。例如:
FunctionName a b c 1 2 3
if($PsCmdlet.ParameterSetName -eq "Name")
{
Write-Host "Doing something with name here"
}
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
输出
a b c 1 2 3
我发现这在创建使用外部命令的函数时特别有用,这些命令可能有许多不同的(可选)参数,但依赖于所述命令提供语法错误反馈等
这里是另一个真实的例子(为tracert命令创建一个函数,我讨厌记住被截断的名称)
代码:
function FunctionName()
{
Write-Host $args
}
Function traceroute
{
Start-Process -FilePath "$env:systemroot\system32\tracert.exe" -ArgumentList $args -NoNewWindow
}
Test-Script "Hello" "World"
Test-Script -arg1 "Hello" -arg2 "World"
因为这是一个经常被浏览的问题,所以我想提一下PowerShell函数应该使用(动词-名词作为函数名)。 名称的动词部分标识cmdlet执行的操作。名称的名词部分标识执行操作的实体。此规则简化了高级PowerShell用户对cmdlet的使用 此外,还可以指定参数是否为必填项以及参数的位置:
function Test-Script
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$arg1,
[Parameter(Mandatory=$true, Position=1)]
[string]$arg2
)
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
要将参数传递给函数,可以使用位置:
function FunctionName()
{
Write-Host $args
}
Function traceroute
{
Start-Process -FilePath "$env:systemroot\system32\tracert.exe" -ArgumentList $args -NoNewWindow
}
Test-Script "Hello" "World"
Test-Script -arg1 "Hello" -arg2 "World"
或者指定参数名称:
function FunctionName()
{
Write-Host $args
}
Function traceroute
{
Start-Process -FilePath "$env:systemroot\system32\tracert.exe" -ArgumentList $args -NoNewWindow
}
Test-Script "Hello" "World"
Test-Script -arg1 "Hello" -arg2 "World"
不要像调用C#中的函数那样使用括号
我建议在使用多个参数时始终传递参数名,因为这样可读性更好 这是一个正确的
params
声明
看
这确实有效。这里有一些很好的答案,但我想指出一些其他的事情。函数参数实际上是PowerShell的亮点。例如,您可以在高级函数中使用命名参数或位置参数,例如:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
然后,您可以通过指定参数名来调用它,也可以只使用位置参数,因为您显式定义了它们。因此,这两种方法中的任何一种都会起作用:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23
尽管第二个示例提供了Name
,但第一个示例仍然有效,因为我们显式使用了参数名。第二个例子是基于位置的,所以Name
必须是第一个。如果可能,我总是尝试定义位置,以便两个选项都可用
PowerShell还能够定义参数集。它使用此方法代替方法重载,同样非常有用:
function Get-Something
{
[CmdletBinding(DefaultParameterSetName='Name')]
Param
(
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
[string] $Name,
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
[int] $Id
)
}
现在,函数将采用名称或id,但不能同时采用两者。您可以按位置或按名称使用它们。既然他们