This is an update to the original Using Named Printers with Terminal Server post from August 2008.
The original post takes you through the process of using Template Users on Terminal Server so that you only need to setup one user per physical location with user mode printers and then users from that physical location can inherit the Named Printers settings from the Template User. It also mentions the unsupported method of sharing a single Machine ID between servers in a Terminal Server farm ONLY if you are sure that the machines are exactly the same.
I am currently working on a support case which raises new issues which need to be discussed as well as bringing back some previous points to which need to be clarified.
The customer has 6 physical locations or sites. At head office, they have a Terminal Server (with Citrix) farm containing 2 load balanced servers. They are using a third party application which stores some settings in the Dex.ini that need to be different based on the site where the current user is located.
To facilitate the Dex.ini settings for the third party application, the customer is using individual Dex.ini files for each user stored in the Home directory.
So far so good. The configuration makes sense and works fine... until you introduce Named Printers.
Note: The customer is running Microsoft Dynamics GP 2010 so they don't have the user level Dex.ini functionality that was introduced in Microsoft Dynamics GP 2013. This GP 2013 feature might help with the settings needed by the third party application.
The Boring Stuff
Named Printers bases all of its data and settings off one primary value... the Machine ID. The Machine ID is stored as the ST_MachineID setting in the Dex.ini file, it defaults to the Network name of the machine and is tied to the Server itself.
The Machine ID is required because the Dexterity functionality which allows us to capture and use Printer settings stores its data as a binary dump from the printer driver. This is then stored in SQL as a Binary Large Object (BLOB). This BLOB contains the Printer Name and all the selected settings such as printer tray and orientation. Dexterity does not understand or care about the actual content of the BLOB. When Dexterity wants to change default printer or print a report to a specified printer, it just passes the binary data back to the operating system which then handles the printer changes as required.
The problem is that the binary data is stored by the operating system differently for every printer and printer driver. Even updated versions of the same printer driver for the same printer could store that data differently. The length of the name and/or the address of the printer could shift the settings within the binary data.
If you try to use stored binary data from Named Printers with a different version of the driver for that printer, or if the printer has a different name or address, it will probably fail to work. In some cases we have seen Named Printers cause the application itself to crash as described in KB 909739.
This means that if you ever update or change printer drivers, you should recreate the Named Printer's Printer IDs based on those drivers so that they stay binary compatible with the drivers.
It also means that settings created on one machine or server are unlikely to be binary compatible with another machine or server. In other words, the Machine ID should not be shared between servers as it is very unlikely to work and could cause crashing (and did I mentioned it is not supported). I have seen it work but that was with two virtual servers based off the same image so that were as close to identical as you could get.
So coming back to our support case. The users each had their own Dex.ini file, which contained a Machine ID setting for that user. This meant that each user had to be set up individually within Named Printers. This could be simplified by all users from a specific location sharing the same Machine ID, thus reducing the amount of Named Printers configuration needed. All this works fine until more than one server is added to the farm.
Now the same user level Dex.ini file would get used regardless of which of the servers in the farm the user connected to. So the same Machine ID would be shared between all servers in the farm and, as we now know, that is a problem. For our customer it meant that Named Printers settings created for one server, failed to work on the other server.
In summary, User level Dex.ini files stored in the home folders are not compatible with Named Printers once there is more than one server involved.
Note: Microsoft Dynamics GP 2013 with its user level Dex.ini files, it still has a system level Dex.ini file which would be where the Machine ID is stored, so that works fine.
The path towards the solution starts with no longer using separate User level Dex.ini files and using a single Dex.ini file on each server. This ensures that each server has its own unique Machine ID and allows Named Printers to work. It is now possible to create 6 Template Users on each machine (so 12 configurations) to have Named Printers working per site.
Note: It does introduce a side effect that users see the User ID of the previous user when they attempt to login. This can be easily resolved using the Dex.ini Configuration window in the Support Debugging Tool to clear the SQLLastUser setting (see Why making the Dex.ini file read only is evil).
But if you remember, our customer has a third party application which needs its Dex.ini settings per site and this is not handled with the above configuration with just 2 Dex.ini files.
To handle this situation we need to have 6 Dex.ini files on each server, one for each of the 6 sites. All 6 on each server use the same Machine ID, so Named Printers still only has 2 Machine IDs, but we can now have settings for the third party application per site. To easily use this configuration this we can create a Published Application for each site and pass the path of that site's Dex.ini file as an additional parameter in the shortcut. Then only provide users access to the Published Application for their location.
While discussing this approach with the customer, we came up with a variant that would be easier to implement from the Named Printers point of view. As we now had 12 Dex.ini files (6 sites by 2 servers) instead of having two Machine IDs and using 6 Template Users and User Mode printers, we could create 12 Machine IDs based on Site and Server (eg. Location1A, Location1B, and so on). This would avoid the need for Template Users and User Mode printers. Each site could have its printers defined as System Mode printers on each server.
So now, each site has its own settings for the third party application, each site has its own Named Printers settings and Named Printer settings are not shared between multiple servers.
The problem is solved.
Hope you find this information useful.
23-Jul-2013: For more information check out: The Ultimate Guide to Terminal Server Printing - Design and Configuration.