A PowerShell Object Lesson: Part 2

A PowerShell Object Lesson: Part 2

  • Comments 6
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the importance of returning objects to ease administrative work.

Microsoft Scripting Guy, Ed Wilson, is here. This afternoon I am sipping a magnificent cup of Oolong green tea. I added a spoonful of jasmine buds to my teapot, in addition to a half cinnamon stick and a spoonful of lemon grass. The result is perfect. It goes well with the macadamia nuts I am munching on right now.

Note  This is the second part of a three part series that talk about Windows PowerShell objects. In A PowerShell Object Lesson: Part 1, I talked about the advantage of using Windows PowerShell objects, and how they are helpful to the scripter.

I got it through the pipeline

The next really cool thing about objects is that I can send them down the pipeline to other commands. The other commands might do things or format things. For example, a common way that people who come from other scripting languages write scripts is to “echo” everything. When they find the Write-Host cmdlet, they immediately begin to select the properties they want to display. An example of such a script is shown in the following image:

Image of script

In addition to wasting a lot of time selecting properties, it takes a long time to write all that code. I am actually stepping back in time in terms of usefulness and productivity. The default output from Get-Process is actually better, in my opinion—and as will be seen in a bit, it is more useful. Here is the default output from Get-Process:

Image of command output

If I send the output to the Get-Member cmdlet, I can see that there are more properties available than just the default displayed here. In fact, there are a number of methods as shown in the following image:

Image of command output

The cool thing about methods is that methods do things. After I use the Get-Member cmdlet, the first thing that appears at the top of the screen is the TypeName line. It tells me that I have an instance of the System.Diagnostics.Process object. If I do not know what that is, I can look up that exact phrase on MSDN, and it will tell me everything about the object—including how to use the various methods that appear in the output.

The cool thing about Windows PowerShell and objects is that I do not need to dive into the .NET Framework or MSDN to be able to do some things. For example, my Process object has the following cmdlets that automatically work:

PS C:\> Get-Command -Noun process

 

CommandType     Name                                               ModuleName

-----------     ----                                               ----------

Cmdlet          Debug-Process                                  Microsoft.Powe...

Cmdlet          Get-Process                                       Microsoft.Powe...

Cmdlet          Start-Process                                     Microsoft.Powe...

Cmdlet          Stop-Process                                     Microsoft.Powe...

Cmdlet          Wait-Process                                      Microsoft.Powe...

For example, if I want to stop the Notepad process, I can open MSDN and figure out how to call the Kill() method, or I can simply try the Stop-Process cmdlet. When I take the process object that comes from Get-Process and send it to the Stop-Process object, it automatically stops the processes. The command is shown here:

Get-Process notepad | Stop-Process

The following image illustrates the command, and then shows that Get-Process can no longer find any Notepad processes:

Image of message

Without using the pipeline, I would need to call the Kill method. It is not difficult, but it is another step. Here is an example:

PS C:\> $process = Get-Process notepad

PS C:\> $process.Kill()

Join me tomorrow when I will talk more about working with objects.

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

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I tried the below code and it worked - Few process ID runs even we close applications - I did this because it was crashing and unable to start or stop this. When I used in try catch block it worked good. It's custom made app.

    $process = Get-Process "Name"

    $ID = $Process.id

    Stop-Process $ID

    Your post is Awesome!!!

  • @Chen V awesome. I am glad it worked for you. Thanks for sharing.

  • Hey Ed,

    Awesome post as always.  I have a follow-up question about this:

    In the past, I was working on Internet Explorer UI automation and I was running into a problem trying to find an elegant way to close the IE COM objects I was working with.  Because, if I got the process ID for that instance of the IE window and used Stop-Process, the IE window would re-load, as it was restarting because it thought it was an unexpected shutdown.  And for some reason, the Quit() method wasn't always working.

    Have you ever had experiences trying to Stop or Kill a process / object that was giving you trouble?

  • @Robert

    To properly release COM object call ReleaseComObject static method at the end of script:

    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($x)

    Full explanation in PS tip:

    technet.microsoft.com/.../ff730962.aspx

  • I asked yesterday how to find what property name to use to get a piece of information, and although it might still take several commands of discovery, at least Get-Member helps so you can get all the methods and properties and events. Thanks for the info.

    A cmdlet appears to be different than a method. What exactly is a cmdlet in this object scheme?

    Do all objects support those automatic cmdlets listed in the post? (Is that even a valid question considering my above question - ie, do objects support cmdlets?)

  • Thank you so much, JacekZ!