PowerShell Objects Part 2: Do It Yourself

In part one of our discussion concerning PowerShell objects we discussed the integration of .NET into PowerShell, how this has brought us to the object-oriented paradigm that it utilizes and how to work with these objects. Now, as an extension of that, we will be using objects ourselves when we are scripting. This is when it gets fun.

Let’s suppose I have an XML file that contains weightlifting data on a number of collegiate athletes. As a simple example we’ll use the following format (There may be any number of <Athlete>s):

    <Athlete LastName ="">
    <Athlete LastName ="">

The first thing to be aware of is that PowerShell is perfectly capable of importing this XML file and will parse it into an object for you to manipulate. This can also be done with CSV files.

$AthleteData = [[xml]](Get-Content C:\Path\to\XML\file.xml)

$AthleteData is now a .Net object (System.Xml.XmlNode) with properties and sub-properties. For example, I can return the 1-Rep Max values for Bench Press for all athletes by:


Having all of this data in a single object isn’t very convenient for future processing, so let’s create some objects that will be easier to work with. I will create an arraylist of athletes, each of which will have a last name and all three 1RM stats associated with him. We do this by creating an arraylist object, iterating through the XML object, and creating objects for individual athletes. Then we add attributes:

$Roster = New-Object System.Collections.Arraylist
foreach ($Athlete in $AthleteData.Athlete1RMData.Athlete)
  #Creates a new object that represents an athlete
  $AthObject = New-Object System.Object    

  #Adds properties to the object
  $AthObject | Add-Member -type NoteProperty -name LastName -value $Athlete.LastName
  $AthObject | Add-Member -type NoteProperty -name 1RMBench -value $Athlete.BenchPress
  $AthObject | Add-Member -type NoteProperty -name 1RMMilitary -value $Athlete.MilitaryPress
  $AthObject | Add-Member -type NoteProperty -name 1RMSquat -value $Athlete.Squat

  #Adds the object to our list

Look at what we’ve done. Once we create a list, we iterate through all of the athletes represented in the XML file using a foreach loop. Then, for each athlete we create an object representing an individual. Finally we begin adding values that we extract from the XML as properties into our new athlete object. Each of these properties has a name associated with it which we can use to make reference to its corresponding value later on. Visually this is what we’ve created:
Now that we have our athletes in the form of .Net objects we can more easily do work with them. We can add additional athlete information, make comparisons, find averages, format/export data and a whole host of useful operations.

PowerShell Objects Part 1: No More Parsing!

One of the first things to know about PowerShell in order to wield it effectively is its object-based paradigm. If you are trying to parse strings in PowerShell scripts, it’s likely that there is a better way. (Disclaimer: There are indeed some scenarios where string parsing is necessary, but PowerShell has the muscle to handle that too.)

You see, PowerShell wants you to build, destroy, display, manipulate and break-down objects, and it will do everything in its power to help you get your work done if you comply. If, however, you insist on consistently utilizing the parsing techniques often applied in Unix environments, you will become very frustrated very quickly. Let’s look at a simple example:

Windows Management Instrumentation (WMI) objects are full of valuable system information that is easily accessible using PowerShell. Let’s say I want to display processor information. I can use:

Get-WmiObject Win32_Processor

I get the following output:

Caption           : Intel64 Family 6 Model 69 Stepping 1
DeviceID          : CPU0
Manufacturer      : GenuineIntel
MaxClockSpeed     : 2401
Name              : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
SocketDesignation : SOCKET 0

This is not a string, a table or an array. The output presented here is properties of the Win32_Processor WMI object. Since PowerShell is a .NET technology, the scripting language utilizes the availability of .NET framework classes in its operations. This integration is part of what makes PowerShell such a powerful tool. Since there already exists a wide array of methods and procedures in .NET that are specific to various object types, it is to the engineers advantage to utilize this functionality in scripting. That said, be familiar with and understand the capabilities of these objects, it’s a great step toward mastering Windows management. Now, off my soap box…

What we are looking at in the example above is a .NET object with various members. This is not all of the information contained in the Win32_Processor WMI object either. It’s only a subset that PowerShell thinks you may find useful. If you want a list of all the members that belong to this particular object we need to pipe the output of our last command into the Get-Member Cmdlet:

Get-WmiObject win32_processor | Get-Member

As a result we get a long list of members that belong to the Win32_Processor object. Here is a small sample from my machine:


We see that each member has a Name, MemberType and Definition. Most of the members in this object are of the “Property” type. These properties contain data about the object that we can access. We can also get a glimpse of the methods (specific to that object type) that are available for use on the object.

There are also other “MemberTypes” that we won’t discuss. We also won’t worry about the “Definitions” as they are mostly useful in lower-level .Net programming contexts.

In some cases it may be important understand what kind of .NET object were working with. Fortunately there is a method inherited from .Net’s System.Object class that applies to all objects called GetType(). We can call GetType() on an object to view the class it is derived from.

$CPUInfo = Get-WmiObject Win32_Processor

Notice that we get an object back!

IsPublic IsSerial Name               BaseType
-------- -------- ----               --------
True     True     ManagementObject   System.Management.ManagementBaseObject

Now that we know how to figure out the object type we are working with and the properties and methods associated with it, Let’s build a custom object using Win32_Processor that only contains the data that I need. To do this I pipe the object into “Select”:

Get-WmiObject win32_processor | Select Name, Manufacturer

Which will return only information about the Name and Manufacturer of my CPU:

Name                                              Manufacturer
----                                              ------------
Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz          GenuineIntel

This is still an object but with only two members in it. Now suppose I want nothing more than the name of the processor which I can use as a string. I would then use the -ExpandProperty switch to isolate the property’s value:

Get-WmiObject win32_processor | Select -ExpandProperty Name

Which returns the string:

Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz

Finally, I can save an object to a variable that I can reference to obtain its properties at a later time using <object>.<member> notation. For example:

$CPUInfo = GetWmiObject Win32_processor | Select Name, Manufacturer

Then, if I only want to get the value of a particular property I can do so by:


Which of course returns, as a string:

Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz

Now you understand the basics of the PowerShell object paradigm. Check out Part 2: Do it Yourself.