PowerShell: Remove Offline Network Printers from all Workstations

If you have ever moved Windows print services to a new server, chances are that you have been left wondering what to do with the old stuff left over on the client computers. GPOs make deploying printers a snap, but when it comes to removing them, you are on your own.

Leaving the old printers installed can be confusing to people. In today’s world, printers are increasingly used as attack vectors to establish a beachhead inside corporate networks, leaving them could turn out to be a security risk. Plus, my dad taught me that no job is finished until you’ve cleaned up the mess you made doing it LOL.

If your workstation operating systems are new enough to be running PowerShell and WinRM is enabled, a script could be utilized to remove the old printers. First you will need to find the printers to be removed and store them in a variable. The Get-Printer cmdlet lists all the printers on a system and the Where-Object function will let us filter the properties that identify the specific printers we want to uninstall.

$OfflinePrinters = Get-Printer | Where {($_.Type -like "Connection") -and ($_.PrinterStatus -notlike "Normal")}|
Select Name -ExpandProperty Name

The line above will store the names of printers on the system you run it from that are connected via network and not online in the variable $OfflinePrinters. It should be noted that there is a potential to remove printers you use with this method. If you have a network printer installed from a location you are are not currently connected to, it will match the criteria. For example, if you have a network printer at home but are executing the script from your office the home printer will be deleted.

Next, we’ll loop through the printers in the variable and remove them. If you are concerned about the potential to remove printers you need, remove the -confirm $false and you’ll be prompted for each one.

Foreach ($OfflinePrinter in $OfflinePrinters) {
    Remove-Printer -Name $OfflinePrinter.Name -Confirm $false
}

Removing all the old printers from a single computer is well and good, but PowerShell’s true power comes from it’s ability to execute commands against all systems. With a few more lines of code we can search through your Active Directory domain and find all your workstations. Then we’ll use PowerShell’s Invoke-Command to execute our little printer removal tool on each one.

The script below will need to be run from a Domain Controller or from a system with RSAT installed. To use Invoke-Command, WinRM has to be enabled on your workstations to allow PowerShell Remoting. See Windows Remote Management – Win32 apps | Microsoft Docs


Function Remove-Printers {
    $OfflinePrinters = Get-Printer | Where-Object {($_.Type -like "Connection") -and ($_.PrinterStatus -notlike "Normal")}|
    Select-Object Name -ExpandProperty Name
Foreach ($OfflinePrinter in $OfflinePrinters) {
    Remove-Printer -Name $OfflinePrinter.Name -Confirm $false
    }
}
$Computers = Get-ADComputer -Filter ‘Operatingsystem -Notlike “*server*” -and enabled -eq “true”‘|
Select-Object dnshostname -ExpandProperty dnshostname

ForEach ($Computer in $Computers){
    Invoke-Command -ComputerName $Computer -ScriptBlock {Remove-Printers}
}

Leave a comment