$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
25 Jan // php the_time('Y') ?>
I wrote a PowerShell script to install all printer drivers on a Citrix or Terminal Server.
Actually the script isn’t specific to Citrix or Terminal Server but on such environments we need to preload all drivers because users do not have the permissions to do that.
I have chosen for PowerShell because you can do it in a one-liner which makes it easy to run this script from my Altiris server on all Citrix Servers.
The idea is that we enumerate all the shared printers on a Printer Server and make a connection to each printer. This will make sure that the driver is installed if it wasn’t already present.
The script could even be scheduled to enforce that newly added printer drivers are added to each Citrix Server.
To enumerate all printers we can use the Win32_Printer WMI class like this:
1 | Get-WmiObject win32_printer -ComputerName "MYSERVER" |
It’s possible that some printers are not shared so we are going to filter that out using the -filter parameter:
1 | Get-WmiObject win32_printer -ComputerName "MYSERVER" |
Our next step is to make a printer connection and MSDN shows that the win32_printer class has an AddPrinterConnection method.
So I first tried:
1 2 3 4 5 6 | $Wmi.AddPrinterConnection("\\MYSERVER\PRINTER") Method invocation failed because [System.Object[]] doesn't contain a method named 'AddPrinterConnection'. At line:1 char:26 + $Wmi.AddPrinterConnection <<<< ("\\SERVER\PRINTER") + CategoryInfo : InvalidOperation: (AddPrinterConnection:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound |
I am not sure of the exact reason but obviously there is no access to the AddPrinterConnection method.
This works though:
1 2 | $Wmi = ([wmiclass]"Win32_Printer") $Wmi.AddPrinterConnection("\\MYSERVER\PRINTER") |
Now we can use the For-Each Object to make a connection to each printer using the __SERVER property for the servername and the ShareName property for the Printername:
Once again I met a PowerShell oddity: I couldn’t use AddPrinterConnection(“\\$_.__SERVER\$_.ShareName”) so I used:
1 | $Wmi.AddPrinterConnection( [string]::Concat("\\", $_.__SERVER, "\", $_.ShareName) ) |
And finally we put the whole thing in a one liner, replacing double quote (“) with (‘) and using the gwmi alias to make the line shorter:
1 | powershell.exe "& { $Wmi = ([wmiclass]'Win32_Printer') ; $Wmi.Scope.Options.EnablePrivileges = $true; gwmi win32_printer -ComputerName 'ADNRD02' -Filter 'shared=true' | foreach {$Wmi.AddPrinterConnection( [string]::Concat('\\', $_.__SERVER, '\', $_.ShareName) )} }" |
EDIT: In order to load new driver we need to enable the SeLoadDriverPrivilege. I have corrected the code above, see Enabling Privileges for WMI in PowerShell for an explanation.
5 Responses for "Script to install all print drivers on Citrix or Terminal Server"
[…] Dit blogartikel was vermeld op Twitter door Remko Weijnen, James K Hong. James K Hong heeft gezegd: RT @remkoweijnen: Blogged: Script to install all printer drivers on #Citrix or Terminal Server http://bit.ly/fZddqt […]
[…] Read the script here: https://www.remkoweijnen.nl/blog/2011/01/25/script-to-install-all-print-drivers-on-citrix-or-terminal… […]
[…] Script to install all print drivers on Citrix or Terminal Server | Remko Weijnen’s Blog (Remko… – I wrote a PowerShell script to install all printer drivers on a Citrix or Terminal Server. […]
Hi, not sure I understand what you have created but looks like I need it. Trying to migrate 1800 printers from 3 w2003 32bit servers to 3 W2008 print servers – and I don’t want to do it manually.
First how can I get your script – on your download page the AppPrinter2.zip seems corrupt but might be my side.
Second, is it possible to migrate but not assign any printer driver other than “Generic” – I will assign drivers at a later date – I do not want to import 32 bit drivers onto my 64bit servers and if there is no 64 bit driver then it can stay as Generic.
Any help much appreciated and thanks!!
Hi Remko,
Thank you so much for publishing this script. This may seem a little redundant but server 2000 doesn’t return a “shared” member.
For server 2000 I used “where {$_.sharename -ne $null}” to find shared printers.
Leave a reply