我正在尝试创建一个日志记录函数,它接受管道位置绑定(bind)参数和位置绑定(bind)参数。但是,我不断收到以下代码的错误:
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
我可以获得函数的位置绑定(bind)管道调用以使用以下示例:
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' | 测试 'status'
) 而无需显式调用参数名称 ('message' | Test -State 'status'
)?
最佳答案
让我们用后一个脚本中的以下代码片段替换 Process { Write-Host "${State}: $Msg"}
block ,以生成更具指导性的输出并从中获取信息:
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>
关于powershell - 接受位置绑定(bind)参数作为参数的函数,但也来自管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46409681/