Chapter 3. Objects and PowerShell
In this chapter, we will learn about objects and how they relate to the PowerShell output. The specific topics in this chapter include the following:
- What are objects?
- Comparing DOS and PowerShell output
- The
Get-Member
cmdlet
Objects all the way down
One major difference between PowerShell and other command environments is that, in PowerShell, everything is an object. One result of this is that the output from the PowerShell cmdlets is always in the form of objects. Before we look at how this affects PowerShell, let's take some time to understand what we mean when we talk about objects.
Digging into objects
If everything is an object, it's probably worth taking a few minutes to talk about what this means. We don't have to be experts in object-oriented programming to work in PowerShell, but a knowledge of a few things is necessary.
In a nutshell, object-oriented programming involves encapsulating the related values and functionality in objects. For instance, instead of having variables for speed, height, and direction and a function called PLOTPROJECTILE
, in object-oriented programming you might have a Projectile object that has the properties called Speed
, Height
, and Direction
as well as a method called Plot
. This Projectile object could be treated as a single unit and passed as a parameter to other functions. Keeping the values and the related code together has a certain sense to it, and there are many other benefits to object-oriented programming.
Types, classes, and objects
The main concepts in object-oriented programming are types, classes, and objects. These concepts are all related and often confusing, but not difficult once you have them straight:
- A type is an abstract representation of structured data combining values (called properties), code (called methods), and behavior (called events). These attributes are collectively known as members.
- A class is a specific implementation of one or more types. As such, it will contain all the members that are specified in each of these types and possibly other members as well. In some languages, a class is also considered a type. This is the case in C#.
- An object is a specific instance of a class. Most of the time in PowerShell, we will be working with objects. As mentioned earlier, all output in PowerShell is in the form of objects.
PowerShell is build upon the .NET framework, so we will be referring to the .NET framework throughout Module 1. In the .NET framework, there is a type called System.IO.FileSystemInfo
, which describes the items located in a filesystem (of course). Two classes that implement this type are System.IO.FileInfo
and System.IO.DirectoryInfo
. A reference to a specific file would be an object that was an instance of the System.IO.FileInfo
class. The object would also be considered to be of the System.IO.FileSystemInfo
and System.IO.FileInfo
types.
Here are some other examples that should help make things clear:
- All the objects in the .NET ecosystem are of the
System.Object
type - Many collections in .NET are of the
IEnumerable
type - The ArrayList is of the
IList
andICollection
types among others
What are members?
Members are the attributes of types that are implemented in classes and instantiated in objects. Members come in many forms in the .NET framework, including properties, methods, and events.
Properties represent the data contained in an object. For instance, in a FileInfo
object (System.IO.FileInfo
), there would be properties referring to the filename, file extension, length, and various DateTime
values associated with the file. An object referring to a service (of the System.ServiceProcess.ServiceController
type) would have properties for the display name of the service and the state (running or not).
Methods refer to the operations that the objects (or sometimes classes) can perform. A service object, for instance, can Start and Stop. A database command object can Execute. A file object can Delete or Encrypt itself. Most objects have some methods (for example, ToString
and Equals
) because they are of the System.Object
type.
Events are a way for an object to notify that something has happened or that a condition has been met. Button objects, for instance, have an OnClick
event that is triggered when they are clicked.
Now that we have an idea about objects, let's look back at a couple of familiar DOS commands and see how they deal with the output.
The DOS DIR command
The output that we see in the preceding screenshot includes several details about a single file. Note that there is a lot of formatting included with the static text (for example, Volume in drive
) and some tabular information, but the only way to get to these details is to understand exactly how the output is formatted and parse the output string accordingly. Think about how the output would change, if there were more than one file listed. If we included the /S
switch, the output would have spanned over multiple directories, and would have been broken into sections accordingly. Finding a specific piece of information from this is not a trivial operation, and the process of retrieving the file length, for example, would be different from how you would go about retrieving the file extension.
The IPCONFIG command
Another command that we are all familiar with is the IPConfig.exe
tool, which shows network adapter information. Here is the beginning of the output in my laptop:
Here, again, the output is very mixed. There is a lot of static text and a list of properties and values. The property names are very readable, which is nice for humans, but not so nice for computers trying to parse things out. The dot-leaders are again something that help to guide the eyes towards the property values, but will get in the way when we try to parse out the values that we are looking for. Since some of the values (such as IP addresses and subnet masks) already include dots, I imagine it will cause some confusion.
PowerShell for comparison
Let's look at some PowerShell commands and compare how easy it is to get what we need out of the output:
We can see that the output of the dir
command looks similar to the output we saw in DOS, but we can follow this with Select-Object
to pull out a specific property. This is possible because PowerShell commands always output objects. In this case, the object in question has a property called
Extension
, which we can inspect. We will talk about the select-object
cmdlet in detail in the next chapter, but for now it is enough to know that it can be used to limit the output to a specific set of properties from the original objects.
The DOS DIR command
The output that we see in the preceding screenshot includes several details about a single file. Note that there is a lot of formatting included with the static text (for example, Volume in drive
) and some tabular information, but the only way to get to these details is to understand exactly how the output is formatted and parse the output string accordingly. Think about how the output would change, if there were more than one file listed. If we included the /S
switch, the output would have spanned over multiple directories, and would have been broken into sections accordingly. Finding a specific piece of information from this is not a trivial operation, and the process of retrieving the file length, for example, would be different from how you would go about retrieving the file extension.
The IPCONFIG command
Another command that we are all familiar with is the IPConfig.exe
tool, which shows network adapter information. Here is the beginning of the output in my laptop:
Here, again, the output is very mixed. There is a lot of static text and a list of properties and values. The property names are very readable, which is nice for humans, but not so nice for computers trying to parse things out. The dot-leaders are again something that help to guide the eyes towards the property values, but will get in the way when we try to parse out the values that we are looking for. Since some of the values (such as IP addresses and subnet masks) already include dots, I imagine it will cause some confusion.
PowerShell for comparison
Let's look at some PowerShell commands and compare how easy it is to get what we need out of the output:
We can see that the output of the dir
command looks similar to the output we saw in DOS, but we can follow this with Select-Object
to pull out a specific property. This is possible because PowerShell commands always output objects. In this case, the object in question has a property called
Extension
, which we can inspect. We will talk about the select-object
cmdlet in detail in the next chapter, but for now it is enough to know that it can be used to limit the output to a specific set of properties from the original objects.
The IPCONFIG command
Another command that we are all familiar with is the IPConfig.exe
tool, which shows network adapter information. Here is the beginning of the output in my laptop:
Here, again, the output is very mixed. There is a lot of static text and a list of properties and values. The property names are very readable, which is nice for humans, but not so nice for computers trying to parse things out. The dot-leaders are again something that help to guide the eyes towards the property values, but will get in the way when we try to parse out the values that we are looking for. Since some of the values (such as IP addresses and subnet masks) already include dots, I imagine it will cause some confusion.
PowerShell for comparison
Let's look at some PowerShell commands and compare how easy it is to get what we need out of the output:
We can see that the output of the dir
command looks similar to the output we saw in DOS, but we can follow this with Select-Object
to pull out a specific property. This is possible because PowerShell commands always output objects. In this case, the object in question has a property called
Extension
, which we can inspect. We will talk about the select-object
cmdlet in detail in the next chapter, but for now it is enough to know that it can be used to limit the output to a specific set of properties from the original objects.
PowerShell for comparison
Let's look at some PowerShell commands and compare how easy it is to get what we need out of the output:
We can see that the output of the dir
command looks similar to the output we saw in DOS, but we can follow this with Select-Object
to pull out a specific property. This is possible because PowerShell commands always output objects. In this case, the object in question has a property called
Extension
, which we can inspect. We will talk about the select-object
cmdlet in detail in the next chapter, but for now it is enough to know that it can be used to limit the output to a specific set of properties from the original objects.
The Get-Member cmdlet
One way to find the members of a class is to look up this class online in the
MicroSoft Developers Network (MSDN). For instance, the FileInfo
class is found at https://msdn.microsoft.com/en-us/library/system.io.fileinfo.
Although this is a good reference, it's not very handy to switch back and forth between PowerShell and a browser to look at the classes all the time. Fortunately, PowerShell has a very handy way to give this information, the Get-Member
cmdlet. This is the third of the "big 3" cmdlets, following Get-Command
and Get-Help
.
The most common way to use the Get-Member
cmdlet is to pipe data into it. Piping is a way to pass data from one cmdlet to another, and is covered in depth in the next chapter. Using a pipe with Get-Member
looks like this:
The Get-Member
cmdlet looks at all the objects in its input, and provides output for each distinct class. In this output, we can see that Get-Service
only outputs a single type, System.ServiceProcess.ServiceController
. The name of the class is followed by the list of members, type of each member as well as definition for the member. The member definition shows the type of properties, signature for events, and methods, which includes the return type as well as the types of parameters.
Tip
Your turn!
Use Get-Member
to see the classes output by the Dir
(or Get-ChildItem
) cmdlet. Note that there are two different classes listed.
One thing that can be confusing is that get-member
usually shows more properties than those shown in the output. For instance, the Get-Member
output for the previous Get-Service
cmdlet shows 13 properties but the output of Get-Service
displays only three.
The reason for this is that PowerShell has a powerful formatting system that is configured with some default formats for familiar objects. Rest assured that all the properties are there. A couple of quick ways to see all the properties are to use the Select-Object
cmdlet we saw earlier in this chapter or to use the Format-List
cmdlet and force all the properties to be shown. Here, we use Select-Object
and a wildcard to specify all the properties:
The Format-List
cmdlet with a wildcard for properties gives output that looks the same . We will discuss how the output of these two cmdlets actually differs, as well as elaborate on PowerShell's formatting system in Chapter 5, Formatting Output.
Where did these all come from?
If you look closely at the ServiceController
members listed in the previous figure, you will notice a few members that aren't strictly properties, methods, or events. PowerShell has a mechanism called the Extended Type System that allows PowerShell to add members to classes or to individual objects. In the case of the SystemController
objects, PowerShell adds a Name
alias for the ServiceName
property and a RequiredServices
alias for the built-in ServicesDependedOn
property.
Tip
Your turn!
Use Get-Member
with Dir
and Get-Process
and see what members PowerShell has added. Look these classes up on MSDN and verify that those properties aren't delivered as part of the .NET framework.
Summary
In this chapter, we discussed the importance of objects as output from the PowerShell cmdlets. After a brief primer on types, classes, and objects, we spent some time getting used to the Get-Member
cmdlet. In the next chapter, we will cover the PowerShell pipeline and common pipeline cmdlets.
For further reading
Get-Help about_objects
Get-Help about_properties
Get-Help about_methods
Get-Help about_events
Get-Help Get-Member