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
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.
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
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 email@example.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy