Don’t Write WMI Scripts, Use a PowerShell Module

Don’t Write WMI Scripts, Use a PowerShell Module

  • Comments 4
  • Likes

Summary: Learn how to use a free Windows PowerShell module to avoid writing WMI scripts to get common administrator information.

 

Microsoft Scripting Guy Ed Wilson here. One of the things that is really cool about Windows PowerShell modules, is that you can mix and match them. In this way, a module, a pair of modules, or an entire collection of modules becomes the tools for a bespoke script solution. I can tailor the solution to meet my exact needs, and to provide access to exactly the information I need.

If I am the author of the module, I can use it for my own needs, store it in my personal modules directory, and I have a tool to use. In addition to personal use, if I share the module with my co-workers, I now have a tool to use across the network. It is easy to share a module, and there are more than 100 modules in the Scripting Guys Script Repository.

With Windows PowerShell, quite often I can find a module that contains the capability I need, which means I avoid writing a script. To garner maximum return on my time, when I need to write a script, I should write a module.

However, as I indicated earlier, many times I do not need to write anything because a module already exists. For example, an excellent module is the one written by Microsoft PowerShell MVP Richard Siddaway. Richard wrote a module that he calls PAM--the PowerShell Admin Modules. The PAM consists of a number of modules. To install, all you need to do is to first unblock the compressed (.zip) file that arrives when downloaded via codeplex. Next, copy all the folders into the modules directory. It is very important to first unblock the download files, or the module will never work properly (not just the PAM--any module; see this Scripting Wife article for the details of blocked files, and a cool workaround).

To find decent information about the installed operating system on a computer (either local or remote), use the Get-OsInfo advanced function from the PAM. The command and the associated results appear here.

PS C:\> Get-OSInfo 

Caption                 : Microsoft Windows 7 Enterprise

ServicePackMajorVersion : 1

ServicePackMinorVersion : 0

BuildNumber             : 7601

Code Set                : Latin I

Country Code            : USA

Install Date            : 8/7/2009 1:26:32 PM

Locale                  : English - United States

OSArchitecture          : 64-bit

OS Language             : English - United States

OS Type                 : WINNT

BootDevice              : \Device\HarddiskVolume1

SystemDevice            : \Device\HarddiskVolume2

Version                 : 6.1.7601

WindowsDirectory        : C:\Windows

The information returned by the Get-OSInfo function is extremely useful. Now, do I have to use Get-OSInfo? No, in fact, until PAM came along, I used WMI to retrieve the information. The information is readily available from the Win32_OperatingSystem class. Here is the command I generally used.

PS C:\> Get-WmiObject win32_operatingsystem

 

SystemDirectory : C:\Windows\system32

Organization    : Microsoft IT

BuildNumber     : 7601

RegisteredUser  :

SerialNumber    : 00392-918-5000002-85165

Version         : 6.1.7601

The problem with the above output, is that several of the properties in which I am interested do not appear directly. This is easily addressed by sending the output to the Format-List cmdlet and using the wildcard character (an asterisk) to retrieve all of the property information. The revised command becomes the one that appears here.

Get-WmiObject win32_operatingsystem | Format-List *

The command and associated output appear in the following figure.

Image of command and associated output

One problem is the output is very extensive. In addition, some of the properties do not return any information, and others, such as InstallDate, return the information in an unusable fashion. This is the great thing about a Windows PowerShell Module: Richard picked out the information that is commonly utilized, cleaned up the output, and then packaged it in a form that is easily consumable for other people. Therefore, my choice now is as follows: do I write a long command that does not return the information I need and that returns it in a fashion I cannot use, or do I type a simple command --Get-OsInfo--and receive only the information I seek? Hmm…it is not much of a choice is it?

In addition, because Richard wrote his advanced function in an intelligent manner and he returns objects, I can further manipulate the information to retrieve exactly what I need. For example, one of the things I like to know is when the operating system was installed. It’s not like it used to be when I used to reinstall Windows every six months, but a fresh installation does solve lots of strange problems. With an automated deployment, it can be done quicker than it takes to troubleshoot some problems. To get this information, I use the Get-OsInfo function as appears here.

PS C:\> (Get-OSInfo).'install date' 

Friday, August 07, 2009 1:26:32 PM

There are two things of note here. The first one is that because the property name has a space in it, I need to place quotation marks around it. I use single quotation marks, but double quotation marks would work as well. The following command illustrates this approach.

PS C:\> (Get-OSInfo)."install date" 

Friday, August 07, 2009 1:26:32 PM

So why did I use single quotation marks? On my laptop, they are easier to type (do not have to hold down Shift as I do when typing double quotation marks.) 

Now, if I want to figure out how many days it has been since the operating system was installed, I can use the New-TimeSpan cmdlet and pass it the ‘install date’ property from the Get-OsInfo advanced function. The command and associated output appears here.

PS C:\> New-TimeSpan -Start (Get-OSInfo).'install date'

 

Days              : 684

Hours             : 21

Minutes           : 15

Seconds           : 40

Milliseconds      : 269

Ticks             : 591741402692880

TotalDays         : 684.885882746389

TotalHours        : 16437.2611859133

TotalMinutes      : 986235.6711548

TotalSeconds      : 59174140.269288

TotalMilliseconds : 59174140269.288

This output is not precisely the answer to my question (about the number of days) because it returns more information than just days. Using dotted notation, I can easily only return the days by using the following command:

PS C:\> (New-TimeSpan -Start (Get-OSInfo).'install date').days

684

PS C:\>

I asked Richard about the PAM project, and here is what he had to say:

"The PowerShell Admin Modules (PAM) are currently on version 0.6 (6 releases), comprise eight modules, and supply a total of 49 functions. Additions to the range are in the pipeline in terms of extra modules and in some cases extra functions.

I’ve been blogging, writing and speaking about Windows PowerShell since 2006 so why add the PAM project to the list. There are a number of reasons:

  • Modules are the easiest way to load sets of functionality.
  • I wanted to collect some of my scripts together and convert them to advanced functions and  modules.
  • I wanted to make it easy to get at the set of functions without searching across multiple blog posts.
  • I tend to write and blog about using Windows PowerShell to solve admin problems and making the modules available through a central site makes life easier for the administrator.

After I’d produced the first modules, I decided to create a CodePlex project because it was a central site that made the functionality easy to find and access.

I did spend some time thinking about how to structure the modules.  My initial thought was to create one big monolithic module, but I then realized that I often want to work on a particular problem and didn’t necessarily need the full set of functionality. Creating a set of granular modules makes it easier to load just the functions I need. It also makes them easier to update.

Creating the modules has made me think about the tasks that administrators need to perform and the functions that I need to add to help them solve those tasks. If there is any functionality you would like to see added, please leave a comment at http://psam.codeplex.com/discussions. I can’t guarantee when I’ll get to it but I will try to create the functions."

 

Thank you, Richard! Write Modules, Not Scripts Week will continue tomorrow. 

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
  • Thanks Ed!

    ... and Thanks Richard! for sharing the module with us!

    That reminds of something, I'd always complained about referring to Active-X objects:

    There is a certain need to have a kind of "global catalogue" :-) of modules!

    I'd like to search for some functionality there and hope to get resulting links to

    modules exposing the needed function as well as a documentation of the module.

    Well ... we all may google to find that ... but a place like the CPAN e.g.

    www.cpan.org/.../index.html, the index of perl modules ... is an

    incredible usefull resource for perl programmers!

    I know, there is a Hey, Scripting Guy! Blog, there is a codeplex project site, a blog maintained by each MVP and there are many other places where you can go ... but a central site to start with is something to consider ...!

    Klaus

  • Klaus says: "There is a certain need to have a kind of "global catalogue" :-) of modules"

    Do you mean like CarPoint?

    Why don't you start a site like that?

  • Far too much bloat with these scripts. most of this stuff can be done with one-liners. nice addition for the newbies tho.

  • @Rebo - you are UnBr0n. Even you cannot devise a one-liner to get out of this. Infidel. Abraxis. Non clemente non disitur! I banish thee!