使用PowerShell的Add-Member会导致错误

时间:2012-01-25 13:03:16

标签: object powershell wmi pipeline

为什么下面的脚本会出现以下错误?

  

“Add-Member:由于一个或多个丢失,无法处理命令   必需参数:InputObject。
  + $ obj = Add-Member<<<< -MemberType NoteProperty -Name ComputerName -Value $ ComputerName
      + CategoryInfo:InvalidArgument:(:) [Add-Member],ParameterBindingException
      + FullyQualifiedErrorId:MissingMandatoryParameter,Microsoft.PowerShell.Commands.AddMemberCommand“

脚本

# Receives the computer name and stores the required results in $obj.
Function WorkerNetworkAdaptMacAddress {
    Param($ComputerName)

    $colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $ComputerName -filter "IpEnabled = TRUE"
    $obj = New-Object -TypeName PSobject
    ForEach ($objItem in $colItems)
    {
        $obj = Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
        $obj = Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
        $obj = Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress
    }
    Write-Output $obj
}

# Receives the computer name and passes it to WorkerNetworkAdaptMacAddress.

Function Get-NetworkAdaptMacAddress {
    begin {}
    process{
        WorkerNetworkAdaptMacAddress -computername $_
    }
    end {}
}

# Passes a computer name to get-networkAdaptMacAddress
'tbh00363' | Get-NetworkAdaptMacAddress

5 个答案:

答案 0 :(得分:7)

您需要将PSObject创建移动到循环中。否则,您将收到对象上已存在属性的错误。

其次,您需要告诉Add-Member哪个对象可以运行。您可以通过将对象传递给cmdlet或在InputObject参数上指定它来执行此操作。最后,通过在上一次PassThru调用中指定Add-Member开关,将对象返回管道:

ForEach ($objItem in $colItems)
{
    $obj = New-Object -TypeName PSobject
    Add-Member -InputObject $obj -MemberType NoteProperty -Name ComputerName -Value $ComputerName
    Add-Member -InputObject $obj -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
    Add-Member -InputObject $obj -MemberType NoteProperty -Name IPAddress -Value $objitem.IpAddress -PassThru
}

或者,您可以使用New-Object's -Property参数简化流程:

Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IpEnabled=TRUE" | Foreach-Object {
    New-Object -TypeName PSobject -Property @{
        ComputerName=$ComputerName
        MacAddress=$_.MacAddress
        IPAddress=$_.IpAddress
    }
}

或者使用Select-Object

Get-WmiObject ... | Select-Object @{n='ComputerName';e={$_.__SERVER}},MacAddress,IpAddress

答案 1 :(得分:4)

首先,您需要指定要通过管道将属性添加到Add-Member cmdlet的输入对象。
然后,如果您希望cmdlet返回修改后的对象,则应使用-PassThru参数调用它:

  

使用PassThru参数时,Add-Member返回   新扩展的对象。否则,此cmdlet不会生成任何内容   输出

以下是您的脚本的略微修改版本:

$obj = $objItem | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -PassThru

但是,因为在你的情况下,你真的不需要将输出对象保存在一个新变量中,你也可以简单地说:

$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName

答案 2 :(得分:3)

试试这样:

$objcol = @()
ForEach ($objItem in $colItems)
{
    $obj = New-Object System.Object
    $obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
    $obj | Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
    $obj | Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress
    $objcol += $obj
}
Write-Output $objcol

答案 3 :(得分:1)

如Enrico,Shay和Christian所示,您应指定Add-Member操作的对象,方法是将对象传递给Add-Member或通过在InputObject上明确指定对象参数。使用Add-Member添加多个成员时,我通常会添加PassThru开关,以避免重复InputObject并提供可视提示。

ForEach ($objItem in $colItems) {
  $obj = New-Object PSobject
  $obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -PassThru ` 
       | Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress -PassThru `
       | Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress -PassThru
}

答案 4 :(得分:0)

您将Add-Member的结果分配给变量,而不是将其添加到$obj中的属性集合中。

而不是

$obj = Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName

试试这个:

Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -inputObject $obj