我显然无法理解 -PipelineVariable
的细微差别
如果我将 Get-NetIPAddress
传递到 Get-NetAdapter
中,它会显示关联的适配器。
Get-NetIPAddress | Get-NetAdapter -ErrorAction SilentlyContinue
现在,如果我还想收集 IP,我决定将其附加上
Get-NetIPAddress -PipelineVariable ip | Get-NetAdapter -ErrorAction SilentlyContinue | Select-Object *,@{n='IP';e={$ip.IPAddress}}
但是我看到了错误
Get-NetIPAddress : Cannot retrieve the dynamic parameters for the cmdlet. Object reference not set to an instance of an object.
At line:1 char:5
+ Get-NetIPAddress -PipelineVariable ip
即使只是简单地运行也会出现相同的错误
Get-NetIPAddress -PipelineVariable ip | Get-NetAdapter -ErrorAction SilentlyContinue
这也会返回相同的错误。
Get-NetIPAddress -PipelineVariable ip | Get-NetAdapter -ErrorAction SilentlyContinue | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
IfDesc = $_.Interfacedescription
IfIndex = $_.ifindex
MAC = $_.macaddress
LinkSpeed = $_.linkspeed
IP = $ip.IPAddress
}
}
这不是它本来的用途吗?最初我使用Where-Object 来过滤IPv4 地址族,但在本示例中省略了它。
像这样解决这个问题似乎是错误的。
foreach($ip in Get-NetIPAddress){
$ip | Get-NetAdapter -ErrorAction SilentlyContinue | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
IfDesc = $_.Interfacedescription
IfIndex = $_.ifindex
MAC = $_.macaddress
LinkSpeed = $_.linkspeed
IP = $ip.IPAddress
}
}
}
最佳答案
您似乎发现Windows PowerShell中存在一个错误,该错误影响所有所谓的 CDXML cmdlet,其中 Get-NetIPAddress
是一个实例。
- CDXML cmdlet 通过定义“PowerShell cmdlet 与 CIM 类操作或方法之间的映射”的
*.cdxml
XML 文档以声明方式实现。
看起来,在 Windows PowerShell 中,CDXML cmdlet 不支持 common -PipelineVariable
parameter 并报告您看到的无法检索 cmdlet 的动态参数
错误:
# !! Fails in Windows PowerShell.
# OK in PowerShell (Core) v7.2+
PS> Get-NetIPAddress -PipelineVariable var |
Select IPAddress, @{ Name='IPAddressViaPipelineVar'; Expression = { $var.IPAddress } }
Get-NetIPAddress : Cannot retrieve the dynamic parameters for the cmdlet. Object reference not set to an instance of an object.
注意:
- 自 Windows PowerShell 版本 v5.1.19041.1151 起存在该错误。
- Windows PowerShell 的最新且最终版本为 v5.1,不再积极开发,并且 will see high-priority bug fixes only 。
- 因此,这个错误不太可能被修复,但报告它 via the Feedback Hub application 也没什么坏处。
在PowerShell(核心)7+中:
错误已在 v7.2+ 中修复。
- 但是,存在一个相关错误,从 v7.3.8 开始仍然存在:如果您将
-PipelineVariable
与 CDXML cmdlet 一起使用,并且另一个 CDXML cmdlet 在同一管道中使用(没有-PipelineVariable
),后者意外地将管道变量重置为$null
- 请参阅 GitHub issue #20546 。
- 但是,存在一个相关错误,从 v7.3.8 开始仍然存在:如果您将
警告:我不清楚 CDXML cmdlet 的官方维护状态:
链接的 CDXML 文档被标记为不再更新。
在仍在维护的文档中,CDXML cmdlet 仅在概念性 about_CimSession 帮助主题中顺便提及。
PowerShell(核心)使用与 Windows PowerShell 完全相同的 CDXML 模块:它们随 Windows PowerShell 一起提供(位于
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules 的子文件夹中
)。但是,涉及一个特定于版本的动态转换步骤,即将*.cdxml
XML 文件转换为 PowerShell 函数,然后使用特定于版本的类型,例如[Microsoft.管理.基础设施.CimInstance]
.
以下命令列出包含 CDXML cmdlet 的所有本地可用模块:
注意:这需要相当长的时间,并且显式将所有本地可用的内容导入当前 session ,以便可以检查所有函数体。
在 PowerShell (Core) 7+ 中 - 但不在 Windows PowerShell 中 - 会出现以下问题:
- 报告错误(
Add-Type:具有相同名称的程序集已加载。
,此平台不支持操作 (0x80131539)
),用-ErrorAction Ignore
抑制。 - 可能通过 Windows PowerShell Compatibility feature 创建隐式远程处理模块。
- 大多数模块不报告导出函数集,并显示版本号
0.0
。
- 报告错误(
Get-Command -Type Function |
% { if (-not $_.Module) { return } Import-Module -WarningAction Ignore -EA Ignore $_.Module; if ((Get-Content -EA Ignore "function:$($_.Name)") -match 'cdxml') { $_.Module } } |
Sort-Object Name, @{ Expression={ $_.Version }; Descending=$true } -Unique
关于powershell - -PipelineVariable 不适用于 Get-NetIPAddress,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69005954/