Powershell 函数,该函数接受位置绑定参数作为参数,但也接受来自管道的参数

Powershell 函数,该函数接受位置绑定参数作为参数,但也接受来自管道的参数,powershell,pipeline,powershell-5.0,Powershell,Pipeline,Powershell 5.0,我试图创建一个日志函数,该函数接受管道位置绑定参数和位置绑定参数。但是,我通过以下代码不断收到此错误: Function Test { [CmdletBinding(SupportsShouldProcess,DefaultParameterSetName='def')] Param( [Parameter(Position=0,ParameterSetName='def')] [String]$Pos1, [Parameter(ValueFromPipeline,Position=

我试图创建一个日志函数,该函数接受管道位置绑定参数和位置绑定参数。但是,我通过以下代码不断收到此错误:

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

因此,我的问题是:如何创建一个函数,该函数将在命令行(
测试“消息”状态“
)和管道(
'message'|测试“状态”
)上接受位置绑定参数,而无需显式调用参数名(
'message'|测试-状态“
)?

让我们用后一个脚本中的以下代码片段替换
进程{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'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> 

从管道中删除ParameterSetName,删除ParameterSetName='pip'@ArcSet这样做会导致position 0参数绑定两次,绑定到
$InputObject
$State
,但它确实停止向我抛出错误。为了理解这一点,您基本上是在检查非管道输入的隐式,定位传递的参数并基于此翻转输出?
$MyInvocation
的使用很好。比我希望的要复杂一点(参数集留下了更多需要改进的地方),但它确实有效。谢谢