How Can I List the Network Printers For the Logged-On User?

ScriptingGuy1

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I create a logon script that lists the network printers for the logged-on user, then writes that information to a text file?

— RC

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RC. You know, the nice thing about coming to work after a few days off is – well, OK, so maybe we can’t actually think of anything nice about coming to work after a few days off. If you happen to work at Microsoft, however, you’re at least likely to hear something interesting the moment you get back. For example, this morning the Scripting Guy who writes this column was in the bathroom when he overheard the following conversation:

“So how did he get a window office?”

“I had to give him a window office. He told me he gets violent and angry if he doesn’t have a window office. I didn’t want him to get violent and angry, so I gave him a window office.”

Needless to say, window offices are more valuable than gold around here; for the most part they’re only awarded to the best and the brightest. (And, for some reason, to the Scripting Editor, who also has a window office.) As you might expect, the Scripting Guy who writes this column doesn’t have a window office. Of course, up until now, he wouldn’t expect to have a window office; after all, his name rarely comes up any time people talk about the best and the brightest. But apparently you don’t have to be among the best and the brightest, at least not as long as you’re willing to be violent and angry. Hmmm ….

Ah, who are we trying to kid? For one thing, the Scripting Guy who writes this column is too lazy to be violent. For another, how could he ever be angry, especially when he has the opportunity to do things like write a logon script that can list all the network printers for the logged-on user:

Const ForWriting = 2

Set objNetwork = CreateObject(“Wscript.Network”)

strName = objNetwork.UserName strDomain = objNetwork.UserDomain strUser = strDomain & “\” & strName

strText = strUser & vbCrLf

strComputer = “.”

Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set colPrinters = objWMIService.ExecQuery _ (“Select * From Win32_Printer Where Local = FALSE”)

For Each objPrinter in colPrinters strText = strText & objPrinter.Name & vbCrLf Next

Set objFSO = CreateObject(“Scripting.FileSystemObject”)

Set objFile = objFSO.CreateTextFile _ (“C:\Scripts\Printers.txt”, ForWriting, True)

objFile.Write strText

objFile.Close

Two quick caveats before we explain how the script works. First, in its current incarnation this script won’t work on Windows 2000 or any earlier versions of Windows; that’s because those flavors of Windows don’t include the Local property as part of the WMI class Win32_Printer. But don’t get violent and angry; before we call it a day we’ll show you a modified script that will work on Windows 2000.

Second, this script simply logs the information to a text file named C:\Scripts\Printers.txt; each time the script runs it overwrites the information in Printers.txt with the most recent collection of printer information. That’s fine, but it might not be the behavior you had in mind. If that’s the case then you’ll have to modify the code that writes to the text file. But, again, there’s no need to get violent and angry (violent or angry, maybe, but not violent and angry). After all, we have plenty of information about working with text files. (And that doesn’t even include the Microsoft Windows 2000 Scripting Guide, which also has information about working with text files.)

OK, now we’ll explain how the script works. To begin with, with define a constant named ForWriting and set the value to 2; we’ll use this constant when we write the printer information to the text file. Following that we create an instance of the Wscript.Network object, then execute these three lines of code:

strName = objNetwork.UserName
strDomain = objNetwork.UserDomain
strUser = strDomain & “\” & strName

What are we doing here? Well, all we’re doing is determining the name of the logged-on user (using the UserName property) and the domain of the logged-on user (UserDomain); that’s what the first two lines of code are for. In line three we simply concatenate the user name and domain, giving us a user name in the format DOMAIN\username. In other words:

FABRIKAM\kenmyer

We then take this information plus a carriage return-linefeed (using the VBScript constant vbCrLf) and stash it in a variable named strText:

strText = strUser & vbCrLf

After that we connect to the WMI service on the local computer (because this is a logon script we don’t care about connecting to the WMI service on a remote computer). We then use this line of code to retrieve a collection of all the network printers on the computer:

Set colPrinters = objWMIService.ExecQuery _
    (“Select * From Win32_Printer Where Local = FALSE”)

Here we’re simply selecting all the instances of the Win32_Printer class, or at least those instances where the Local property is False. As you can probably guess, that results in a collection of all the network printers; if the Local property was True we’d have a local printer rather than a network printer. That’s why the script won’t work on Windows 2000; the Win32_Printer class in Windows 2000 doesn’t support the Local property.

But don’t worry: we said we’d show you an alternate script that will work on Windows 2000 and, by golly, we’re going to do just that.

But not yet. Before we do that, let’s finish explaining how the original script works. After we retrieve the printer information we set up a For Each loop that lets us walk through the entire collection; for each printer in the collection we use this line of code to add the Name of the printer to the variable strText:

strText = strText & objPrinter.Name & vbCrLf

This should be pretty easy to follow: all we’re doing is assigning a new value to strText. And just what is that new value? That’s easy: it’s the existing value of strText plus the name of the printer plus a carriage return-linefeed.

The rest is easy. First we create an instance of the Scripting.FileSystemObject object; we then use the CreateTextFile method to create a new text file named C:\Scripts\Printers.txt:

Set objFile = objFSO.CreateTextFile _
    (“C:\Scripts\Printers.txt”, ForWriting, True)

Note the three parameters we pass to the CreateTextFile method:

The full path to the new file (C:\Scripts\Printers.txt).

The constant ForWriting, which indicates that we want to write to the file.

The value True, which tells the script to overwrite an existing instance of C:\Scripts\Printers.txt. If the file Printers.txt exists then the script will overwrite it; if the file doesn’t exist then the script will create it.

After that we call the Write method to write the printer information to the file, then use the Close method to close the file. If we open the text file we should see information similar to this:

FABRIKAM\kenmyer
\\atl-ps-01\b43-2927-a
\\atl-ps-01.fabrikam.com\b43-2315-a
\\atl-ps-02\HP LaserJet 5MP

Which is exactly what we wanted to see.

Now, what about Windows 2000? Well, without explaining how this works, here’s a logon script that will run on Windows 2000 and Windows NT:

Const ForWriting = 2

strComputer = “.”

Set objNetwork = CreateObject(“Wscript.Network”)

strName = objNetwork.UserName strDomain = objNetwork.UserDomain strUser = strDomain & “\” & strName

Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

strText = strUser & vbCrLf

Set colPrinters = objWMIService.ExecQuery(“Select * From Win32_Printer”)

For Each objPrinter in colPrinters If Not objPrinter.Attributes And 64 Then strText = strText & objPrinter.Name & vbCrLf End If Next

Set objFSO = CreateObject(“Scripting.FileSystemObject”)

Set objFile = objFSO.CreateTextFile _ (“C:\Scripts\Printers.txt”, ForWriting, True)

objFile.Write strText

objFile.Close

The big difference here? This time we need to return all the printers, both local and network. We then check the value of the bitmask property Attributes. If the “switch” equal to 64 is on then this is a local printer; if it’s not, then this must be a network printer. In that case, we then add the Name of the printer to the variable strText.

Incidentally, we need to issue a correction before we go. Earlier we stated that window offices were distributed to “the best and the brightest.” As it turns out, window offices are distributed on the basis of seniority. In other words, the Scripting Editor didn’t get a window office because she’s really, really smart; instead, she got one because she’s really, really old.

Just don’t tell her we said that.

Editor’s Note: The fact that the Scripting Guy who writes this column is much older than the Scripting Editor sort of blows away that last theory. Unless we’re talking about mental age, in which case the Scripting Editor has at least managed to reach adulthood, unlike the Scripting Guy who writes this column.

0 comments

Discussion is closed.

Feedback usabilla icon