Handy PowerShell client-side code for print server migration

The Challenge

A client will be decomissioning a Windows print server but will keep the printers and have Windows clients print directly to print devices. How can we automate the setup of the new printer ports and printers?…and as a bonus we’ll get a simple way to mitigate your environment from Printnightmare. The key there is you can use a GPO to deny remote printing and have the Windows clients print/spool directly to the printer. This may not work for all environments, so I offer this solution for your consideration.

The Solution

First you’ll want to grab the printers hosted by the source server that the Windows client currently has a connection to. We simply assign a variable to the output of Get-Printer and filter for ComputerName. The handy thing about Get-Printer is it can tell you the server hosting the printer share as well as the printer’s IP address (PortName).

$printers = Get-Printer | Where-Object {$_.ComputerName -like "*Server01*"}

Next we’ll capture the current “default” printer and save to a variable. It’s this extra step that users appreciate after the cutover. (Or at least they will let you know if you don’t maintain their default printer!!) Once we have the default printer when loop through each printer in the list and for each we’ll create a new printer port and new printer. If the printer is also the current default printer the script will reset the replacement as the default. And finally the script will delete the smb connected printer.

Adding on some error control and logging and you get the final code:

$printers = Get-Printer | Where-Object {$_.ComputerName -like "*Server01*"}
foreach ($printer in $printers)
{
    #Get default printer
    $DefaultPrinter = (Get-WmiObject -Query " SELECT * FROM Win32_Printer WHERE Default=$true").Name

    #Fix IP Port formatting
    if($($printer.PortName) -like "IP_*"){$portName = $printer.PortName.Replace("IP_","")}
    elseif($($printer.PortName) -like "*_*"){$portName = $printer.PortName.Split("_")[0]}
    else{$portName = $($printer.PortName)}

Add-PrinterPort -Name $portName -PrinterHostAddress $portName
Add-PrinterPort -Name $portName -PrinterHostAddress $portName
   if($($printer.Name) -eq $DefaultPrinter)
     {
                      $defPrinter = Get-CimInstance -ClassName Win32_Printer -Filter $filter
            Invoke-CimMethod -InputObject $defPrinter -MethodName SetDefaultPrinter
     }

  #Remove legacy printer
  Remove-Printer -Name $printer.Name
}

I hope you find this helpful.

Happy building,

D

Handy PowerShell client-side code for print server migration

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top