Mr. Script

Using WMI Remotely

Two different solutions for using WMI with remote connections.

I recently received an e-mail from Doug Cox, a regular reader of this column. Doug was working through a script from an old column (“Addressing the Issue,” June 2002) that used Windows Management Instrumentation (WMI) to change a computer’s TCP/IP settings. Doug writes, “This [script] works great if you’re logged on with administrative privileges. However, if not, you get a return code of 91, ‘Access denied.’ How can I run this same script on a local machine with a power user logged on? I know there’s a way through WMI, but I just can’t figure it out. Can you help?”

Well, I have good news and bad news. The good news is that WMI does, indeed, allow connecting with different credentials. The bad news is that it only works with remote connections—not on scripts running on the local machine.

When you connect to a remote computer, you can “connect as” by providing a username and password. (This is explored in-depth shortly and in the corresponding script.) However, this should be reserved for very specific tasks. In Doug’s case, I don’t think it’s the way to go. First and most importantly, in order to do this, you have to “hardwire” the username and password of an admin (or otherwise sufficiently powerful) account into the script. Even if you encrypt the script using the Script Encoder, someone could easily obtain this account information and use it maliciously. Second, WMI can do anything remotely that it can do locally. You’re better off executing these scripts remotely from the safety of your admin workstation and operating under your own administrative privileges. The result is the same: The currently logged-on power users aren’t required to log off (and will be unaware that you’re changing settings on their computers), and you can make all the TCP/IP changes needed.

While using alternate credentials to connect via WMI didn’t turn out to be the right solution for Doug (sorry, dude!), there are times when it can be quite useful. A perfect example of this is when working with multiple domains where there’s no trust relationship (like my former life as an IIS admin).

Situation 1: You’re the administrator of several Web servers that are members of a different domain. There’s no trust relationship between the two domains, but you have an admin account on the Web server domain. One of your servers has stopped responding and needs rebooting. Unfortunately, the servers are located in a secure building at the client’s government complex.

'RemoteRebootSU.vbs
'Reboot a remote computer using alternate
'security credentials
Dim objLocator, objWMI, colOS, clsOS
Set objLocator=CreateObject("WbemScripting.SWbemLocator")
Set objWMI=objLocator.ConnectServer("remotecomputer", _
  "root\cimv2", "User", "Pass")
objWMI.Security_.ImpersonationLevel=3 'Impersonate
objWMI.Security_.Privileges.Add 18 'SeShutdown privilege
Set colOS=objWMI.InstancesOf _
  ("Win32_OperatingSystem where Primary=true")
For Each clsOS in colOS
  clsOS.Reboot()
Next

The first thing you’ll notice about the script is that it connects using the SWbemLocator object, rather than my preferred method of using a moniker. This is necessary when changing security credentials. I’ve also included a line that sets the “Shutdown” privilege. Strictly speaking, though, this isn’t required for remote connections. I’ve included it here for those who want this script to reboot the local machine (in which case, alternate credentials can’t be used. Round and round we go).

The ability to perform a task via WMI on a remote computer using different credentials can be quite helpful. Although I feel compelled to emphasize that hard wiring an admin account and password into a script is generally a very bad idea, as long as the script remains on your admin workstation and is protected by appropriate NTFS permissions (and possibly even stored in an encrypted folder), it should be OK. Again, this technique should only be used in specific instances.

Situation 2: Of the computers used in your organization, 20 servers were purchased at the same time (hey, you were expanding!) and are identical. You’ve been diligent at keeping them current with the latest software patches, but you’re not sure which ones have received the most recent BIOS update.

'GetBIOSVer.vbs
'Retrieves the BIOS information from remote computer

Dim ojLocator, objbWMI, colBIOS, clsBIOS
Set objLocator=CreateObject("WbemScripting.SWbemLocator")
Set objWMI=objLocator.ConnectServer("remotecomputer", _
  "root\cimv2", "User", "PWord")
objWMI.Security_.ImpersonationLevel=3 'Impersonate
Set colBIOS=objWMI.InstancesOf("Win32_BIOS")
For Each clsBIOS in colBIOS
  Wscript.Echo "Build Number: "& clsBIOS.BuildNumber
  Wscript.Echo "Current Language: " _
   & clsBIOS.CurrentLanguage
  Wscript.Echo "Installable Languages: " _
   & clsBIOS.InstallableLanguages
  Wscript.Echo "Manufacturer: " & clsBIOS.Manufacturer
  Wscript.Echo "Name: " & clsBIOS.Name
  WScript.Echo "SMBIOSBIOSVersion: " _
   & clsBIOS.SMBIOSBIOSVersion
  WScript.Echo "SMBIOSMajorVersion: " _
   & clsBIOS.SMBIOSMajorVersion
  WScript.Echo "SMBIOSMinorVersion: " _
   & clsBIOS.SMBIOSMinorVersion
  Wscript.Echo "Primary BIOS: " & clsBIOS.PrimaryBIOS
  Wscript.Echo "Release Date: " & clsBIOS.ReleaseDate
  Wscript.Echo "Serial Number: " & clsBIOS.SerialNumber
Next

When I want to see if my BIOS is current, I usually try to catch the version during the Power On Self Test (POST) or go into system setup and look at it. This can be a real pain in the neck when checking the BIOS versions of several servers. WMI allows performing this remotely, without requiring a reboot of the server. Of course, you still have to update the BIOS manually in the machines needing it. Still, this will save you a chunk of time.

For consistency’s sake, this script assumes that all of these computers are in another domain. In real life, however, some may be in your local domain. In this case, you simply remove the username and password specified in the connection string.

I could write many columns showing how to perform a really cool scripting task using WMI—it’s that powerful. I won’t because there are many other neat administrative tasks you can script that don’t involve WMI. In fact, we’re going to cover one such task next month.

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].

Featured

comments powered by Disqus

Subscribe on YouTube