A PowerShell Object Lesson: Part One

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the importance of objects when working with Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. It is starting to get rather cold and rainy outside here in Charlotte, North Carolina in the United States. On a day like this, I like to have a cup of Lapsang Souchong tea. Lapsang Souchong tea is one of the teas that I routinely add milk to before drinking. The smoky flavor and smell remind me of standing in front of the fireplace when I was a kid to warm up after a day of playing in the snow. The nice hot tea allows me to relive that moment, and it warms me nicely. A hot cup of tea, and a cool laptop keyboard with a warm blue Windows PowerShell console is all I need to spend a productive day inside—away from the ravages of cold, pelting rain and bone-chilling wind.

Note  This is the first of a three-part series of posts that talk about Windows PowerShell objects.

A fundamental concept of Windows PowerShell

One of the most fundamental concepts of Windows PowerShell is the concept of objects. It is a truism that all good Windows PowerShell functions return objects. This is a design goal to which all good scripters should aspire. All Windows PowerShell cmdlets return objects. But what is an object? Why is an object desirable? Why should we care about objects?

The great thing about an object is that it makes it easy to do things, and it makes it easy to obtain information. With an object, doing things is called a method and obtaining information is called a property. If I do not have an object, it is much more difficult to do things or to obtain information.

One way information can be obtained without an object is to use command-line utilities. These are the same utilities that have been around for years—going back to the earliest days of DOS (and in some cases, before DOS). These old utilities all return text. They do not return rich objects. (To be fair, in Windows PowerShell, even text is an object. In fact, everything in Windows PowerShell is an object.)

When I use a utility that returns only text, I am pretty much stuck with the information that it returns. This means that if I do not like the output, well, that’s tough. An example of a utility that returns only text is the IPConfig command. The output comes back and fills the console with lots of text, but if I want to find only the IP address of the DNS server, I am stuck reading through lots of output as shown here:

Image of command output

When I finally find it, then what? I have a textual representation of the IP address of the DNS server. But what if I am troubleshooting my computer? If I want to ping that DNS server, how do I do it? I have to type a bunch of numbers and hope that I get it in the right order. What if I want to ping the IPv6 address? Dude, I am out of luck. Lots of typing. Hopefully I can cut and paste the address to another utility to do the ping.

So, what happens if I have an object that comes back with IP address types of information? Initially, it does not look like much difference. I type the command, and it returns output to the Windows PowerShell console, just like the IPConfig command. So what is the difference?

Well, the difference is under the covers. With an object, I can gain direct access to the property that contains the information. For example, if I want the IP address of the DNS server, I access the DNS server property from the object. This is easier that it sounds:


The output is shown here:

Image of command output

What is not an object

…well at least, not really an object.

When you use the Write-Host cmdlet, it displays output to the Windows PowerShell console (or even to the output pane of the Windows PowerShell ISE). Write-Host does not generate an object—it simply displays to the console, as shown in the following image:

Image of command output

If I have a script that uses a series of Write-Host cmdlets, that script is not returning any objects; and therefore, the script does not go anywhere else. It cannot feed the output to a text file or to another Windows PowerShell cmdlet. This is a common mistake that is made by beginning script writers. There is nothing wrong with using Write-Host to provide status notification the Windows PowerShell console when you are running a script. But Write-Host does not return any objects, and it should not be used for returning the data from your Windows PowerShell script or function because once you use Write-Host, you are done.

Note  One of the things I like to tell my classes is that Write-Host equals “write-forever.” The data has reached the end of the line, and it is forever trapped on the console. You cannot do anything else with it.

Join me tomorrow when I will talk about using the objects that Windows PowerShell generates.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (3)

  1. UserInterface says:

    What if I wanted to get only the IPv4 address and pipe it to ping?

  2. ed wilson says:

    @UserInterface, you can use the following code to ping each ipv4 address associated with the network adapter:

    (Get-NetIPConfiguration).ipv4address | foreach { ping $_.ipaddress}

  3. And how would one determine to use ...$_.ipaddress}? says:

    In your response to @UserInterface, how did you arrive at using $_.ipaddress as the particular property? Did that come from using two commands Get-NetIPConfiguration and (Get-NetIPConfiguration).ipv4address and observing the label of the data you wanted in the second output? (And why are parenthesis used in the 2nd one?)

    Does everything have to go through so many steps? It's like to get one piece of information you have to do 3 things (two to discover and one to implement). And it would be worse if the results you wanted were "deeper".

    Also, it would have been nice if you would have used examples to solve your initial "but if I want to find only the IP address of the DNS server…" goal. (Which appears to have 3 IPv6 addresses.) (Perhaps that answer is in the next day's posting which I haven't gotten to yet.)

Skip to main content