How Can I Tell Which Users are Connected to a Print Queue?

How Can I Tell Which Users are Connected to a Print Queue?

  • Comments 1
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I tell which users are connected to a print queue?

-- RE

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RE. You know, if your printers are anything like the ones the Scripting Guys are used to working with then it’s easy to tell which users are connected to a print queue: all you have to do is walk into the printer room and see who’s in there frantically looking in every nook and cranny for the document that the printer insists it printed. At Microsoft the paperless office is very close to a reality. Not because we consciously set out to save paper, mind you, but because you typically have a better chance of hitting the jackpot in Las Vegas than you do of getting a document to actually print.

If you have printers that are a tad bit more reliable than that, however, you might find it easier to use a script to determine which users are currently printing to a particular printer. There’s a bit of a trick to doing this, and you have to use a slightly different approach to carry out this task on any version of Windows prior to Windows XP. But we’ll explain all that in a moment. For now, let’s take a look at a script that works on Windows XP and Windows Server 2003:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colPrintJobs =  objWMIService.ExecQuery _
    ("Select * From Win32_PrintJob Where Name Like '%FinancePrinter%'")

For Each objPrintJob in colPrintJobs 
    Wscript.Echo objPrintJob.Owner
Next

As you can see, there’s not much to the script. It begins by connecting to the WMI service on the local computer (although the script could just as easily run against a remote machine). Here’s where it gets a little tricky.

As it turns out, the WMI class Win32_PrintJob can return the logon name of all the users currently printing to all the printers connected to a computer. Interestingly enough, however, Win32_PrintJob does not have a class that pinpoints which print queue a user is connected to. At best, you can identify the printer using the Name property. Values for this property are composed of two items: the name of the printer and a print job ID. For example, the print jobs currently in the queue for the printer FinancePrinter might look like this:

FinancePrinter, 1
FinancePrinter, 2
FinancePrinter, 3

Is that a problem? Yes, it is; after all, it prevents us from using a query like this to return all the print jobs in the FinancePrinter print queue:

Set colPrintJobs =  objWMIService.ExecQuery _
    ("Select * From Win32_PrintJob Where Name = 'FinancePrinter'")

Why can’t we use this query? Well, because there won’t be any print jobs with the Name FinancePrinter; instead, all the print jobs will be named things like FinancePrinter, 1. How … delightful ….

But that’s all right; as usual, we can work around WMI’s idiosyncrasies. On Windows XP and Windows Server 2003 we can use the LIKE operator and a wildcard query, one that looks like this:

Set colPrintJobs =  objWMIService.ExecQuery _
    ("Select * From Win32_PrintJob Where Name Like '%FinancePrinter%'")

Note the construction of our Where clause: Where Name Like ‘%FinancePrinter%’. The percent signs are our wildcard characters: they signify any character or set of characters, much the same way the asterisk does when used with the dir command. The command dir *.* means, “Show me all the files and folders whose names start with any character or set of characters, have a period in it, then end with any character or set of characters.” Our WQL query can be read in similar fashion: “Bring back all the print jobs where the Name property starts with any character or set of characters, has the term FinancePrinter in it, then ends with any character or set of characters.” (And, yes, “any character or set of characters” also means no character at all.) In other words, bring back any print job where the Name includes the string FinancePrinter.

At that point all we have to do is set up a For Each loop and walk through the collection of print jobs, echoing back the value of the Owner property for each one. The Owner property is the logon name of the connected user; for example, kmyer or packerman. That’s the best you can do with Win32_PrintJob; if you need, say, the user’s first and last name, you’ll have to do something else. (One suggestion: take the logon name [also known as the sAMAccountName] and use it in an Active Directory search that can return the user’s first and last name. For more information, see the Tales from the Script column Dude, Where’s My Printer?)

Now that’s all well and good on Windows XP and Windows Server 2003; unfortunately, this script won’t do much for anyone running an earlier version of Windows. That’s because the LIKE operator isn’t available on earlier version of Windows. That doesn’t mean you’re out of luck, it just means we have to do things the old-fashioned way. For example, instead of writing a query that returns only the print jobs being printed to FinancePrinter we need to write a query that returns all the print jobs, regardless of printer:

Set colPrintJobs =  objWMIService.ExecQuery _
    ("Select * From Win32_PrintJob")

Once we have the entire collection of print jobs we can then use the InStr function to determine whether or not the Name property includes the string FinancePrinter:

If Instr(objPrintJob.Name, "FinancePrinter") Then

It’s a little more cumbersome, but it’ll work. Here’s a complete script that returns the list of users currently connected to a Windows 2000 print queue:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colPrintJobs =  objWMIService.ExecQuery _
    ("Select * From Win32_PrintJob")

For Each objPrintJob in colPrintJobs 
    If Instr(objPrintJob.Name, "FinancePrinter") Then
        Wscript.Echo objPrintJob.Owner
    End If
Next

Unfortunately, we don’t have a script that can tell you where printed documents actually go when the printer says they were printed yet the printed pages are nowhere to be found. But we’re working on it.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Need your help / suggestions / guidance for following query.

    Query: Need to monitor Print Job activity based on application that gives print

    Details:

    In typical situation we want to monitor which application (e.g. notepad.exe, winword.exe etc) gives print into printer named “Printer-XYZ”. Is it possible to implement? If yes, what is the best way to implement? Our application uses VB.Net framework 3.5 32Bit.

    Anticipating your best answer,

    Thank you,

    Dhaval (India)