Jonathan Rioux
Jonathan Rioux

Reputation: 1096

PowerShell - Delete a print queue from a print server

I have a printer server which hosts around 1000 printers. I want to delete one of these.

I am currently using this command:

$p = Get-WmiObject -Class Win32_printer -ComputerName $server -namespace "root\CIMV2" -filter "name='printer0456'"

It works, it finds the printer, and then I can use this command to delete it:

$p.delete()

But what freaks the hell out of me, is that it takes like 2-3 minutes for the first command to find the printer. To me, it makes to sense at all.

Is there something I am doing wrong, or something else I can use to delete a printer faster ?

EDIT: check my response

That way, it only fetch until it founds the correct printer, instead of parsing the whole printer list.

Upvotes: 0

Views: 10967

Answers (7)

JRrelyea
JRrelyea

Reputation: 301

Everyone's going down the PowerShell path unnecessarily because gathering a collection of installed print queues on a print server that could have 2000+ queues installed is slow. Extremely slow.

Microsoft has a few built in printing management scripts, typically having a default path of: c:\Windows\System32\Printing_Admin_Scripts\en-US

Want to delete 1 print queue named "Q1"? Run this from a command prompt:

cscript c:\Windows\System32\Printing_Admin_Scripts\en-US\prnmngr.vbs -d -p "ap1"

Gets the job done, satisfies the op's how-to question & is blazing fast (<1 second) compared to running PowerShell to make WMI calls (>2 minutes with 3400 queues installed). Build the formula, save the column to a batch file & run it. Takes care of all of the other proposed answers a lot more efficiently

It's also super simple to build the commands in Excel for deleting multiples as a cleanup effort of some sort

Side note-- Use correct terminology: A "printer" is the physical device spitting out paper. Windows has "print queues" installed, not "printers"

Upvotes: 0

DrG
DrG

Reputation: 1

<#
    Delete printers on remote servers using csv list(server,printer)
    Note: For queues with job(s), they will be stuck in a "deleting"
    state and you must clear the job(s) manually, the queue will delete
    after that. Or, you will need to write in code to stop spooler and
    delete jobs from \spool\printers. Not a big enough deal to warrant
    risk of spooler not starting back up.
#>

$InCSVPath = "\\path_to_list_file\printerstodelete.csv"

$csv = Import-Csv $InCSVPath
foreach($item in $csv){ 

       $server = $item.Server

       $printer = $item.Printer 

       $a = Get-WmiObject -Class Win32_printer -ComputerName $server -Filter "name= '$printer'"

        if($a){

             "Deleting Printer: " + $a.Name #

              $a.Delete()

         }

         else{

               "could not delete: "+$printer

         }

}

Upvotes: 0

Avalon77
Avalon77

Reputation: 31

You should use a WMI accelerator to speed up a lot your query against WMI.

$PrinterInstance = [wmi]"\\$CentralServer\root\cimv2:Win32_Printer.DeviceID='$PrinterName'"

DeviceID is an indexed value in the WMI Database and by default DeviceID should be the same as the printer name.

Upvotes: 3

Daniel
Daniel

Reputation: 1

$PrintersTodelete = Get-WmiObject -Class Win32_printer -ComputerName $server -filter "name='printer0456'"
 if($printersToDelete){
     Foreach($printer in $PrintersTodelete){
         $printer.delete()
      }
 }

Upvotes: 0

DreadfullyDespized
DreadfullyDespized

Reputation: 1

$p = gwmi win32_printer | ? {$_.name -match "PrintServer"} | % ($i in $p) {$i.delete()}

This will only remove printers that have the following print server name in their name path.

Upvotes: 0

Jonathan Rioux
Jonathan Rioux

Reputation: 1096

TEMPORARY SOLUTION I HAVE FOUND

$p = $null
Get-WmiObject -Class Win32_printer -ComputerName $server|ForEach-Object{
    if($_.name -eq "printer0456"){
        $p = $_
        break
    }
}
if($p -ne $null){
    $p.delete()
}

Upvotes: 0

vonPryz
vonPryz

Reputation: 24071

Its the WMI query that costs, so cache the results. Pull all the printers in a collection. Filter the collection and delete the printers you wish to.

$printers = gwmi Win32_printer -ComputerName $server -namespace "root\CIMV2"

$del = $printers | ? { $_.Name -eq "printer1"}
$del.delete()
$del = $printers | ? { $_.Name -eq "printer6"}
$del.delete()
$del = $printers | ? { $_.Name -eq "printer89"}
$del.delete()

You can use -like and -match to filter printers with similar enough names. Like so,

$printers = gwmi Win32_printer -ComputerName $server -namespace "root\CIMV2"

$del = $printers | ? { $_.Name -match "printer10[1-3]" } # Match printer101..103
$del | % {$_.delete()}

Upvotes: 1

Related Questions