Hey, Scripting Guy! How can I tell which version of the .NET Framework is installed on a computer?
Hey, MW. You know, every now and then people say to us, “Wow, you guys write a daily column about system administration scripting; you must be really smart.” We wish. The truth is, we write a daily column about system administration because we aren’t smart. When we first began this column (our one-year anniversary is fast approaching) we assumed that it would be easy: people would ask us questions like, “How do I display information in a message box?” and we’d respond by writing a script like this:
Msgbox "Here is information in a message box."
The rest of the day would then be free for playing Internet poker and watching baseball. Sweet.
What we failed to take into account, though, is the fact that while Windows is an excellent platform for system administration scripting it’s not without its weaknesses. And, needless to say, those weak spots represent the things nearly everyone asks questions about. (Come on, doesn’t anyone want to know how to display information in a message box?) As a result, we have to spend a lot of time researching various problems, trying out possible solutions, and, well, working. Meanwhile, the World Series of Poker goes on without us.
Scripting Guys Opinion. No, we do not believe that the World Series of Poker should be seen on ESPN; the same goes for the National Spelling Bee, the X Games, the NBA, and other pseudo-sports. (We have nothing against these events, but come on: not at the expense of baseball or college basketball.) Of course, if ESPN is willing to broadcast Scripting Week 3, well, we’re willing to reconsider our position. ESPN, we’re waiting to hear from you.
Editor’s Note. Now for the legal stuff: The opinions expressed here are not necessarily the opinions of the Microsoft Corporation or anyone else affiliated with Microsoft, etc. etc. As a matter of fact, not all of the Scripting Guys even agree on what a “sport” is. (But really, poker and spelling?)
MW’s question about the .NET Framework is a good example of the dilemma we sometimes face. It’s very important to know which version of the .NET Framework is installed on a computer, especially when you’re working with custom applications written in-house; the Scripting Guys know from painful experience that custom applications often require a very specific version of the .NET Framework. Any version earlier - or later - and the application might not run.
Because of that you might think there’s a very quick, easy way to determine which version (or versions) of the .NET Framework is installed on a computer. Well, if there is, we couldn’t find it: we were unable to locate a COM object or a specific registry key that could tell us, once and for all, which version is installed on a computer. The best we could do was this brute force method, a method which is accompanied by a caveat we’ll talk about momentarily. First let’s take a look at the script:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Product")
For Each objItem in colItems
If InStr(objItem.Name, "Microsoft .NET Framework") > 0 Then
As you can see, the script itself is pretty simple. We begin by connecting to the WMI service and then use the ExecQuery method to retrieve a collection of the all the instances of the Win32_Product class. Win32_Product is designed to retrieve information about all the software on a computer that was installed using Windows Installer (i.e., a .MSI file). Win32_Product is not foolproof - it sometimes misses an application that really was installed using Windows Installer - but it seems to have no problem identifying most major software programs, including the .NET Framework.
After issuing the query we set up a For Each loop to cycle through the collection of software products installed using .MSI files. Inside this loop we use this line of code and the InStr function to see if the application name includes the string Microsoft .NET Framework:
If InStr(objItem.Name, "Microsoft .NET Framework") > 0 Then
Note. We called this a brute force method because we’re returning all the installed software products and laboriously checking each name. We could have used the LIKE operator to return only software that has the string Microsoft .NET Framework somewhere in its name. Unfortunately, though, the LIKE operator is found only on Windows XP and Windows Server 2003. Because of that, we went with the brute force method to ensure that the script would also run on Windows 2000.
All we’re doing here is passing InStr two parameters: objItem.Name (a variable which contains the name of the application) and our target string (Microsoft .NET Framework). If our target string cannot be found in objItem.Name, then the return value of InStr will be 0; if the target string can be found, then InStr will be a value other than 0. To be specific, InStr will equal the character position where our target string begins. For example, suppose objItem.Name equals this:
The Microsoft .NET Framework Version 2.0
In that case, InStr will equal 5, because the string Microsoft .NET Framework begins at the fifth character. If InStr is greater than 0 we echo the Version property of the application; in other words, we’ll get back information similar to this:
And, of course, if we have multiple version of the .NET Framework installed we’d get back more than one version number.
As you can see, this actually works quite nicely. So what’s the problem? Well, there are really two issues. For one, this can be a little slow: the Win32_Product class is no speed demon, and it could take 30 seconds or so before you get any information back (depending in large part on how many applications are installed on your computer). More important, the Win32_Product class is not installed by default on Windows Server 2003. If you want to run the script against a Windows 2003 machine you’ll need to do the following:
In Add or Remove Programs, click Add/Remove Windows Components.
In the Windows Components Wizard, select Management and Monitoring Tools and then click Details.
In the Management and Monitoring Tools dialog box, select WMI Windows Installer Provider and then click OK.
Yes, kind of a hassle, but probably worth it. After all, the Win32_Product class can be used to get at more information than just the version of the .NET Framework installed on a computer.
Oh, and did we mention that we use this line of code to display information in a message box?
Then again, if you’re running under CScript, information will display in the command window instead of a message box. OK, so maybe it isn’t so bad that people don’t ask us questions like, “How do I display information in a message box?” Even that isn’t as simple as we thought it was.