Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Vbscript to delete old printers

Posted on 2011-02-22
18
Medium Priority
?
1,256 Views
Last Modified: 2012-06-27
Hi Experts:

We are migrating from a Server running Windows SBS 2003 (name:Server) to a Server running Windows Server 2008 (name:Server2008).

Our Workstation/Clients are running Windows XP SP3.

Our workstations have references to printers on the old server that have been retired.
I would like to delete all of these with a Workstation/Client login script.

The following code will delete printers hosted on the old server if they are connected, but I cannot figure out how to delete retired printers.

Regards,
Leigh

'Delete all the old Server printers 

' 21 Feb 2011 - first version by Leigh Wardle

dim boolDebug

boolDebug = True
boolDebug = False

Set objNetwork = CreateObject("WScript.Network") 


Set objPrinters = objNetwork.EnumPrinterConnections


if boolDebug then
	Wscript.echo "objPrinters.count=" & objPrinters.count
End If 

For i=0 to objPrinters.count-1 

	if boolDebug then
		wscript.echo "Printer Name: " & objPrinters.Item(i)
	end if
	
	If Instr(Lcase(objPrinters.Item(i)),"server") Then

		if boolDebug then
			wscript.echo objPrinters.Item(i)
		end if
		
		If Instr(Lcase(objPrinters.Item(i)),"server2008") Then
			'do not delete
		Else
			if boolDebug then
				Wscript.echo "delete - " & objPrinters.Item(i)
				objNetwork.RemovePrinterConnection objPrinters.Item(i)
			End If 
		End If 
	End If 
Next

if boolDebug then
	Wscript.echo "script complete" 
End If

Open in new window

0
Comment
Question by:LeighWardle
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
  • 2
  • +1
18 Comments
 
LVL 7

Expert Comment

by:frajico
ID: 34950529
Set objNetwork = WScript.CreateObject("WScript.Network")
Set WshNetwork = CreateObject("WScript.Network")
Set colPrinters = objNetwork.EnumPrinterConnections

For i = 0 to colPrinters.Count -1 Step 2
 If Left(colPrinters.Item(i+1),7) = "\\server" Then
      On Error Resume Next
        impresora = colPrinters.Item(i+1)
          WshNetwork.RemovePrinterConnection impresora, forced , updateprofile
      On Error Goto 0
 End If
Next
0
 
LVL 7

Expert Comment

by:frajico
ID: 34950546
Set objNetwork = WScript.CreateObject("WScript.Network")
Set WshNetwork = CreateObject("WScript.Network")
Set colPrinters = objNetwork.EnumPrinterConnections

For i = 0 to colPrinters.Count -1 Step 2
 If Left(colPrinters.Item(i+1),8) = "\\server" Then
      On Error Resume Next
        impresora = colPrinters.Item(i+1)
          WshNetwork.RemovePrinterConnection impresora, forced , updateprofile
      On Error Goto 0
 End If
Next
0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34950564
objNetwork.EnumPrinterConnections only enumerates the connected printers - it does not include disconnected printers.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 37

Expert Comment

by:Neil Russell
ID: 34950862
This will enumerate ALL printers. You should be able to work from this....

 
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_Printer")
For Each objPrinter in colInstalledPrinters
 Wscript.Echo "Name: " & objPrinter.Name
 Wscript.Echo "Location: " & objPrinter.Location
Next

Open in new window


REF: http://technet.microsoft.com/en-us/library/ee176746.aspx
0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34956310
Hi Neilsr,

I tried your code, but it is not picking up the disconnected (retired) printers such as "Bono on Server" - see screendump below.

Regards,
Leigh
0001.jpg
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34957710
Hi Leigh, does the script provided actually show the ones "on server" or not?  I'd be surprised that it's skipping the output altogether....

Rob.
0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34958077
Hi Rob,

I just modified the script to concatenate all the Printer Names - see below.

It is not picking up any of the printers associated with the old Server (name:"Server").

Regards,
Leigh
0006.jpg
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34958126
Hmmm, well that's a bummer...I just dug up something I did a while ago, which goes through the registry to find the devices.  In your case, I'm searching for anything that's got ",server," in it, as that's the server name you've retired.

I've commented out the delete lines, so it will only tell you what it finds.

Regards,

Rob.
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
 
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
 
strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*,server,*"

strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\Devices\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*,server,*"
 
Sub DeleteSubkeysName(HKEY_CURRENT_USER, strKeyPath, strName)
	objRegistry.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubkeys
 
	If IsArray(arrSubkeys) Then
		For Each strSubkey In arrSubkeys
			Wscript.Echo strSubKey
			If InStr(strName, "*") = 0 Then
				If LCase(strSubkey) = LCase(strName) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
				If InStr(LCase(strSubkey), LCase(strName)) > 0 Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" Then
				If Right(LCase(strSubkey), Len(strName) - 1) = Right(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			ElseIf Right(strName, 1) = "*" Then
				If Left(LCase(strSubkey), Len(strName) - 1) = Left(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			End If
 
			DeleteSubkeysName HKEY_CURRENT_USER, strKeyPath & "\" &	strSubkey, strName
		Next
	End If
End Sub

Open in new window

0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34958179
Rob,

We are on a winning streak with that one.

I cannot figure out how to tweak your script so that it bypasses the printers that are on the new Server (Name:Server2008).

Regards,
Leigh
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34958193
In the output though, it should be
,,server,<printername>
which should be different to
,,server2008,<printername>

because your print servers have different names....isn't that along the lines of the output you get?

Try this....
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
 
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
 
strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*,,server,*"

strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\Devices\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*\\server\*"
 
Sub DeleteSubkeysName(HKEY_CURRENT_USER, strKeyPath, strName)
	objRegistry.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubkeys
 
	If IsArray(arrSubkeys) Then
		For Each strSubkey In arrSubkeys
			Wscript.Echo strSubKey
			If InStr(strName, "*") = 0 Then
				If LCase(strSubkey) = LCase(strName) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
				If InStr(LCase(strSubkey), LCase(strName)) > 0 Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" Then
				If Right(LCase(strSubkey), Len(strName) - 1) = Right(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			ElseIf Right(strName, 1) = "*" Then
				If Left(LCase(strSubkey), Len(strName) - 1) = Left(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			End If
 
			DeleteSubkeysName HKEY_CURRENT_USER, strKeyPath & "\" &	strSubkey, strName
		Next
	End If
End Sub

Open in new window

0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34958255
Rob, sorry it's a bit tricky to get it to skip the Server2008 printers

I still get outputs like:  

,,server2008, Bing

0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34958284
That surprises me.....since we are searching for
"*,,server,*"

and
"*\\server\*"

it's odd that it's pulling ,,server2008,

I'll have to do some tests tomorrow....

Rob.
0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34958321
Hi Rob,

I worked out how to skip the Server2008 entries - I added an If statement:

If InStr(LCase(strSubKey), "server2008") = 0 Then

see revised code below.

I also changed your code:

strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*,,server,*"

to:

strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*\\server\*"

I assume that change does not make any difference?

Regards,
Leigh

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
 
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
 
strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*\\server\*"

strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\Devices\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*\\server\*"
 
Sub DeleteSubkeysName(HKEY_CURRENT_USER, strKeyPath, strName)
	objRegistry.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubkeys
 
	If IsArray(arrSubkeys) Then
		For Each strSubkey In arrSubkeys
		If InStr(LCase(strSubKey), "server2008") = 0 Then
			Wscript.Echo strSubKey
			If InStr(strName, "*") = 0 Then
				If LCase(strSubkey) = LCase(strName) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
				If InStr(LCase(strSubkey), LCase(strName)) > 0 Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" Then
				If Right(LCase(strSubkey), Len(strName) - 1) = Right(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			ElseIf Right(strName, 1) = "*" Then
				If Left(LCase(strSubkey), Len(strName) - 1) = Left(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					'objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			End If
 
			DeleteSubkeysName HKEY_CURRENT_USER, strKeyPath & "\" &	strSubkey, strName
		End If
		Next
	End If
End Sub

Open in new window

0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34958369
>> I assume that change does not make any difference?

it would, to the first one, because if you look in
HKCU\Printers\Connections\

you'll see that the connections have commas in that key.  The second one, at:
HKCU\Software\Microsoft\Windows NT\CurrentVersion\Devices\

has slashes.

So, if that gives you some good output, you should be able to go ahead and delete those keys.

Maybe delete one manually first...

Rob.
0
 
LVL 1

Author Comment

by:LeighWardle
ID: 34966024
Hi Rob,

I put your code into a Procedure (see below).

And trying to delete just one printer, "Hendrix".

Line 102 outputs:

Attempting to delete ,,server,Hendrix

But none of the lines such as line 107 (Wscript.Echo "Deleting " ...) are getting executed...

Regards,
Leigh
'defines printers to be mapped to all PCs + Default printer is set to the one defined in the Client PC List spreadsheet

'5 June 2007 - Updated by Sarah Webber
'15 August 2008 - LW - updated so that printers mapped to all PCs are Kylie, Hendrix, Sinatra, Springsteen. (removed Joplin)
'13 Nov 2008 - Updated standard printers by Sarah Webber
'19 Feb 2011 – [LW] Updated to assume that argument is simply the Printer Name
'24 Feb 2011 – [LW] added Public Access Server2008 Printers

'TESTING: if logged in to dbserver as administrator:
'	wscript.exe //d //x "\\server2008\C$\ASRC IT Scripts\Add the Specified Printer (Test).vbs" Elvis

'The strings below define the printers mapped for all PCs
'If printer names change then modify the text below 
' to reflect the new printer share names 

dim objNetwork
dim objArgs
dim strServerName
dim strUserName
dim strUNCDefaultPrinter
dim strPrinter
dim strUNCPrinter
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

'On Error Resume Next 'comment this out when testing!

'test Delete_All_Printers_from_Old_Server.vbs
Delete_All_Printers_from_Old_Server


' obArgs(0) is the first argument that refers to the Default printer name that is passed to this batch file
' defined in the Client PC List spreadsheet

Set objNetwork = Wscript.CreateObject("WScript.Network")
Set objArgs = WScript.Arguments

strServerName = "Server2008"

'strUserName = objNetwork.UserName
'msgbox "strUserName=" & strUserName


'add all the Public Access Printers
arrPrinters = Array("Kylie", "Toshiba_B_W", "Elvis")
For Each strPrinter In arrPrinters
	strUNCPrinter = "\\" & strServerName & "\" & strPrinter
	'MsgBox  "strUNCPrinter= " & strUNCPrinter
	objNetwork.AddWindowsPrinterConnection strUNCPrinter
Next 

strUNCDefaultPrinter = "\\" & strServerName & "\" & objArgs(0)

If LCase(objNetwork.ComputerName) = "dbserver" Then
	'MsgBox  "strUNCDefaultPrinter =" & strUNCDefaultPrinter
End If




'add the Default Printer
objNetwork.AddWindowsPrinterConnection strUNCDefaultPrinter
'set the Default Printer
objNetwork.SetDefaultPrinter strUNCDefaultPrinter

If LCase(objNetwork.ComputerName) = "dbserver" Then
	'MsgBox  "script complete" 
End If

Sub Delete_All_Printers_from_Old_Server ()

'boolTest
'boolTest = True

Const HKEY_CURRENT_USER = &H80000001
'strComputer = "."
 
'Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
 
strKeyPath = "Printers\Connections\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*,,server,*"

strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\Devices\"
DeleteSubkeysName HKEY_CURRENT_USER, strKeypath , "*\\server\*"

End Sub
 
Sub DeleteSubkeysName(HKEY_CURRENT_USER, strKeyPath, strName)
	objRegistry.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubkeys
 
	If IsArray(arrSubkeys) Then
		For Each strSubkey In arrSubkeys
		
		'ignore the Server2008 printers
		If InStr(LCase(strSubKey), "server2008") = 0 Then
			
			Wscript.Echo strSubKey
			
			'our first test is to delete "Hendrix"!
			If InStr(LCase(strSubKey), "hendrix") <> 0 Then
			
			msgbox "Attempting to delete " & strSubKey
			
			If InStr(strName, "*") = 0 Then
				If LCase(strSubkey) = LCase(strName) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
				If InStr(LCase(strSubkey), LCase(strName)) > 0 Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If
			ElseIf Left(strName, 1) = "*" Then
				If Right(LCase(strSubkey), Len(strName) - 1) = Right(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			ElseIf Right(strName, 1) = "*" Then
				If Left(LCase(strSubkey), Len(strName) - 1) = Left(LCase(strName), Len(strName) - 1) Then
					Wscript.Echo "Deleting " & strKeyPath & "\" & strSubkey
					objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey
				End If				
			End If 'If InStr(LCase(strSubKey), "bono") > 0 Then
			End If  
 
			DeleteSubkeysName HKEY_CURRENT_USER, strKeyPath & "\" &	strSubkey, strName
		End If
		Next
	End If
End Sub

Open in new window

0
 
LVL 65

Accepted Solution

by:
RobSampson earned 2000 total points
ID: 34966232
Please change these two lines (lines 109 and 110 in your code):

                  ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
                        If InStr(LCase(strSubkey), LCase(strName)) > 0 Then

to this

                  ElseIf Left(strName, 1) = "*" And Right(strName, 1) = "*" Then
                        If InStr(LCase(strSubkey), LCase(Mid(Left(strName, Len(strName) - 1), 2))) > 0 Then


Regards,

Rob.
0
 
LVL 1

Author Closing Comment

by:LeighWardle
ID: 34966294
Hi Rob,

That did the trick!

Many thanks,

Leigh
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34966321
Sorry about that. I hadn't realised that line was incorrect in terms of the wildcard detection.

Regards,

Rob.
0

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Resolving an irritating Remote Desktop connection that stops your saved credentials from being used.
This tutorial will show how to configure a single USB drive with a separate folder for each day of the week. This will allow each of the backups to be kept separate preventing the previous day’s backup from being overwritten. The USB drive must be s…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question