Hey, Scripting Guy! How can I set the default printer based on the IP address of the computer?
— TT
Hey, TT. You’ll have to forgive us for being a little distracted this morning. Last night the Scripting Guy who writes this column went to the gym with his 16-year-old son. For the first time ever, the Scripting Son was able to bench press more than the Scripting Dad. Sure, the Scripting Dad can still beat his son in wrestling, but as the Scripting Son pointed out, “That’s just because you know all those moves. If I keep getting bigger and stronger, those moves won’t help you: I’ll just pick you up and crush you.”
And he will, too.
What that means, of course, is that the days of the Scripting Dad wrestling the Scripting Son – or at least wrestling him and winning – are numbered. Therefore, the Scripting Dad is beginning to look for new things to wrestle, things like, well, wrestling with the problem of changing the default printer based on the IP address of the computer.
Note. OK, so maybe that doesn’t make for the most exciting wrestling match ever held. But right now the Scripting Dad isn’t looking for a challenge, he’s looking for something he can beat. |
As you noted in your email, TT, you have several different subnets, and you’d like to set the default printer based on the second octet of those subnets. For example, if a computer is on subnet 192.1.x.x the user would be assigned one default printer; if the computer is on subnet 192.2.x.x the user would be assigned a different default printer.
Sounds hard, doesn’t it? In truth though, it’s pretty easy, at least for those dads who are stronger than their sons.
Fortunately, it wasn’t too hard for the rest of us, either:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery _ (“Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True”)
For Each objItem in colItems strIPAddress = objItem.IPAddress(0) arrIPAddress = Split(strIPAddress, “.”)
If arrIPAddress(0) = “192” Then
Select Case arrIPAddress(1) Case 1 Set colInstalledPrinters = objWMIService.ExecQuery _ (“Select * from Win32_Printer Where Name = ‘\\\\atl-ps-01\\printer1′”) For Each objPrinter in colInstalledPrinters objPrinter.SetDefaultPrinter() Exit For Next Case 2 Set colInstalledPrinters = objWMIService.ExecQuery _ (“Select * from Win32_Printer Where Name = ‘\\\\atl-ps-01\\printer2′”) For Each objPrinter in colInstalledPrinters objPrinter.SetDefaultPrinter() Exit For Next End Select End If Next
A few caveats here. First, we’re assuming that all the requisite printers have been preinstalled on the computers; if that’s not the case, you’ll have to modify the code to check for the existence of a particular printer and, if it can’t be found, install it. Second, we’ve used WMI to configure the default printer. The good news? That gives us a script that can run locally (perhaps as a logon script) or that we can run remotely. The bad news? That means the script shown above works only on computers running Windows XP or Windows Server 2003.
Note. Is there a workaround for those of you still using Windows 2000? You bet there is: you can use Windows Script Host 5.6 and its SetDefaultPrinter method to achieve the same effect. The only drawback to that approach is that the script must run locally; of course, if you are running this as a logon script then that’s a given anyway. For more information, see the Microsoft Windows 2000 Scripting Guide. Tell you what: if you can’t figure out how to get this to work on Windows 2000 let us know, and we’ll see what we can do to help you out. |
Now, where were we? Oh, yeah: the script. As you can see, we start out in pretty humdrum fashion; we simply use these two lines of code to connect to the WMI service on the local computer:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
After we make the connection, we then issue this query, which returns a collection of the IP-enabled network adapters found on the computer:
Set colItems = objWMIService.ExecQuery _ (“Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True”)
Incidentally, the Where clause – Where IPEnabled = True – is important: it helps us filter out all the “network adapters” that don’t have (or can’t get) IP addresses. That might sound silly, but WMI considers all sorts of things (like virtual machine drivers and packet schedulers) to be network adapters. It’s a good idea to get in the habit of using IPEnabled = True to help zero in on your real network adapters. (The script will actually work just fine without this Where clause, but ….)
Once we have the collection we then set up a For Each loop to walk through all the network adapters in that collection. What we do inside that loop is actually pretty easy, but it does require a bit of explanation.
To begin with, we use this line of code to get the first IP address assigned to the first network adapter in the collection:
strIPAddress = objItem.IPAddress(0)
Granted, a single network adapter can potentially have more than one IP address. We’re assuming that if you’re mapping printers as part of a logon script then you’re probably dealing with client workstations; if that’s the case, then you don’t need to worry about “multi-homed” adapters. We’re taking a calculated risk that most (if not all) of your network cards will have just one IP address, so we take a shortcut here and grab just that first IP address.
So let’s say we now have the IP address 192.2.168.1. We’re interested in only the second octet; in this case 2. How do we isolate that value? Well, to begin with, we use the Split function to split the IP address into an array:
arrIPAddress = Split(strIPAddress, “.”)
By splitting the IP address on the period, we end up with an array consisting of (in this example) the following items:
• |
192 |
• |
2 |
• |
168 |
• |
1 |
Our next step is to verify that the first octet (or item 0 in our array) is equal to 192:
If arrIPAddress(0) = “192” Then
Depending on your network setup this might not be a concern; that is, maybe all your IP addresses start with 192. We tossed this in just to be on the safe side.
We then use a Select Case statement that examines the value of the second octet (item 1 in our array):
Select Case arrIPAddress(1)
We then have a series of Case statements that check for the possible values of this second octet. For example, because our second octet is 2, this Case statement applies to us:
Case 2 Set colInstalledPrinters = objWMIService.ExecQuery _ (“Select * from Win32_Printer Where Name = ‘\\\\atl-ps-01\\printer2′”) For Each objPrinter in colInstalledPrinters objPrinter.SetDefaultPrinter() Exit For Next
As you can see, what we’re doing here is using a WMI query to select all the printers that have the Name \\atl-ps-01\printer2; because printer names must be unique, that returns a collection consisting of, at most, one printer. And, no, we didn’t fall asleep with our finger on the \ key when we typed the printer name like this:
\\\\atl-ps-01\\printer2
As you probably know, the \ is a reserved character in WMI; that means that any time we use the \ in a Where clause we have to “escape” the character by prefacing it with another \. In other words, we have to double up each \; that means that the two \\’s found at the beginning of the string end up being four \\\\’s.
Crazy, huh?
Next we set up a For Each loop to walk through all the items in that collection; inside that loop we then use the SetDefaultPrinter method to make \\atl-ps-01\printer2 the default printer:
objPrinter.SetDefaultPrinter()
After that we exit the For Each loop. Why? Well, we’ve already assigned a default printer; there’s probably no reason to assign that default printer all over again (assuming that there’s another network adapter with an IP address starting with 192). Of course, if there is a reason to assign the default printer all over again then you can simply remove the Exit For statement.
You’ll need to set up similar Case statements (or some kind of function) to account for all the other possible values of that second octet. To do that, simply specify the octet value as part of the case statement (e.g., Case 3) and then include code that assigns the relevant printer for that subnet. All in all, it’s easy, way easier than the bench press. (Which, when you come to think of it, is kind of silly: since when does being able to lift heavy weights have anything to do with how strong you are?)
Hope that helps, TT. As for us, we have to go home and challenge the Scripting Son to a wrestling match. We need to try to get in as many victories over him as we can; after all, we have a sinking feeling that as soon as he beats us one time we’ll never be able to beat him again.
Oh: and here’s a version of this script that works on Windows 2000. Now that we can no longer count on beating people up we figured we’d better start being nice instead:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery _ (“Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True”)
Set objNetwork = CreateObject(“Wscript.Network”)
For Each objItem in colItems strIPAddress = objItem.IPAddress(0) arrIPAddress = Split(strIPAddress, “.”)
If arrIPAddress(0) = “192” Then
Select Case arrIPAddress(1) Case 1 Set colInstalledPrinters = objWMIService.ExecQuery _ (“Select * from Win32_Printer Where Name = ‘\\\\atl-ps-01\\printer1′”) For Each objPrinter in colInstalledPrinters objNetwork.SetDefaultPrinter objPrinter.Name Exit For Next Case 2 Set colInstalledPrinters = objWMIService.ExecQuery _ (“Select * from Win32_Printer Where Name = ‘\\\\atl-ps-01\\printer2′”) For Each objPrinter in colInstalledPrinters objNetwork.SetDefaultPrinter objPrinter.Name Exit For Next End Select End If Next
0 comments