接受位置绑定参数作为参数的函数,但也来自管道
Function that accepts position-bound parameters as arguments, but also from pipeline
我正在尝试创建一个日志记录函数,它接受管道位置绑定参数和位置绑定参数。但是,我不断收到以下代码的错误:
Function Test
{
[CmdletBinding(SupportsShouldProcess,DefaultParameterSetName='def')]
Param(
[Parameter(Position=0,ParameterSetName='def')]
[String]$Pos1,
[Parameter(ValueFromPipeline,Position=1,ParameterSetName='pip')]
[String]$InputObject,
[Parameter(Position=1,ParameterSetName='def')]
[Parameter(Position=0,ParameterSetName='pip')]
[String]$State
)
Process
{
Switch ($PScmdlet.ParameterSetName)
{
'def' {Write-Host "${State}: $Pos1"}
'pip' {Write-Host "${State}: $InputObject"}
}
}
}
PS C:\> 'this' | Test 'error'
test : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:10
+ 'test' | test 'error'
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (test:String) [Test], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Test
我可以通过以下示例获取函数的位置绑定管道调用:
Function Test
{
Param(
[Parameter(Position=1,ValueFromPipeline)]
[String]$Msg,
[Parameter(Position=0)]
[String]$State
)
Process
{
Write-Host "${State}: $Msg"
}
}
PS C:\> 'this' | Test 'error'
error: this
所以我的问题是:我如何创建一个函数来在命令行 (Test 'message' 'status'
) 和管道 ('message' | Test 'status'
) 中获取位置绑定的参数,而无需显式调用参数名称 ('message' | Test -State 'status'
)?
让我们用后一个脚本中的以下代码片段替换 Process { Write-Host "${State}: $Msg" }
块,以生成更具指导意义的输出并从中获取信息:
Process
{
### Write-Host "${State}: $Msg"
Write-Host "State=$State`t Msg=$Msg" -NoNewline
Write-Host "`t`t`t`t$($MyInvocation.Line.trim())" -ForegroundColor Cyan
}
然后,检查 output 以获得(几乎)所有可能的参数组合:
PS D:\PShell>
'this' | Test -State 'error'
'this' | Test 'error'
Test -Msg 'this' -State 'error'
Test -Msg 'this' 'error'
Test 'this' -State 'error'
Test 'this' 'error'
State=error Msg=this 'this' | Test -State 'error'
State=error Msg=this 'this' | Test 'error'
State=error Msg=this Test -Msg 'this' -State 'error'
State=error Msg=this Test -Msg 'this' 'error'
State=error Msg=this Test 'this' -State 'error'
State=this Msg=error Test 'this' 'error'
PS D:\PShell>
我们可以看到 Test 'this' 'error'
的不同输出(没有管道 和 行中没有明确命名的参数)。因此,Test 'error' 'this'
可以给出“正确的”结果。
另一种方法:让我们改变脚本输出如下:
Function Test
{
Param(
[Parameter(Position=1,ValueFromPipeline)]
[String]$Msg,
[Parameter(Position=0)]
[String]$State
)
Process
{
#Write-Host "${State}: $Msg"
$auxLine = $MyInvocation.Line.split( ' ',
[System.StringSplitOptions]::RemoveEmptyEntries)
if ( $auxLine[0] -eq $MyInvocation.InvocationName -and
'-Msg' -notin $auxLine -and
'-State' -notin $auxLine )
{
Write-Host "State=$Msg`t Msg=$State" -NoNewline
Write-Host "`tALTERED`t`t$($MyInvocation.Line.trim())" -ForegroundColor Yellow
} else {
Write-Host "State=$State`t Msg=$Msg" -NoNewline
Write-Host "`t`t`t`t$($MyInvocation.Line.trim())" -ForegroundColor Cyan
}
}
}
输出:
PS D:\PShell>
'this' | Test -State 'error'
'this' | Test 'error'
Test -Msg 'this' -State 'error'
Test -Msg 'this' 'error'
Test 'this' -State 'error'
Test 'this' 'error'
State=error Msg=this 'this' | Test -State 'error'
State=error Msg=this 'this' | Test 'error'
State=error Msg=this Test -Msg 'this' -State 'error'
State=error Msg=this Test -Msg 'this' 'error'
State=error Msg=this Test 'this' -State 'error'
State=error Msg=this ALTERED Test 'this' 'error'
PS D:\PShell>
我正在尝试创建一个日志记录函数,它接受管道位置绑定参数和位置绑定参数。但是,我不断收到以下代码的错误:
Function Test
{
[CmdletBinding(SupportsShouldProcess,DefaultParameterSetName='def')]
Param(
[Parameter(Position=0,ParameterSetName='def')]
[String]$Pos1,
[Parameter(ValueFromPipeline,Position=1,ParameterSetName='pip')]
[String]$InputObject,
[Parameter(Position=1,ParameterSetName='def')]
[Parameter(Position=0,ParameterSetName='pip')]
[String]$State
)
Process
{
Switch ($PScmdlet.ParameterSetName)
{
'def' {Write-Host "${State}: $Pos1"}
'pip' {Write-Host "${State}: $InputObject"}
}
}
}
PS C:\> 'this' | Test 'error'
test : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:10
+ 'test' | test 'error'
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (test:String) [Test], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Test
我可以通过以下示例获取函数的位置绑定管道调用:
Function Test
{
Param(
[Parameter(Position=1,ValueFromPipeline)]
[String]$Msg,
[Parameter(Position=0)]
[String]$State
)
Process
{
Write-Host "${State}: $Msg"
}
}
PS C:\> 'this' | Test 'error'
error: this
所以我的问题是:我如何创建一个函数来在命令行 (Test 'message' 'status'
) 和管道 ('message' | Test 'status'
) 中获取位置绑定的参数,而无需显式调用参数名称 ('message' | Test -State 'status'
)?
让我们用后一个脚本中的以下代码片段替换 Process { Write-Host "${State}: $Msg" }
块,以生成更具指导意义的输出并从中获取信息:
Process
{
### Write-Host "${State}: $Msg"
Write-Host "State=$State`t Msg=$Msg" -NoNewline
Write-Host "`t`t`t`t$($MyInvocation.Line.trim())" -ForegroundColor Cyan
}
然后,检查 output 以获得(几乎)所有可能的参数组合:
PS D:\PShell>
'this' | Test -State 'error'
'this' | Test 'error'
Test -Msg 'this' -State 'error'
Test -Msg 'this' 'error'
Test 'this' -State 'error'
Test 'this' 'error'
State=error Msg=this 'this' | Test -State 'error'
State=error Msg=this 'this' | Test 'error'
State=error Msg=this Test -Msg 'this' -State 'error'
State=error Msg=this Test -Msg 'this' 'error'
State=error Msg=this Test 'this' -State 'error'
State=this Msg=error Test 'this' 'error'
PS D:\PShell>
我们可以看到 Test 'this' 'error'
的不同输出(没有管道 和 行中没有明确命名的参数)。因此,Test 'error' 'this'
可以给出“正确的”结果。
另一种方法:让我们改变脚本输出如下:
Function Test
{
Param(
[Parameter(Position=1,ValueFromPipeline)]
[String]$Msg,
[Parameter(Position=0)]
[String]$State
)
Process
{
#Write-Host "${State}: $Msg"
$auxLine = $MyInvocation.Line.split( ' ',
[System.StringSplitOptions]::RemoveEmptyEntries)
if ( $auxLine[0] -eq $MyInvocation.InvocationName -and
'-Msg' -notin $auxLine -and
'-State' -notin $auxLine )
{
Write-Host "State=$Msg`t Msg=$State" -NoNewline
Write-Host "`tALTERED`t`t$($MyInvocation.Line.trim())" -ForegroundColor Yellow
} else {
Write-Host "State=$State`t Msg=$Msg" -NoNewline
Write-Host "`t`t`t`t$($MyInvocation.Line.trim())" -ForegroundColor Cyan
}
}
}
输出:
PS D:\PShell>
'this' | Test -State 'error'
'this' | Test 'error'
Test -Msg 'this' -State 'error'
Test -Msg 'this' 'error'
Test 'this' -State 'error'
Test 'this' 'error'
State=error Msg=this 'this' | Test -State 'error'
State=error Msg=this 'this' | Test 'error'
State=error Msg=this Test -Msg 'this' -State 'error'
State=error Msg=this Test -Msg 'this' 'error'
State=error Msg=this Test 'this' -State 'error'
State=error Msg=this ALTERED Test 'this' 'error'
PS D:\PShell>