Hey, Scripting Guy! How can I determine the name of the local computer using WMI?
— BM
Hey, BM. As you noted in your email we Scripting Guys always tell people that, in WMI, you can simply use a dot (.) to refer to the local computer. For example, the following mini-script connects you to the WMI service on the local computer:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Cool, huh? Of course, as you pointed out that’s really only half the story: yes, we can use a dot to refer to the local computer, but what if we need to know the name of that computer? When it comes to doing that, when it comes to helping you determine the name of the machine that the dot represents, well, in that case the Scripting Guys haven’t been much help.
Note. To be honest, it doesn’t really sound like the Scripting Guys to do half a job and then just plain give up on it. Usually we don’t make it even that far before giving up on something! |
Before we go any further we should probably take a moment to address the skeptics in the audience. No doubt some of you are looking at this question and thinking, “So what’s the big deal here? If the script is running on the local computer, well, then why would you even care about the name of the local computer? And if the script is running remotely, well, wouldn’t you already know the name of the computer where the script is running? Wouldn’t you simply set the value of the variable strComputer to the name of that remote machine?”
The answer to all those questions is the same: maybe. But, then again, maybe not. For example, suppose our code is running as part of a logon script or a computer startup script, and suppose we need to log collected data to a database. In one of those scenarios we need to know the name of the computer. Yes, the script will run just fine by using a dot to represent the computer name, but we can’t rely entirely on the dot; if we do, our database will end up looking something like this:
Computer |
Number of Processors |
. |
1 |
. |
2 |
. |
4 |
. |
1 |
Cute, but not too terribly informative. Needless to say, a table like this would be a bit more useful:
Computer |
Number of Processors |
atl-ws-01 |
1 |
atl-fs-02 |
2 |
atl-dc-03 |
4 |
atl-ws-04 |
1 |
Likewise there might be times when we do need get the computer name when dealing with remote machines. With WMI you can connect to a remote computer by specifying the computer name; however, you can also connect to a remote computer by specifying an IP address:
strComputer = “192.168.1.1”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Because very few of us have memorized the IP addresses of all our computers (and because, thanks to DHCP, many of these IP addresses are wont to change anyway) a table like is also only marginally useful:
Computer |
Number of Processors |
192.168.1.1 |
1 |
192.168.1.2 |
2 |
192.168.1.3 |
4 |
192.168.1.4 |
1 |
In other words, even in this high-tech day and age of ours something as old-fashioned as a name can still come in handy. (Which sounds funny coming from a group that hides behind the collective moniker “The Scripting Guys,” doesn’t it?)
So can we use WMI to determine the name of the local computer (or, say, a remote machine where all we know is the IP address)? You bet we can. And when we tell you that there are hundreds and hundreds of different ways to do that, well, we aren’t kidding. For example, suppose you have a burning desire to use the Win32_BIOS class to determine the computer name. Hey, why not:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery(“Select * From Win32_BIOS”)
For Each objItem in colItems Wscript.Echo objItem.Path_.Server Next
As you can see, this is a standard WMI script, one that binds to the WMI service on the local computer. We then use this line of code to retrieve BIOS information for that machine:
Set colItems = objWMIService.ExecQuery(“Select * From Win32_BIOS”)
Why did we pick the Win32_BIOS class? No reason; we could have picked any WMI class. That’s because each and every WMI class returns an SWbemObjectPath object; the Path_ property for that object serves as the unique address for the item in question. For example, the Path_ to the BIOS on a computer might look something like this:
\\ATL-WS-01\root\cimv2:Win32_BIOS.Name=”EPP runtime BIOS – Version 1.1 “, SoftwareElementID=”EPP runtime BIOS – Version 1.1 “,SoftwareElementState=3, TargetOperatingSystem=0,Version=”HP – 22110520”
That path is unique: no other object on the computer atl-ws-01 will have that same path.
As you can see, the name of the computer (ATL-WS-01) is embedded in the beginning portion of that path. (Which makes sense: not including the name of the computer in the path would be about as useful as having an address of 111 Main Street that didn’t include the name of the city.) Admittedly, we could do some fancy string manipulation in order to try and tease out the computer name from the path. Or, we could simply ask for the value of the Server property, like we do here:
For Each objItem in colItems Wscript.Echo objItem.Path_.Server Next
It’s that easy. And, best of all, any WMI object you get back from a script will include an SWbemObjectPath object and the Server property. Are you already using the Win32_ParallelPort class to connect to a machine? That’s fine; while you’re there you can get the value of the Server property using Win32_ParallelPort:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery(“Select * From Win32_ParallelPort”)
For Each objItem in colItems Wscript.Echo objItem.Path_.Server Next
Connecting to a machine using the Win32_PrinterConfiguration class? Then you can get at the value of the Server property using Win32_PrinterConfiguration. Connecting to a machine using the Win32_LogicalDisk class? Then you can get at – well, you get the idea.
But what if you don’t like all this talk of SWbemObjectPaths? Well, in that case you can always rely on the Win32_ComputerSystem class to get the computer name:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”) Set colItems = objWMIService.ExecQuery(“Select * From Win32_ComputerSystem”)
For Each objItem in colItems Wscript.Echo objItem.Name Next
That works just fine; it’s just nowhere near as cool as using the Win32_TimeZone class to determine the computer name. And just think of how many bar bets you’re likely to win now; after all, from here on you’ll be able to walk into a crowded bar and tell people, “Give me the name of a WMI class – any WMI class – and I’ll use just that class to determine the name of a computer.” If people aren’t impressed by that then maybe they aren’t worth impressing.
We hope that answers your question, BM. After all, we Scripting Guys take pride in our motto: Leave no job undone. We don’t necessarily live up to that motto, mind you. But we do take pride in it.
0 comments