- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个高级函数来从 VMware ESXi 上运行的虚拟机获取 MAC 地址。
function Get-MacFromVm {
[CmdletBinding(SupportsShouldProcess=$true)]
Param(
# The name of the VM of which we want to obtain the mac address.
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]
$Name
)
Begin {}
Process {
foreach ($item in $Name) {
if ($PSCmdlet.ShouldProcess($item, "Getting the mac address")) {
Get-VM $item -PipelineVariable vm |
Get-NetworkAdapter |
Select-Object @{n="Name"; e={$vm.Name}},
@{n="ClientId"; e={$_.MacAddress -replace ":","-"}}
}
}
}
End {}
}
到目前为止,一切都很完美。我可以通过以下任何一种方式使用它并获取结果。
它通过命名参数或管道输入接受单个字符串或字符串数组。
Get-MacFromVm -Name "playground"
Get-MacFromVm -Name "playground", "DC01"
"playground", "DC01" | Get-MacFromVm
输出是一个 [PSCustomObject]
,具有 2 个属性:Name 和 ClientId。
现在,当我想使用 -PipelineVariable
参数将结果链接到多个其他 cmdlet 时,问题就出现了。
通常我应该能够像这样使用它:
Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv}
但它没有向我显示任何结果。如果我用 $_
替换 $pv
,它确实会显示正确的结果,但我无法在管道链中进一步使用该自动变量 2 或 3 个 cmdlet。
尽管我可以通过使用 -OutVariable
和/或将其拆分为多行来解决此问题。我想知道为什么这不起作用,我想知道我在这里缺少什么。
最佳答案
我没有 -PipelineVariable
的经验范围。于是,我以此为契机,了解了-PipelineVariable
参数:
因为我也不容易访问虚拟机,所以我模拟了如下功能:
Function Get-MacFromVm {
[CmdletBinding(SupportsShouldProcess=$true)]
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]
$Name
)
Function MacAddress {(1..4 | ForEach {'{0:x2}' -f (Get-Random -Min 0 -Max 255)}) -Join ":"}
Function Get-VM {[cmdletbinding()] Param ($Name) [pscustomobject]@{Name = $Name; MacAddress = (MacAddress)}}
ForEach ($Item in $Name) {
If ($PSCmdlet.ShouldProcess($Item, "Getting the mac address")) {
Get-VM $item -PipelineVariable vm |
Select-Object @{n="Name"; e={$vm.Name}}, @{n="ClientId"; e={$_.MacAddress -replace ":","-"}}
}
}
}
但我无法重现该问题:
PS C:\> Get-MacFromVm -Name "playground", "DC01" -PipelineVariable pv | % {$pv}
Name ClientId
---- --------
playground 3c-23-55-c4
DC01 4f-38-42-a7
所以我想知道这个模拟功能是否也适合你。
如果是的话,也许您可以找到与真实VM对象的差异。
了解PowerShell,我会质疑是否没有任何输出或没有任何显示。那么如果你只输出一个属性会发生什么:
Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv.Name}
或者:
Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv.GetType()}
这是否会返回“You cannot call a method on a null-valued expression.
”错误?
2019 年 10 月 30 日更新
根据mklement0评论:
您看不到 the bug 的原因这是你的功能,因为没有使用 begin
/process
/end
block ,隐式运行在 end
block ,并且任何这些脚本 block 的第一次调用都会在管道变量中捕获,但不会捕获后续脚本 block 调用的输出,这会发生在具有 process
的函数中。 block 。
这意味着正确的模拟应该是:
Function Get-MacFromVm {
[CmdletBinding(SupportsShouldProcess=$true)]
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]
$Name
)
Begin {
Function MacAddress {(1..4 | ForEach {'{0:x2}' -f (Get-Random -Min 0 -Max 255)}) -Join ":"}
Function Get-VM {[cmdletbinding()] Param ($Name) [pscustomobject]@{Name = $Name; MacAddress = (MacAddress)}}
}
Process {
ForEach ($Item in $Name) {
If ($PSCmdlet.ShouldProcess($Item, "Getting the mac address")) {
Get-VM $item -PipelineVariable vm |
Select-Object @{n="Name"; e={$vm.Name}}, @{n="ClientId"; e={$_.MacAddress -replace ":","-"}}
}
}
}
}
这确实没有给出 PipelineVariable
的任何结果:
PS C:\> Get-MacFromVm -Name "playground", "DC01" -PipelineVariable pv | % {$pv}
PS C:\>
当前项目 ( $_
) 会:
PS C:\> Get-MacFromVm -Name "playground", "DC01" -PipelineVariable pv | % {$_}
Name ClientId
---- --------
playground e7-b5-a0-31
DC01 0f-ed-94-cc
关于function - PowerShell高级功能输出PipelineVariable不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45782372/
我是一名优秀的程序员,十分优秀!