我正在尝试创建一个日志函数,它接受管道位置绑定参数和位置绑定参数。但是,我使用以下代码继续收到此错误:
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'
)?
答案 0 :(得分:2)
让我们用后一个脚本中的以下代码片段替换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
}
然后,检查输出(几乎)所有可能的参数组合:
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>