# blog.powershell.no

## Bulk-create printer objects on print servers using Windows PowerShell

When installing a new print-server with several hundreds or thousands of printer objects there arentt too much fun doing this manually.

Here are 3 steps to automate this process:

1) Install all the necessary printer drivers on the printserver

2) Create a csv-file with a listing of all printer objects and their properties

3) Bulk-import the printer objects using a script

For the 3rd step Ive created a basic Windows PowerShell script, available on PoshCode.org from this link.

The script contains one function for creating a TCP/IP printer port and one function for creating a printer object. These functions are used in a foreach-loop cycling through the csv-file containing all the printer objects. The script are pretty basic, and should be further expanded with error handling and further details for printer properties.

The script are created and tested on a Windows Server 2008 server against a remote Windows Server 2003 server.
Running the script from Windows Server 2003 returns an access denied error, possibly due to the impersonation-model in Windows Server 2003. However, it should work from Windows Vista, Windows 7, Windows Server 2008 and Windows Server 2008 R2 against remote print-servers (2000/2003/2008/2008 R2).

Especially the ability to set NTFS permissions on the printer objects would be a useful addition in the script.

Please feel free to leave suggestions for improvements in the comments section below.

Update 09.11.2009:
Ive got some feedback regarding the ability to set NTFS permissions on the printer objects in the script.
A utility called SubInACL from Microsoft could be used for this.

Example usage:
subinacl.exe /printer “\\print-server\printer” /revoke=”Power Users”
subinacl.exe /printer “\\print-server\printer” /grant=”DOMAIN\Domain Users”

The tool can be downloaded from here.

November 7, 2009 -

## 33 Comments »

1. Hi,
I have this error on try to create print on windows 2008 R2:
Exception calling “Put” with “0” argument(s): “Generic failure ”
+ $print.Put <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException Any help? thanks Comment by Leao braz | November 23, 2009 | Reply 2. Hi! Youre sure the csv-file contains the necessary headers?Printserver,Driver,Portname,Sharename,Location,Comment,Printername. The same thing happens if you manually try to run the CreatePrinter function? Comment by Jan Egil Ring | November 23, 2009 | Reply 3. Hi, The printer port creating work fine, but I have this error on the printer creator. My CSV= Printserver,Driver,Portname,IPAddress,Sharename,Location,Comment,Printername HL-SPRINTER02,Microsoft XPS Document Writer,10.0.19.1,10.0.19.1,HL-P001,teste,teste,HL-P001 I have tried configure the printers settings direct on the CreatePrinter funcition, but show me this error: PS C:\Users\administrator.HLUZ\Desktop> .\createprinter3.ps1 Unexpected token ‘.19’ in expression or statement. At C:\Users\administrator.HLUZ\Desktop\createprinter3.ps1:31 char:26 +$print.PortName = 10.0.19 <<<< .1
+ CategoryInfo : ParserError: (.19:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken

Thanks for your helping,
LB

Comment by Leao Braz | November 24, 2009 | Reply

4. Hi,
After many attempts, the problem is on Microsoft XPS Document Writer… Bad luck on test driver…

Thanks

Comment by Leao Braz | November 26, 2009 | Reply

5. Hi,

The script work fine but I’m on a Windows 2k8 cluster and when I launch the script it create the printer on the node and not the cluster instance.

Could you tell me what can I do ?

Thanks

Comment by Selenae | January 5, 2010 | Reply

6. WMI does not support the cluster virtual machine name, only node names.

Pick us the Windows Resource Kit and use prnadmin.dll and associated
scripts and support when scripting printers on the cluster.

If you have an existing print server, try the print migrator tool if you
wish to move printers from one or more machines to the cluster.

http://www.microsoft.com/WindowsServ…grator3.1.mspx

Comment by Jan Egil Ring | January 5, 2010 | Reply

7. Hi,

I have the same issue as Leao Braz on a 2008 Server R2 x64. the printer port creation work fine, but I have this error on the printer creator:
Exception calling “Put” with “0″ argument(s): “Generic failure ”
At C:\temp\createprinter.ps1:53 char:12
+ $print.Put <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException Then i have tried with several drivers and the issue is always the same. I have tried on windows 2003 and it works like a charm… Any idea ? Help would be appreciated Thanks Comment by stelephan | March 30, 2010 | Reply 8. Can you confirm if this script works with Windows Server 2008? I’m also getting the same error as stelephan. thanks Comment by Luke | August 25, 2010 | Reply 9. hi – i am having the same issue when trying to create a printer. the below works just fine on XPSP2$server = “.”
$print = ([WMICLASS]”\\$server\ROOT\cimv2:Win32_Printer”).createInstance()

$print.drivername = “HP Universal Printing PCL 6”$print.PortName = “10.1.20.31_PR1”
$print.Shared = “true”$print.Sharename = “ScriptedPrinter2”
$print.Location = “USA/Redmond/Building 37/Room 115”$print.Comment = “HP Universal Printing PCL 6”
$print.DeviceID = “ScriptedPrinter2″$print.Put()

when i run the same on Win2003 server it fails with the err ” Exception calling Put with 0 arguments: Access Denied” i am totally frustrated now, as i have been trying to research for over 4 days on this. i am using Powerscript 2.0 ver.

i have tried with various combinations of drivers and port addresses that are added and not used on the server.

Pls someone help !! what am i missing???

thanks a lot

Comment by Raj | September 9, 2010 | Reply

• Raj,
Did you ever get this to work? I am having the same problem trying o run the script locally on a Win2003 server.
Thank You
Keih

Comment by Keith | February 22, 2012 | Reply

10. Raj: Have you tried running the script against Windows Server 2003 from a remote server/client?

E.g.:
$server = “your-win2003-server”$print = ([WMICLASS]“\\$server\ROOT\cimv2:Win32_Printer”).createInstance( Comment by Jan Egil Ring | September 9, 2010 | Reply 11. I can’t seem to get this script to work. If I run in from a 2008 R2 box I get the following Cannot convert value “\\MYSERVERNAME\ROOT\cimv2:Win32_TCPIPPrinterPort” to type “System.Management.ManagementClass”. Error: “The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)” If I change the following from$print = ([WMICLASS]”\\server$\ROOT\cimv2:Win32_Printer”).createInstance() to$print = ([WMICLASS]”\\.\ROOT\cimv2:Win32_Printer”).createInstance()

it will give a different error. That error is:

Exception calling “Put” with “0” argument(s): “Invalid parameter ”
At C:\it\testImport.ps1:46 char:10
+ $port.Put <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException Any ideas? Comment by worldzfree | February 11, 2011 | Reply 12. I get this message when trying to run the Script from my Win7 Workstation to a 2008 R2 Server but it works fine when PrintServer is a 2003 Server. Exception calling “Put” with “0” argument(s): “Generic failure ” At C:\Bulk Printer Import.ps1:36 char:11 +$print.Put <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Furthermore there are EventID's 10009 in the System log. Something in Win2008R2 seems to be blocking DCOM Calls. I called MS but they have not been able to tell me how to resolve this.
Idea?

Comment by Carl Lee | February 11, 2011 | Reply

• Issue resolved IPAddress column was missing from Input file

Comment by Carl Lee | February 12, 2011 | Reply

• Glad you resolved it.
Ill see if Ill add some CSV-file validation to the function so errors like this are easier to discover.

Comment by Jan Egil Ring | February 12, 2011

13. $server =$args[0]
$print = ([WMICLASS]”\\$server\ROOT\cimv2:Win32_Printer”).createInstance()
$print.drivername =$args[1]
$print.PortName =$args[2]
$print.Shared =$true
$print.Sharename =$args[3]
$print.Location =$args[4]
$print.Comment =$args[5]
$print.DeviceID =$args[6]
$print.Put() Works for me. Comment by Mac | March 8, 2011 | Reply 14. The code from the original post works perfect. I am using it now to add 700 printers to a node in my cluster. I can’t add to the virtual instance, but thats easily worked around, export the printers from the node with printMgmt console and import to the Virtual Instance. Thanks. Comment by Mac | March 8, 2011 | Reply 15. Seem to have some trouble with it and getting several errors.. Can anyone help me out? Thanks Cannot convert value “\\\ROOT:Win32_TCPIPPrinterPort” to type “System.Management.ManagementClass”. Error: “Invalid parameter” At C:\Users\hex\Desktop\Create-Printers.ps1.ps1:41 char:20 +$port = ([WMICLASS] <<<< "\\$server\ROOT\cimv2:Win32_Printer").createInstance() + CategoryInfo: Not Specified: (:) [], RuntimeException + FullyQualifiedErrorId : RuntimeException Comment by Micahel | May 4, 2011 | Reply 16. Hi guys, The script works fine under Windows 2k8 R2. Just one issue, the csv file must have the following headers: Printserver,Driver,IPAddress,Portname,Sharename,Location,Comment,Printername A previous post mentioned the header, nut the IPAddress was missing. Comment by PGP | June 1, 2011 | Reply 17. Thank you! This script worked beautifully during a server migration from 2003 x86 to 2008 x64 with about 315 queues. I added another function that calls SetACL.exe (www.sf.net/projects/SetACL) to set perms on each queue since subinacl.exe was being a pain (couldn’t set “manage documents” and “print” permissions at the same time). Comment by Peter | July 31, 2011 | Reply 18. I have used this script in the past on a Windows 2008 R2 and it has worked…however all printers were configured with their IP address…We have a new site and i was trying to configure the print server before the printers were moved to the site when i run the script it creates one print queue/port and gets stuck….I am a power shell noob….i know the script is waiting for a response from the printer but it’s not there…can anyone offer any advice Comment by Larry | August 10, 2011 | Reply 19. Hi, script worked ok, but how to set “Print spooled documents first” too? When you created printer by wizard it’s set by default, but by script is unchecked. Comment by kosmito | September 22, 2011 | Reply 20. Hi guys I am, having troubles. Help please function CreatePrinter {$server = $args[0]$print = ([WMICLASS]”\\$server\ROOT\cimv2:Win32_Printer”).createInstance()$print.drivername = “Lexmark Universal PS3”
$print.PortName = “172.30.29.58”$print.Shared = $true$print.Sharename = “BNEBCP_HP4250_2”
$print.Location = BCP/Interactive$print.Comment = “Lexmark Universal PS3”
$print.DeviceID = “BNEBCP_HP4250_2”$print.Put()
}

Comment by Marc | September 26, 2011 | Reply

• You don’t say what you need help with.. But perhaps adding quotes around “BCP/Interactive” will do the trick. Also the function is still expecting the server name to be passed to it as an argument, even though you’ve “hard coded” the rest of the information.

Comment by Andreas | October 5, 2011 | Reply

21. works for me: server 2008 r2

function CreatePrinter {
$server =$args[0]
$print = ([WMICLASS]“\\.\ROOT\cimv2:Win32_Printer”).createInstance()$print.drivername = $args[1]$print.PortName = $args[2]$print.Shared = $true$print.Published = $true$print.Sharename = $args[3]$print.Location = $args[4]$print.Comment = $args[5]$print.DeviceID = $args[6]$print.Put()
}

function CreatePrinterPort {
$server =$args[0]
$port = ([WMICLASS]”\\.\ROOT\cimv2:Win32_TCPIPPrinterPort”).createInstance()$port.Name= $args[1]$port.SNMPEnabled=$false$port.Protocol=1
$port.HostAddress=$args[2]
$port.Put() }$printers = Import-Csv “printers.csv”

foreach ($printer in$printers) {
CreatePrinterPort $printer.Printserver$printer.Portname $printer.IPAddress CreatePrinter$printer.Printserver $printer.Driver$printer.Portname $printer.Sharename$printer.Location $printer.Comment$printer.Printername
}

csv tabs:

Comment by steve88 | October 2, 2011 | Reply

22. Works great at creating printers for me too on Server 2008 R2

However, I have an issue with migrating printers after creating them with this script. After using the script to create the printers I take a “PrintMig” (Printer Migration) of the print queues for importing to a different server (for DR purposes). We plan to use “Internet Printing” on the DR server, formally IPP in Server 2003. However after importing the PrintMig to the new server (both servers are same OS version and spec), the printers show up fine and print with no issues, but they do not show up in the list of “Internet Printers” on the new server, i.e. http://localhost/printers.

Any printers I create locally on the DR server show up in the Internet Printers list fine. Also, a printer that I created manually on the source server (where I ran the script) and was captured in the PrintMig, this also shows up fine in the Internet Printers list on the DR server.

This seems very strange. Does anyone know why this is?

Comment by Glenn | December 19, 2011 | Reply

• Another update on this:
I have just used this PowerShell script to create printers on my DR print server and the printer objects create fine and the test print works fine. However the printers do not show up in the Internet Pritners list. Does anyone have any idea why this is? Just to note again, printers created manually, i.e. in “Devices and Printers” show up fine in the Internet Printers list.
Many thanks,
Glenn.

Comment by Glenn | January 3, 2012 | Reply

• Forget this now, it was actually an error on my part 🙂 I did not have the printer set to “Share”, so this is why it had not showed up in the list of “Internet Printers”…!

Set your printers to share and all should be fine if you are using this scenario.

Comment by Glenn | January 5, 2012 | Reply

23. Extremly nice Script for PrintServermigration
Im Installing the Printers on 2008R2.
The Port will be created, but on the Printerpart i reseve this msg:

Exception calling “Put” with “0” argument(s): “Generic failure ”
At D:\PrintMig\Install_Printer.ps1:12 char:11
+ \$print.Put <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

CSV content: