This is by no means a script 🙂 never the less the logic is so simple that it could be a life saver for certain projects with very specific printing naming requirements. My colleague currently POCing XenDesktop VDI to a customer received a requirement related to one printer which is USB redirected and had to have a specific name in virtual desktops for in-house application to successfully print.
Now for those of you familiar with Citrix XD, USB printers by default are redirected with a name PRINTER NAME (from clientname) with clientname being the device hostname you are connecting from. If you decide to enable legacy printer naming using Citrix policies, you would get a redirected printer name Client\clientname\PRINTER . All customer wants is for the redirected printer to show the same name as local printer.
Being asked for support on the spot, I decided to go the easiest but longest way. I changed the registry name of the printer [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\PRINTER (from clientname)] , exported the registry, created a batch file to import the registry and restart printer spooler/ Citrix Print Management , logon script.
Well obviously it wasn’t`t well thought through, although it did work, I soon realized that the registry path for the redirected USB printer had the clientname in path so if I run the script on another device with a different client name surely it would not apply . Second thing was that with a logon script, the printer might not have been created yet during logon (can be changed in CTX policies but increases login time) so it would surely fail to import the changed registry printer name setting.
Moving on it seemed only sensible to turn to PowerShell 🙂 . I can use the Set-ItemProperty to change only the printer name instead of importing the whole printer registry settings but again I have a variable which is the clientname ( connecting device hostname) that would change for every connection.
Now with VDI you have a variable called %ClientName% variable that would return the hostname of the connecting endpoint and as I was just going to move on that way , I decided why not simplify things and go back to basics. I have a printer which has the same name on all endpoints, if I manually rename the printer in VDI session that would be the end of the story so why not let PowerShell simply rename the printer. Good but what about the clientname variable 🙂 , Well remember default USB redirected printer name is PRINTER NAME (from clientname) thus all I have to do is use the power of PowerShell to search for the printer name only with anything that follows and change to required name ! Lets do that just that.
Remember I have several client devices with different names and I have the same printer name on all devices.
clientname (connecting device name) : DIYAR-PC
Printer Name on clientname (connecting device name) : DIYAR-PRINTER
1- Create the following .ps1 PowerShell script and save on an accessible file share location:
The most important part of this is the asterix * beside the printer name because that is actually what is getting the clientname which is added by default on the USB redirected printer.
2- Apply group policy to your virtual desktops OU (Make sure Loop-Back processing is enabled), go to Machine Configuration, Preferences, Control Panel Settings, Scheduled Tasks ( AT LEAST WINDOWS 7 ), right click and New Scheduled Task.
New Task Settings:
Conditions default and Settings
That’s it, whenever users login, the script will wait one minute ( until all printers have been created successfully ) after which it will rename the printer that starts with PRINTER-NAME even when its followed by (redirected from client) to the desired printer name which is in our case the original name PRINTER-NAME .
Note that if you have different printer names on each endpoint, you can play around with PowerShell to get check what objects can be tackled to define the criteria on which the printer name is changed . For example we can set all redirected printers to use Citrix Universal Printer Driver and then amend the script to use the | where-object -Name DriverName -eq *Citrix* and so on you can get as granular as you would like, just do your research well.
Would love to hear your comments.