Hey, Scripting Guy! I am trying to determine how to use WMI to add a printer connection by using Windows PowerShell. I have found this script, but it uses VBScript and not WMI. This means that it is not very close at all, I am afraid. Do you have a WMI script I can use?
– CM
Hi CM,
Ed looked around, but he did not find anything. Therefore, he dug out his script editor, dusted off his keyboard, and got to work. He did not write a single script last week while at Tech·Ed. The Sapien dudes (one of our sponsors for the Summer Scripting Games) even gave him a flying script monkey. (Incidentally, if it were not for the quick reflexes of Scripting Guy Editor Craig, Ed’s script monkey would have been history. Someone nabbed it from our booth, but Craig politely retrieved it from the nabber.) Ed claims he was too busy talking to people at the Scripting Guys booth and being driven crazy by the TechNet Plus slot machine to do any writing last week. It’s true. We swear.
This week we will examine printing. There are lots of resources related to printing on the TechNet Script Center. There is a collection of Hey, Scripting Guy! articles that lists 24 articles relates to both server-side and client-side printing. We have almost 50 scripts in the printer section of the Script Center Script Repository. There are also almost 50 scripts in the printer section of the Community-Submitted Scripts Center. We have some good technical information about printing in the Scripting Guide. All those resources are in VBScript. To use them in Windows PowerShell, you would have to translate the scripts into PowerShell. The Microsoft Press book, Windows PowerShell Scripting Guide, has a whole chapter devoted to printing. |
CM, here is Ed’s ListSharedPrintersAddPrintConnection.ps1 script. We hope that you will enjoy it, and use it in good health. If you want to know how it works, read on. Otherwise, we will see you tomorrow.
ListSharedPrintersAddPrintConnection.ps1
Param($computer, $printerPath, [switch]$list)Function Add-PrinterConnection([string]$printerPath){ Write-Host -foregroundcolor cyan "Adding printer $printerpath" $printClass = [wmiclass]"win32_printer" $printClass.AddPrinterConnection($printerPath)} #end Add-PrinterConnectionFunction Get-Printer($computer){ Get-WmiObject -class Win32_Printer -computer $computer} #end Get-PrinterFunction Format-Printer($printObject){ Write-Host -foregroundcolor cyan "Shared printers on $computer" $printObject | Where-Object { $_.sharename } | Format-Table -property sharename, location, comment -autosize -wrap} #end Format-PrinterFunction Get-SuccessCode($code){ if($code.ReturnValue -eq 0) { Write-Host -foregroundcolor green "Add Printer connection suceeded!" } Else { Write-Host -foregroundcolor red "Add Printer connection failed with $($code.returnvalue)" }} #end get-successcode# *** Entry Point to Script ***if($list) { Format-Printer(Get-Printer($computer)) ; exit }if($printerPath) { Get-SuccessCode -code (Add-PrinterConnection($printerPath)) ; exit }
The ListSharedPrintersAddPrintConnection.ps1 script will add to your computer a printer connection to a shared printer. Printer connections are seen under Printers in Control Panel:
The first thing that you have to do in the ListSharedPrintersAddPrintConnection.ps1 script is use the param statement to create three command-line parameters. The first parameter is the computer parameter. This is used to hold the name of the computer that will be queried for the list of shared printers. The second parameter is the printerpath parameter that is used to specify the name of the printer that will be added. The last parameter is a switched parameter list, which is used to provide a list of all the shared printers from the destination computer. The param statement is seen here:
Param($computer, $printerPath, [switch]$list)
The syntax to call the script and cause it to list shared printers is seen here:
PS C:\ .\ListSharedPrintersAddPrintConnection.ps1 –computer Berlin -list
When the script is run with the list switched parameter, this output is seen:
The first function to be created is the Add-PrinterConnection function. The Add-PrinterConnection function accepts a single parameter—the UNC path of the shared printer to be added. When the Add-PrinterConnection function is called, the first thing that happens is the Write-Host cmdlet is used to display a message in cyan that states the printer is being added. This is seen here:
Function Add-PrinterConnection([string]$printerPath){ Write-Host -foregroundcolor cyan "Adding printer $printerpath"
The AddPrinterConnection method from the Win32_Printer WMI class is a static method. This means that it must be called from the management class itself, and not from an instance of the class. To do this, you use the [wmiclass] type accelerator to return the Win32_Printer class. When you pipe the management object to the Get-Member cmdlet, you are presented with a listing of methods and properties similar to the one in Table 1.
Table 1 Members of the Win32_Printer management class | |
Name | MemberType |
Name |
AliasProperty |
AddPrinterConnection |
Method |
__CLASS |
Property |
__DERIVATION |
Property |
__DYNASTY |
Property |
__GENUS |
Property |
__NAMESPACE |
Property |
__PATH |
Property |
__PROPERTY_COUNT |
Property |
__RELPATH |
Property |
__SERVER |
Property |
__SUPERCLASS |
Property |
ConvertFromDateTime |
ScriptMethod |
ConvertToDateTime |
ScriptMethod |
CreateInstance |
ScriptMethod |
Delete |
ScriptMethod |
GetRelatedClasses |
ScriptMethod |
GetRelationshipClasses |
ScriptMethod |
GetType |
ScriptMethod |
Put |
ScriptMethod |
The Win32_Printer management class is stored in the $printClass variable, and the AddPrinterConnection method is called from that object. The AddPrinterConnection takes a string with the path of the shared printer. This is seen here:
$printClass = [wmiclass]"win32_printer" $printClass.AddPrinterConnection($printerPath)} #end Add-PrinterConnection
The next function that is created is the Get-Printer function. This function takes a single parameter—the name of the computer. The Get-WmiObject WMI class is used to return a Win32_Printer management object. This is seen here:
Function Get-Printer($computer){ Get-WmiObject -class Win32_Printer -computer $computer} #end Get-Printer
Next the Format-Printer function is created. This function accepts the Win32_Printer management object that was created in the Get-Printer function. It is used to format the output that is displayed in the Windows PowerShell console. The first thing the Format-Printer function does is use the Write-Host cmdlet to display a message in cyan that states the shared printers on the computer name that is stored in the $computer variable. The management object that is stored in the $printObject variable is pipelined to the Where-Object cmdlet. The Where-Object cmdlet examines the properties of each printer object in the $printObject variable to determine whether a value for the sharename property is present. If it is, the instance of the printer object is sent along the pipeline to the Format-Table cmdlet. If there is no sharename property that is defined for the printer, it means that the printer is not shared, and the instance of the object will therefore be dropped. As soon as at the Format-Table cmdlet, the sharename, location, and comment properties are displayed. The autosize and wrap switches are used to tighten up the display. The Format-Printer function is seen here:
Function Format-Printer($printObject){ Write-Host -foregroundcolor cyan "Shared printers on $computer" $printObject | Where-Object { $_.sharename } | Format-Table -property sharename, location, comment -autosize -wrap} #end Format-Printer
Next the return code from calling the AddPrinterConnection method must be evaluated. To do this, you use the Get-SuccessCode function. The return value is passed to the Get-SuccessCode function through the code parameter. If the ReturnValue property is equal to 0, no errors occurred, and a message is displayed in green that “Add Printer connection succeeded!” If the return value is anything else, the method call was not successful, and a message in red is displayed that states the add printer connection failed along with the error code that was generated. The Get-SuccessCode function is seen here:
Function Get-SuccessCode($code){ if($code.ReturnValue -eq 0) { Write-Host -foregroundcolor green "Add Printer connection suceeded!" } Else { Write-Host -foregroundcolor red "Add Printer connection failed with $($code.returnvalue)" } #end get-successcode
When the script successfully adds a new printer connection, the confirmation message from the Add-PrinterConnection function is displayed, in addition to the success message from the Get-SucccessCode function:
It is time to examine the entry point to the script. If the script was started with the list switched parameter, the Get-Printer function is called. The Get-Printer function receives the name of the computer to search for printer objects. The resulting Win32_Printer management object is passed to the Format-Printer function where the display will be cleaned up, formatted, and displayed on the Windows PowerShell console. The script then exits. This is seen here:
if($list) { Format-Printer(Get-Printer($computer)) ; exit }
If the printerPath parameter is passed to the script when it runs, the Add-PrinterConnection function is called. When the Add-PrinterConnection function is called, it is passed the string that is contained in the $printerPath variable. The return value from calling the Add-PrinterConnection function is passed to the Get-SuccessCode function, which is used to determine whether the printer connection was added successfully. The script then exits. This is seen here:
if($printerPath) { Get-SuccessCode -code (Add-PrinterConnection($printerPath)) ; exit }
When the script is called by using the printerPath parameter, the script adds the printer connection and evaluates the status code. The command line to cause all this is seen here:
PS C:\ .\ListSharedPrintersAddPrintConnection.ps1 –printerPath \\berlin\testprinter
As soon as the script has successfully added the new printer connection, the new printer appears under Printers in Control Panel:
Well, CM, that is about all we have time for today. We hope that you enjoyed this look at using WMI to add a new printer connection. Join us tomorrow as Printing Week continues. If you have not already done this, mark your calendars because the 2009 Scripting Games start June 15, 2009. However, the first scripting game event will be revealed on Monday June 8, 2009—one week before the start of the Scripting Games. This year’s theme is the decathlon. It will be a blast! Follow us on Twitter for all the latest information about the Scripting Games as well as everything related to the Script Center.
Ed Wilson and Craig Liebendorfer, Scripting Guys
0 comments