Alan Renouf gave a vBrownBag presentation on Advanced PowerCLI 5.5R2 last night. During the show, he showed an interesting bit of code:
$output = "" | Select VmName, PgName $output.VmName = "value1" $output.PgName = "value2"
This was intriguing to me. The “proper” way to create an object with attributes is to use New-Object and pipeline it through some Add-Member commands.
$output = New-Object PSObject | Add-Member -PassThru NoteProperty VmName "value1" | Add-Member -PassThru NoteProperty PgName "value2"
That creates an excessive, and somewhat unreadable, pipeline for objects with a long list of members, especially if a member’s name is long. It’s a pretty neat trick to make your code look pretty neat.
In fact, I had just added a function with such a list to my powercli-modules repo and was aggravated that I couldn’t make it look any more elegant, so I converted it from the New-Object | Add-Member style to the $object = “” | Select Attribs style. Here’s the diff:
- New-Object PSObject | - Add-Member -PassThru NoteProperty "VMhost" $VMHost.Name | - Add-Member -PassThru NoteProperty "Model" $VMHostModel | - Add-Member -PassThru NoteProperty "Sockets" $VMHostView.Hardware.cpuinfo.NumCPUPackages | - Add-Member -PassThru NoteProperty "Cores" $VMHostView.Hardware.cpuinfo.NumCPUCores | - Add-Member -PassThru NoteProperty "Threads" $VMHostView.Hardware.cpuinfo.NumCPUThreads | - Add-Member -PassThru NoteProperty "VMs" $VMCount | - Add-Member -PassThru NoteProperty "vCPU" $CPUCount | - Add-Member -PassThru NoteProperty "vCPU/Core" $vCPUPerCore | - Add-Member -PassThru NoteProperty "RAM (GB)" $RAMGB | - Add-Member -PassThru NoteProperty "RAM Usage (GB)" $RAMUsageGB | - Add-Member -PassThru NoteProperty "RAM Free (GB)" $RAMFreeGB | - Add-Member -PassThru NoteProperty "RAM Usage (%)" $PercentRAMused | - Add-Member -PassThru NoteProperty "15% RAM Reservation (GB)" $RAMreservedFree | - Add-Member -PassThru NoteProperty "Available RAM (GB)" $RAMavailable + $VMHostInfo = "" | Select VMhost, Model, Sockets, Cores, Threads, VMs, vCPU, vCPU/Code, "RAM (GB)", "RAM Usage (GB)", + "RAM Free (GB)", "RAM Usage (%)", "15% RAM Reservation (GB)", "Available RAM (GB)" + $VMHostInfo.VMhost = $VMHost.Name + $VMHostInfo.Model = $VMhostModel + $VMHostInfo.Sockets = $VMHostView.Hardware.cpuinfo.NumCPUPackages + $VMHostInfo.Cores = $VMHostView.Hardware.cpuinfo.NumCPUCores + $VMHostInfo.Threads = $VMHostView.Hardware.cpuinfo.NumCPUThreads + $VMHostInfo.VMs = $VMCount + $VMHostInfo.vCPU = $CPUCount + $VMHostInfo.'vCPU/Code' = $vCPUPerCore + $VMHostInfo.'RAM (GB)' = $RAMGB + $VMHostInfo.'RAM Usage (GB)' = $RAMUsageGB + $VMHostInfo.'RAM Free (GB)' = $RAMFreeGB + $VMHostInfo.'Ram Usage (%)' = $PercentRAMused + $VMHostInfo.'15% RAM Reservation (GB)' = $RAMreservedFree + $VMHostInfo.'Available RAM (GB)' = $RAMavailable + $VMHostInfo
Note that when not assigning New-Object and the pipeline to a variable, as above, the new object is then displayed to the screen (or pushed into the pipeline, etc.). Our little trick doesn’t ever do this because we are assigning to a variable, so we throw out the variable by itself on a line to display the object for equivalent effect. Obviously, you may not need that in every situation, so pay attention to what you’re doing.