PowerShell Script Switches Printer Configurations Between Sites

Attending the community conference PubForum E2E Conference has many benefits, the biggest is in my opinion getting to know many very talented and very nice people. One of them, Ton de Vreede, recently sent me a PowerShell script he had written which I am happy to publish here.

What Does it Do?

DefPrn.ps1 saves and loads the configurations of mapped network printers as well as the default printer. The clever thing is that it is designed to work with multiple configurations. That makes it easy to have different configurations per site/location.

Usage

Using DefPrn.ps1 is very straightforward: just tell it whether to save or to load and give an arbitrary name for the current location:

.\DefPrn.ps1 save <location name>
.\DefPrn.ps1 load <location name>

The location data is stored in this registry key: HKEY_CURRENT_USER\Software\DefPrn.

DefPrn.ps1

Here is the script in all its glory.

<# DefPrn.PS1
Author: Ton de Vreede
Revision: 0.2
Date: 30-3-2011
Description:
  Save/Load Default printer based on location. Also stores and retrieves custom settings (DevMode) for all connected netwrok printers. 
  If default printer has not been set yet for location user is informed and printer dialog is opened.
  If default printer saved for location cannot be set (most likely not available) user is informed and printer dialog opened.
  CAUTION: Many printer settings are stored in keys under the manufacturers name, for example HKCU\Software\Konica Minolta. Make sure 
           these keys are saved for the user as well.
Switches:
  Save LocationName --> Saves default printer in HKCU\Software\DefPrn\LocationName and save DevMode settings for each printer   
  Load LocationName --> Retrieves default printer from HKCU\Software\DefPrn\LocationName and retrieves any stored DevMode settings
#>
 
# SavePrinter retrieves and 'cleans' default printer entry in registry, then saves it as the value of the 'LocationName' entry in Software\DefPrn
function SavePrinter {
   $DefPrn = Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows" -Name Device | Format-table -HideTableHeaders -Property Device | Out-String
   New-Item -Path HKCU:\Software\DefPrn -ErrorAction SilentlyContinue
   Set-ItemProperty -Path "HKCU:\Software\DefPrn" -Name $args[0] -Value $DefPrn.Substring(2,($DefPrn.IndexOf(",")-2))
   }
 
# LoadPrinter retrieves the value of the 'LocationName' entry and sets it as Default printer
function LoadPrinter {
   $DefPrn = (Get-ItemProperty -ErrorAction SilentlyContinue "HKCU:\Software\DefPrn" $args[0]).($args[0])
   if ($DefPrn -ne $null) {
      trap {
         $MsgBox = New-Object -comobject WScript.Shell
         $MsgBox.Popup("The printer that is set as default could not be connected. Please choose another printer to use as Default.",0,"Default printer could not be set")
         C:\WINDOWS\system32\Control.exe printers
         }
      $Printer = New-Object -ComObject WScript.Network
      $Printer.SetDefaultPrinter($DefPrn)
 
   }
   Else {
      $MsgBox = New-Object -comobject WScript.Shell
      $MsgBox.Popup("You do not have a Default printer stored for this location. Please set a printer to use as Default.",0,"Default printer not set")
      C:\WINDOWS\system32\Control.exe printers
   }
}
 
# SaveSettings gets the DevMode value (if it exists) from each connected printer and stores it in Software\DefPrn as a value with the name of the printer connection
function SaveSettings {
   foreach ($PrinterName in (Get-ChildItem "HKCU:\Printers\Connections")){
   $DevMode = ((Get-ItemProperty $PrinterName.PSPath devmode -ErrorAction SilentlyContinue).devmode)
   if ($DevMode -ne $null) {
      New-ItemProperty -Force -propertyType binary -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Path "HKCU:\Software\DefPrn" -Name $PrinterName.PSChildName -Value $DevMode
      }
   }
   }
 
# LoadSettings checks the name of all connected printers and retrieves the DevMode settings (stored in Software\DefPrn under value 'printerconnection') if they exist.
function LoadSettings {
$DevModeList = Get-Item HKCU:\Software\DefPrn
foreach ($PrinterName in (Get-ChildItem "HKCU:\Printers\Connections")){
   $KeyName = $PrinterName.PSChildName
   $DevModeValue = (Get-ItemProperty -path HKCU:\Software\DefPrn -name $KeyName -ErrorAction SilentlyContinue).$KeyName
   if ($DevModeValue -ne $null) {
      New-ItemProperty -Force -propertyType binary -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Path "HKCU:\Printers\Connections\$KeyName" -Name "DevMode" -Value $DevModeValue
      }
   }
   }
 
 If ($args[0] -eq "Load") {
    LoadPrinter $args[1]
   LoadSettings
   }
ElseIf ($args[0] -eq "Save") {
    SavePrinter $args[1]
   SaveSettings
   }
Else {
   Write-Host "`nPlease specify a command line option.`n"
   }

, ,

One Response to PowerShell Script Switches Printer Configurations Between Sites

  1. Lawson Gold November 14, 2011 at 11:47 #

    Thanks for this, it’s just what was needed!

    I’m now stuck at trying to run this after GPP printers have been deployed – due to the size of our network (and the age of some of the machines), even running this as late as possible (‘run at desktop logon’) has resulted in the settings trying to load before the printers have been deployed.

    Is there an option to make a script wait until a GPO has finished processing?

    Cheers,

    LG

Leave a Reply