Felix Umansky
Felix Umansky

Reputation: 3

powershell outputs argument with (@{Name=name}:String)

I'm trying to run the command Get-VMNetworkAdapter on a list of VMs

I'm getting the list with the command:

Get-VM –ComputerName (Get-ClusterNode –Cluster clustername)|select name

and it looks fine, when I'm using

$vmm=Get-VM –ComputerName (Get-ClusterNode –Cluster clustername)|select name 
foreach ($item in $vmm)
{Get-VMNetworkAdapter -VMName $item}

it gives me the exception

nvalidArgument: (@{Name=vmname}:String)

like it adds all those symbols.. What is the proper way to lose them?

Upvotes: 0

Views: 356

Answers (1)

Bacon Bits
Bacon Bits

Reputation: 32210

You need to expand the property. Select doesn't remove the object otherwise:

$vmm = Get-VM –ComputerName (Get-ClusterNode –Cluster clustername) `
| Select-Object -ExpandProperty name

To explain what -ExpandProperty does:

First of all, the drawback of -ExpandProperty is that you can only do it to one property at a time.

Select-Object normally wraps the results in another object so that properties remain properties. If you say $x = Get-ChildItem C:\Windows | Select-Object Name, then you get an object array with one property: Name.

PS C:\> $x = Get-ChildItem C:\Windows | Select-Object Name
PS C:\> $x

Name
----
45235788142C44BE8A4DDDE9A84492E5.TMP
8A809006C25A4A3A9DAB94659BCDB107.TMP
.
.
.
PS C:\> $x[0].Name
45235788142C44BE8A4DDDE9A84492E5.TMP
PS C:\> $x[0].GetType().FullName
System.Management.Automation.PSCustomObject

Notice the header? Name is a property of the object.

Also, the base object with it's type is still kind of there:

PS C:\> $x | Get-Member


       TypeName: Selected.System.IO.DirectoryInfo

    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    Name        NoteProperty string Name=45235788142C44BE8A4DDDE9A84492E5.TMP


       TypeName: Selected.System.IO.FileInfo

    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    Name        NoteProperty string Name=bfsvc.exe

Normally, that's all great. Especially because we normally want multiple properties of the object.

Sometimes, however, not what we want. Sometimes, we want an array that's the same type as the property we selected. When we use it later we want just that property and nothing else and we want it to be the exact same type as the property and nothing else.

PS C:\> $y = Get-ChildItem C:\Windows | Select-Object -ExpandProperty Name
PS C:\> $y
45235788142C44BE8A4DDDE9A84492E5.TMP
8A809006C25A4A3A9DAB94659BCDB107.TMP
.
.
.
PS C:\> $y[0].Name
PS C:\> $y[0]
45235788142C44BE8A4DDDE9A84492E5.TMP
PS C:\> $y.GetType().FullName
System.Object[]
PS C:\> $y[0].GetType().FullName
System.String

Notice there's no header, and any calls to a Name property fail; there is no Name property anymore.

And, there's nothing left over from the original object:

PS C:\> $y | Get-Member


   TypeName: System.String

Name             MemberType            Definition
----             ----------            ----------
Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()
.
.
.
.

Basically, here it's the equivalent of doing this:

$z = Get-ChildItem C:\Windows | ForEach-Object { $_.Name }

Which I think is how you had to do it in PowerShell v1.0 or v2.0... it's been too many years since I've used that to remember right.

Upvotes: 1

Related Questions