Hey, Scripting Guy! Question

Hey, Scripting Guy! I do not know about you, but does it seem that printers are a major pain in the dark side? I mean, they seem to multiply faster than bacteria. They are all just different enough to cause maintenance problems, and forget about trying to keep track of toner cartridges. Do you have any ideas that could help?

- HR

SpacerHey, Scripting Guy! Answer

Hi HR,

Don’t give in to the dark side. Use the force of scripting. Granted I am not as wise as Yoda, but I do have more hair. So with free support, I guess you kind of take what you can get. I promise not to give you a script that is too hairy. There are lots of VBScripts on the Script Center that work with printers. Here is one that enumerates printer connections and this section of the Script Repository works with printer ports. And this article talks about printer drivers.

Here’s the script:

$computers = "localhost"
$classes = "Win32_Printer", "Win32_TcpIpPrinterPort", "Win32_Share"
$file = "C:\fso\printers.txt"
Foreach($computer in $computers)
{
 Foreach($class in $classes)
 { 
  if($class -eq "win32_share")
     { 
       Get-WmiObject -class $class -filter "type = 1" >> $file
     }
     ELSE
      {
       Get-WmiObject -class $class >> $file
      }
 } #end foreach class
} #end foreach computer
notepad $file

The script begins by declaring a couple of variables and assigning values to them. The first variable is the $computers variable, which controls where the information will be obtained. It is plural, so this would be a good indication that you could assign more than one computer name here. In addition, you could even feed it a text file of computer names. The code to do that would look like this:

$computers = Get-Content –path c:\fso\mycomputers.txt

The script is already set up to allow for iterating through a collection of computer names. The good thing about Windows PowerShell is that you can use the foreach statement to walk through a single item. In VBScript, you had to test if something was an array or not, and then choose the appropriate methodology for your script. This is covered, from a VBScript perspective, in the Microsoft Press book, Microsoft VBScript Step By Step. This is discussed from the Windows PowerShell perspective in the Microsoft Press book, Microsoft Windows PowerShell Step By Step. We use an array of WMI class names to govern the way the script will run. You could add additional WMI classes here if you wish. For more information about some of the WMI classes that you could use, take a look at this section of the Script Center. The $file variable is used to point to a text file to which you will add data. Here are the first couple of lines of the :

$computers = "localhost"
$classes = "Win32_Printer", "Win32_TcpIpPrinterPort", "Win32_Share"
$file = "C:\fso\printers.txt"

We then use a pair of Foreach statements. The reason for this pair of statements is to first walk through the collection of computer names, and then walk through the collection of WMI class names. We walk through the computer names first, because we want to query each WMI class on each specific computer. The Foreach statement uses a pair of parentheses, and inside the parentheses the first variable is used to walk through the collection. The second variable is the collection that we will walk through. The curly brackets begin the code block that will be repeated for each item in the collection. Here is the code for the beginning of the two Foreach statements:

Foreach($computer in $computers)
{
 Foreach($class in $classes)
 {

If the WMI class is win32_share, we will perform a separate WMI query. We will add a filter to choose only the share type of 1. This is because a share type of 1 is a printer share. We are not interested in file shares, admin shares, or any of the other kinds of shares. To do this, we use the if statement. The decision point is placed inside the parentheses. The code block goes inside the curly brackets. To do the WMI query, we use the Get-WmiObject cmdlet where we give it the WMI class name and the filter we are interested in using. The filter parameter is optional for the Get-WmiObject cmdlet, and it takes the place of a where clause when using the WMI Query language (WQL). We use the double redirection arrows to create or to append to the text file $file. This is seen hhere:

if($class -eq "win32_share")
     { 
       Get-WmiObject -class $class -filter "type = 1" >> $file
     }

If  the WMI class name is not win32_share, we do a straightforward WMI query, without any special filter. We use the double redirection arrows to append to the text file indicated in the $file variable. This is seen here:

ELSE
      {
       Get-WmiObject -class $class >> $file
      }

We then close each of the Foreach loops, and open the file in Notepad as seen here:

} #end foreach class
} #end foreach computer
notepad $file

The resulting text file is seen here:

Image of the resulting text file

 

So, HR, that is how you document printers. See you tomorrow for Quick-Hits Friday.

Ed Wilson and Craig Liebendorfer, Scripting Guys