Reputation: 1096
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
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
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
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
Reputation: 1
$PrintersTodelete = Get-WmiObject -Class Win32_printer -ComputerName $server -filter "name='printer0456'"
if($printersToDelete){
Foreach($printer in $PrintersTodelete){
$printer.delete()
}
}
Upvotes: 0
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
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
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