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 arent`t 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 I`ve 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:
I`ve 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.





Hi,
I have this error on try to create print on windows 2008 R2:
Exception calling “Put” with “0″ argument(s): “Generic failure ”
At C:\Users\administrator.HLUZ\Desktop\createprinter.ps1:53 char:12
+ $print.Put <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any help?
thanks
Hi! You`re 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?
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
Hi,
After many attempts, the problem is on Microsoft XPS Document Writer… Bad luck on test driver…
Thanks
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
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.
http://www.microsoft.com/downloads/d…DisplayLang=en
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
Source: http://forums.techarena.in/server-cluster/75119.htm
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
Can you confirm if this script works with Windows Server 2008? I’m also getting the same error as stelephan.
thanks
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
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(
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?
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?
Issue resolved IPAddress column was missing from Input file
Glad you resolved it.
I`ll see if I`ll add some CSV-file validation to the function so errors like this are easier to discover.
$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.
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.
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
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.
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).
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
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.
Take a look at this document:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394363(v=vs.85).aspx
There’s a value for “Start jobs that are finished spooling first.”:
PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST
Now, I haven’t tested it myself yet, but it try:
$print.DoCompleteFirst = $true
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()
}
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.
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:
Printserver,Driver,Portname,IPAddress,Sharename,Location,Comment,Printername