powershell - -PipelineVariable 不适用于 Get-NetIPAddress

标签 powershell

我显然无法理解 -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.

注意:


PowerShell(核心)7+中:

  • 错误已在 v7.2+ 中修复

    • 但是,存在一个相关错误,从 v7.3.8 开始仍然存在:如果您将 -PipelineVariable 与 CDXML cmdlet 一起使用,并且另一个 CDXML cmdlet 在同一管道中使用(没有 -PipelineVariable),后者意外地将管道变量重置为 $null - 请参阅 GitHub issue #20546

警告:我不清楚 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/

相关文章:

PowerShell 和磁盘部分

sql-server - 如何通过powershell关闭数据库加密

sql-server - 如何使用 SSIS 将 Powershell 输出加载到 SQL 表中?

windows - 在 3 个不同的子目录中创建 2 个子目录

Powershell:两个 System.Object 变量具有相同值的相等条件为 false

powershell - 通过引用访问列表的问题

powershell - WMI中的多个通配符查询Powershell?

PowerShell 中的日期时间解析

powershell - 如何从 Powershell 4 指向 Powershell 版本 3?

powershell - 函数内点源 a "script"