PowerShell for Windows Admins

May 3, 2011  2:53 PM

Book review: Learn Windows PowerShell in a Month of Lunches

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Author: Don Jones

Publisher: Manning

ISBN: 978-1617290213

Don Jones is a well-known PowerShell MVP, trainer, author and blogger. This is his latest book on PowerShell. It sets out to teach a complete new comer to PowerShell how to use the language and commands to get stuff done. That is an important point – the book is about learning PowerShell so that you can use it to automate your administrative tasks.

The book is not an abstract look at PowerShell as a language but treats it as a tool you want to learn. It assumes you will be reading the chapters in order (which I would strongly recommend) and that you will be performing the exercises and running the code examples. Please make sure you do as it’s the only way you will get the maximum benefit from the book.

As I have stated in other reviews I have three main criteria for judging a book:

· Is it technically accurate?

· Does deliver the material it claims to deliver?

· Is worth the cost of purchase and the time I spend reading it?

The first one is easy to deal with. Yes it is technically accurate. Don is an expert on the subject of PowerShell and more importantly for a book of this sort he is an expert on how to teach it. The book has been reviewed by a number of PowerShell experts and I performed the final technical review. It’s as accurate as it can be!

The book has the following chapters:

1. Before you begin

2. Running commands

3. Using the help system

4. The pipeline: connecting commands

5. Adding commands

6. Objects: just data by another name

7. The pipeline, deeper

8. Formatting—and why it’s done on the right

9. Filtering and comparisons

10. Remote control: one to one, and one to many

11. Tackling Windows Management Instrumentation

12. Multitasking with background jobs

13. Working with bunches of objects, one at a time

14. Security alert!

15. Variables: a place to store your stuff

16. Input and output

17. You call this scripting?

18. Sessions: remote control, with less work

19. From command to script to function

20. Adding logic and loops

21. Creating your own “cmdlets” and modules

22. Trapping and handling errors

23. Debugging techniques

24. Additional random tips, tricks, and techniques

25. Final exam: tackling an administrative task from scratch

26. Beyond the operating system: taking PowerShell further

27. Never the end

28. PowerShell cheat sheet

Each chapter is designed to be read, and the exercises performed, in an approximately one hour lunch break. They are short, concise and very much to the point. Don has a very easy writing style that stops the topics being dry. The humour comes through in places to liven things up.

This is a book about doing. If we look at chapter 17 for instance – this is where scripting is introduced as the previous chapters show what you can do with PowerShell just from the command line. The chapter has 7 solid examples plus a lab. There are two callouts urging you to try the code and a list of ideas to try at the end of the chapter. All of this in 12 pages!

As well as the basics of the PowerShell language the book covers what might be considered more advanced topics such as remoting and PowerShell jobs.

In a nutshell this book teaches you how to use PowerShell. If you work through the chapters and labs you can’t fail to learn how to use PowerShell. Will it make you an overnight expert? No it won’t but it will provide a very solid foundation for you to progress and discover more about PowerShell yourself.

Don is a teacher and that comes through the way the book is written and constructed. In terms of my last two questions:

· Does it deliver the material it claims – YES. There were a couple of points in the book that made me think about me assumptions about PowerShell.

· Is it worth the money to buy and the time to read – YES.

On the back cover there’s a quote of mine “The book I wish I’d had when I started PowerShell”. That sums it up for me. It’s an excellent introduction to PowerShell itself and achieves exactly what it states it will do.

If you are new to PowerShell, or want to get started with it I can’t recommend this book strongly enough. Buy it. Read it. Use it.

May 1, 2011  12:25 PM

PowerShell Deep Dive: VI WQL Query Speed–Remote

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Looking at WQL query vs a Get-WmiObject filter on the local machine we saw that they were practically the same. If we used a where-object to do the filtering it took nearly twice as long.

I wanted to repeat these runs against a remote machine.  I use two Windows 2008 R2 servers for the test.


PS> 1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process -Filter "Name=’Notepad.exe’" -computername webr201}} |

Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 29.678681
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


PS> 1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name=’Notepad.exe’" -computername webr201}} | Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 30.669341
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


PS> 1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process -computername webr201 | Where {$_.Name -eq ‘Notepad.exe’} }} |

Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 59.997321
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


Results Summary

Filter: 29.678681

Query:  30.669341

Where:  59.997321

Again the filter and the query are nearly the same. I millisecond difference in the average of 100 runs is not enough to worry about. Using where-object is again about twice the time.

The results this time are quicker than running on the local machine.  This is because the server I used is more powerful than the laptop I used for the local test. The important thing is the relationships not the exact numbers. I ran the tests locally on the server and got similar pattern of results.

After all this I would say the running a full WQL query or using –Filter are about the same in speed. There may be a gain for the query if we selected properties as well but the extra typing and checking probably don’t justify the gain. Use a query or use a filter the results will be similar.  I’ll stick with the filter because its less typing.

May 1, 2011  4:13 AM

PowerShell Deep Dive: V WMI associations

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

NOTE: If you are wondering why the Deep Dive posts are non-consecutive – they are part of a longer series posted here http://msmvps.com/blogs/richardsiddaway/default.aspx

WMI classes will sometimes have be associated with other classes for example each instance of the Win32_NetworkAdatper class is associated with an instance of the Win32_NetworkAdapterConfiguration.  The link is expressed by the Win32_NetworkAdapterSetting which shows the links.

I normally use WQL queries based on ASSOCIATORS and REFERENCES to discover these classes.  ASSOCIATORS shows the end point of the link and REFERENCES shows the linking class

We can do some of this work directly from the WMI object.

Lets get a network adapter object (you will need to use a deviceid thats present on your machine)

$nic = Get-WmiObject Win32_NetworkAdapter  -Filter "DeviceId=11"

and check its methods

$nic | gm -MemberType method


This doesn’t show what we need so we’ll drop to the underlying object

$nic.psbase | gm -MemberType method


which shows two methods of interest



We could also use

$nic | gm -MemberType method -View base

The methods relate to WQL like this

GetRelated = Associations
GetRelationships = References


What we get with these methods is the full related object.  We don’t have a method on the object to discover the classes that are related. For that we stick with WQL

Get-WmiObject -Query "ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=11} WHERE ClassDefsOnly"
Get-WmiObject -Query "REFERENCES OF {Win32_NetworkAdapter.DeviceID=11} WHERE ClassDefsOnly"


though these snippets are equivalent

$nic.GetRelated() | select __class –Unique

$nic.GetRelationships() | select __class –Unique


If we want to see the associated classes we can do this



Get-WmiObject -Query "ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=11}"


For a specific result class we can do this



et-WmiObject -Query "ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=11} WHERE ResultClass=Win32_NetworkAdapterConfiguration"


Switching to the links between classes – if we want to see all the links



Get-WmiObject -Query "REFERENCES OF {Win32_NetworkAdapter.DeviceID=11} "


and if we want to see a single link



Get-WmiObject -Query "REFERENCES OF {Win32_NetworkAdapter.DeviceID=11} WHERE ResultClass=Win32_NetworkAdapterSetting"

This gives us two routes to the information we need.  Use whichever you are most comfortable with.

April 30, 2011  12:02 PM

PowerShell Deep Dive III: WQL query speed

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One topic that came up during my talk at Deep Dive was the speed of running a WQL vs using –Filter in Get-WmiObject.  I’d never tested it so its time to find out.

PowerShell v2 has a handy cmdlet called Measure-Command that times how long a command runs

We’ll start with using a filter

Get-WmiObject -Class Win32_Process -Filter "Name=’Notepad.exe’"


if we wrap it in Measure-Command we get this

Measure-Command -Expression {Get-WmiObject -Class Win32_Process -Filter "Name=’Notepad.exe’"}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 81
Ticks             : 817436
TotalDays         : 9.46106481481481E-07
TotalHours        : 2.27065555555556E-05
TotalMinutes      : 0.00136239333333333
TotalSeconds      : 0.0817436
TotalMilliseconds : 81.7436


We want the TotalMilliseconds property and we need to do it more than once


1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process -Filter "Name=’Notepad.exe’"}} |

Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 52.640332
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


Now lets repeat as a query

Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name=’Notepad.exe’"


which becomes

Measure-Command -Expression {Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name=’Notepad.exe’"}


1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name=’Notepad.exe’"}} |

Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 52.345972
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


Just for fun lets try this

1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process | Where {$_.Name -eq ‘Notepad.exe’} }} |

Measure-Object -Property TotalMilliseconds -Average

Count    : 100
Average  : 92.96794
Sum      :
Maximum  :
Minimum  :
Property : TotalMilliseconds


So the results so far

Filter:  52.640332

Query:   52.345972

Where:   92.96794

The filter and the query are almost the same – I’m not going to argue over 0.03 milliseconds.  Using Where-Object takes nearly twice as long. This is understandable because the query and filter pick out a single process but using Where-Object we return all processes and then filter.

I stated in my talk that it was better to use the filter because it was less typing. On these results I’ll stand by that statement for local machines as it takes me more than a few milliseconds to type the extra characters using a query.

Further research is needed:

  1. What happens if running against remote machines?
  2. is it faster to select properties in the query or using select-object

We’ll return to these points later

April 29, 2011  3:28 AM

PowerShell Deep Dive: II Win32_Volume

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One question that I was asked at the deep dive –

Is there a way to link a disk volume back to the physical disk it resides on?

There doesn’t seem to be. If we test the WMI classes associated with a volume we get these results


If anyone knows how to relate Win32_Volume to the physical disk (need to get the serial number off the disk) then I’d be interested in hearing about it

April 26, 2011  1:27 PM

May 2011–UK PowerShell UG

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

When: Tuesday, May 10, 2011 8:30 PM (BST)

Where: Live Meeting


Join PowerShell MVP and author Jonathan Medd to learn about PowerShell modules and how to get the most out of them.


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
  2. Copy and paste the required information:
    Meeting ID: 8TWQGF
    Entry Code: 6NB,TJm(m
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.

April 26, 2011  1:08 PM

System Stability part II

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Last time we looked at the Win32_ReliabilityStabilityMetrics and closed by stating we’d look at the reliability records.  Reliability records are event log records related to system reliability.  The working part of the record is shown below (after the system properties are removed)

ComputerName     : RSLAPTOP01
EventIdentifier  : 19
InsertionStrings : {Security Update for Microsoft .NET Framework 4 on  Windows XP, Windows Server     2003, Windows Vista, Windows 7, Windows Server 2008, {ac2a295d-228e-4941-8568-ff131f842920}, 105}

Logfile          : System
Message          : Installation Successful: Windows successfully installed the following update: Security Update for Mi                 crosoft .NET Framework 4 on Windows XP, Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 x86 (KB2446708)

ProductName      : Security Update for Microsoft .NET Framework 4 on Windows XP, Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008
RecordNumber     : 180291
SourceName       : Microsoft-Windows-WindowsUpdateClient
TimeGenerated    : 20110414224442.000000-000
User             : NT AUTHORITY\SYSTEM


This is fairly typical in that it shows something that has changed and could therefore affect system reliability. Which logs are involved.  On my system

PS> Get-WmiObject Win32_ReliabilityRecords | select Logfile -Unique


As we are talking about event logs they have to have a source

PS> Get-WmiObject Win32_ReliabilityRecords | select SourceName -Unique

Application Error
Application Hang

If we want to see the events related to a particular source then we can do this

PS> Get-WmiObject -Class Win32_ReliabilityRecords -Filter "SourceName=’Application Hang’" | Format-Table TimeGenerated, ProductName, Message –wrap –AutoSize

What we really need is a function to wrap the choices so we just choose parameters. Thats what we’ll do next

April 23, 2011  5:34 AM

System Stability

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

As admins one of the things we need to be able to prove is the stability and reliability of our systems. With Windows 7 and Windows 2008 R2 we have a way to do this

function get-stabilityindex {
Get-WmiObject -Class Win32_ReliabilityStabilityMetrics
-ComputerName $computer |
 select @{N="TimeGenerated"; E={$_.ConvertToDatetime($_.TimeGenerated)}},

Use the Win32_ReliabilityStabilityMetrics class – see http://msdn.microsoft.com/en-us/library/ee706632(VS.85).aspx for details

The function takes a computer name and returns the date and time a metric was computed and its value.

We’ll follow this up with a look at Win32_Reliability records next time

April 21, 2011  1:52 PM

PowerShell and WMI MEAP update

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Chapters 8 and 9 of PowerShell and WMI have been released into the MEAP. They are available from http://www.manning.com/siddaway2/


Chapter 8 covers the File system

  • Administer shares
  • Compress or encrypt files
  • Monitor file system events

Chapter 9 covers Services and processes including:

  • service load order
  • discover process owners
  • use WMI events to control processes

The code from the chapters is available for download.

Next up is chapter 10 dealing with printers.

Chapter 11 on Networking is complete and I’m working on the IIS WMI provider (chapter 12) and configuring a new server (chapter 13)


April 13, 2011  12:58 PM

Tuesday’s recording

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The recording from Tuesdays UG meeting is available.

Richard Siddaway has invited you to view a Microsoft Office Live Meeting recording.
View Recording
Recording Details
Subject: PowerShell and COM objects
Recording URL: https://www.livemeeting.com/cc/usergroups/view
Recording ID: Q4DPJT
Attendee Key: 4~_TzB%6w

The slides and scripts are available from


Previous meeting’s recordings are still available:

  • Regular Expressions
  • PowerShell utility cmdlets
  • PowerShell best practice
  • Remoting
  • Registry
  • DNS
  • Events
  • Modules

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: