I’ve encountered some applications that, during installation, change the default printer for the users on the machine, regardless if it’s installed from an admin account or system account.
To prevent this, you might want to look into the MSI custom actions, but if you don’t have that option, then these scripts can be a workaround.
First, we must create a backup script:
Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv") Const HKEY_USERS = &H80000003 Const HKEY_LOCAL_MACHINE = &H80000002 Set WNetwork = CreateObject("WScript.Network") strComputer = "." Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") KEYPATH="Software\Microsoft\Windows NT\CurrentVersion\Windows" VALUENAME="Device" strUserName = WNetwork.username If UCase(strUserName) = getUserNameFromSID("S-1-5-18") Then string1 = "S-1-5-21" string2 = "Classes" objReg.EnumKey HKEY_USERS, "", arrsubkeys For Each Subkey In arrSubKeys If InStr(1,Subkey,string1,1)And (InStr(1,Subkey,string2,1) = "0") Then ID = Subkey strKeyPathSUB = ID & "\" & KEYPATH objReg.GetStringValue HKEY_USERS,strKeyPathSUB,VALUENAME,strValue if Not IsNull(strValue) then strKeyPath = "SOFTWARE\DefaultPrinterBackup" If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys) <> 0 Then objReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath End If strKeyPath1 = "SOFTWARE\DefaultPrinterBackup\" & ID If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath1, arrSubKeys) <> 0 Then objReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath1 End If strValueNameUsers = "Device" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath1,strValueNameUsers,strValue end if End If Next End If Function getUserNameFromSID(SID) server = "." Set objWMIService = GetObject("winmgmts:\\" & server & "\root\cimv2") Set objAccount = objWMIService.Get("Win32_SID.SID='" & SID & "'") strUser = objAccount.AccountName If Err.Number <> 0 Then getUserNameFromSID = Err.Description Err.Clear Else getUserNameFromSID = UCase(strUser) End If End Function
This script first checks if it’s executed from a system account, if this is run from an admin account then it fails.
The registry where the default printer is saved for a user can be found in “HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows”, and the registry is “Device”
For example on my machine i have Device=Microsoft Print to PDF,winspool,Ne01:
We then search in all subkeys from “HKEY_USERS” except the ones that start with “Classes”, those are not users.
If we find the registry in the users hive, we then create a general key in “HKEY_LOCAL_MACHINE\Software\DefaultPrinterBackup”. We get each user key ID, for example “S-1-5-21-661462176-3111377266-2001793429-1001” and place the “Device” registry in it.
So now that we have the backup script done, we should create a restore one for all the users. This will look like this:
Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv") Const HKEY_USERS = &H80000003 Const HKEY_LOCAL_MACHINE = &H80000002 Set WNetwork = CreateObject("WScript.Network") strComputer = "." Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") KEYPATH="Software\Microsoft\Windows NT\CurrentVersion\Windows" VALUENAME="Device" strUserName = WNetwork.username strKeyPath = "SOFTWARE\DefaultPrinterBackup" If strUserName = "SYSTEM" Then string1 = "S-1-5-21" string2 = "Classes" objReg.EnumKey HKEY_USERS, "", arrsubkeys For Each Subkey In arrSubKeys If InStr(1,Subkey,string1,1)And (InStr(1,Subkey,string2,1) = "0") Then ID = Subkey strKeyPathSUB = ID & "\" & KEYPATH objReg.GetStringValue HKEY_USERS,strKeyPathSUB,VALUENAME,strValue strKeyPath1 = "SOFTWARE\DefaultPrinterBackup\" & ID If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath1, arrSubKeys) = 0 Then objReg.GetStringValue HKEY_LOCAL_MACHINE,"SOFTWARE\DefaultPrinterBackup\" & ID,VALUENAME,strValuem strv=strvaluem objReg.DeleteValue HKEY_USERS,strKeyPathSUB,VALUENAME objReg.SetStringValue HKEY_USERS,strKeyPathSUB,VALUENAME,strv else If objReg.EnumKey(HKEY_USERS, strKeyPathSUB, arrSubKeys) <> 0 Then If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath1, arrSubKeys) = 0 Then objReg.GetStringValue HKEY_LOCAL_MACHINE,"SOFTWARE\DefaultPrinterBackup\" & ID,VALUENAME,strValuem strv=strvaluem objReg.SetStringValue HKEY_USERS,strKeyPathSUB,VALUENAME,strv end if end if End If If objReg.EnumKey(HKEY_USERS, strKeyPathSUB, arrSubKeys) = 0 Then If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath1, arrSubKeys) <> 0 Then objReg.DeleteValue HKEY_USERS,strKeyPathSUB,VALUENAME end if end if End If Next End If If objReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys) = 0 Then objReg.DeleteKey HKEY_LOCAL_MACHINE,strKeyPath end if
We are now doing the exact opposing. We are searching in the previously created key in “HKEY_LOCAL_MACHINE\Software\DefaultPrinterBackup\” and for each subkey, we copy it in the according user registry.
If you want to use these scripts in your MSI, place the backup script right after the “InstallInitialize” sequence, and the restore script before the “InstallFinalize” sequence.