[英]PowerShell pipeline parameter binding order
我有一個高級函數,可以接受兩種管道數據:
這是我的功能:
function Test-PowerShell {
[CmdletBinding(DefaultParameterSetName = "ID")]
param (
[Parameter(
Mandatory = $true,
ParameterSetName = "InputObject",
ValueFromPipeline = $true
)]
[PSTypeName('MyType')]
$InputObject,
[Parameter(
Mandatory = $true,
ParameterSetName = 'ID',
ValueFromPipelineByPropertyName = $true
)]
[int]
$ID
)
process {
if ($InputObject) {
$objects = $InputObject
Write-Verbose 'InputObject binding'
}
else {
$objects = Get-MyType -ID $ID
Write-Verbose 'ID binding'
}
# Do something with $objects
}
}
我可以像這樣使用這個函數:
$obj = [PSCustomObject]@{
PSTypeName = 'MyType'
ID = 5
Name = 'Bob'
}
$obj | Test-PowerShell -Verbose
請注意,此對象滿足上述兩個條件:它是MyType,並且具有ID屬性。 在這種情況下,PowerShell始終綁定到ID屬性。 這在性能方面並不理想,因為管道對象被丟棄,我不得不使用ID重新查詢它。 我的問題是:
如果可能,如何強制PowerShell將管道綁定到$ InputObject?
如果我將默認參數設置更改為InputObject,PowerShell將綁定$ InputObject。 但是,我不希望這樣,因為在沒有參數的情況下運行時,我希望PowerShell提示輸入ID,而不是InputObject。
簡單的答案:刪除$InputObject
上的Parameter
屬性的Mandatory
參數以獲得所需的功能。 我沒有關於如何參數綁定作品解釋為什么這個作品足夠的知識。
function Test-PowerShell {
[CmdletBinding(DefaultParameterSetName = 'ID')]
param(
[Parameter(ParameterSetName = 'InputObject', ValueFromPipeline)]
[PSTypeName('MyType')]
$InputObject,
[Parameter(ParameterSetName = 'ID', Mandatory, ValueFromPipelineByPropertyName)]
[int]
$ID
)
process {
$PSBoundParameters
}
}
$o = [pscustomobject]@{
PSTypeName = 'MyType'
ID = 6
Name = 'Bob'
}
PS> $o | Test-PowerShell
Key Value
--- -----
InputObject MyType
PS> [pscustomobject]@{ID = 6} | Test-PowerShell
Key Value
--- -----
ID 6
這是解決您的問題的方法(定義您自己的類型):
Add-Type -TypeDefinition @'
public class MyType
{
public int ID { get; set; }
public string Name { get; set; }
}
'@
然后你將你的參數標記為 [MyType]
,創建像[pscustomobject]
那樣的對象:
[MyType]@{ ID = 6; Name = 'Bob' }
事后看來,這種方法不起作用。 您遇到的是DefaultParameterSet
的行為。 我建議你改變你的管道輸入。 是否存在將ID作為管道輸入而不是僅使用Test-PowerShell -ID 5
或Test-PowerShell
並被提示輸入ID的用戶的用例?
這是一個可能與我的測試有關的建議:
function Test-PowerShell {
[CmdletBinding(DefaultParameterSetName = 'ID')]
param(
[Parameter(ParameterSetName = 'InputObject', Mandatory = $true, ValueFromPipeline = $true)]
[PSTypeName('MyType')]
$InputObject,
[Parameter(ParameterSetName = 'ID', Mandatory = $true, ValueFromPipeline = $true)]
[int]
$ID
)
process {
$PSBoundParameters
}
}
要從現有的內置cmdlet中獲取示例,它們不會在對象上使用相同的名稱或屬性來表示多個參數。 在Get-ChildItem
, LiteralPath
和Path
接受管道輸入,但LiteralPath
只接受PropertyName LiteralPath
或PSPath
(別名)。 Path
是ByValue和PropertyName,但僅作為Path
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.