Link to home
Start Free TrialLog in
Avatar of LeighWardle
LeighWardleFlag for Australia

asked on

Vbscript to delete old printers

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

Avatar of frajico
frajico

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
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
Avatar of LeighWardle

ASKER

objNetwork.EnumPrinterConnections only enumerates the connected printers - it does not include disconnected printers.
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
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
Avatar of RobSampson
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.
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
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

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
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

Rob, sorry it's a bit tricky to get it to skip the Server2008 printers

I still get outputs like:  

,,server2008, Bing

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.
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

>> 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.
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

ASKER CERTIFIED SOLUTION
Avatar of RobSampson
RobSampson
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Rob,

That did the trick!

Many thanks,

Leigh
Sorry about that. I hadn't realised that line was incorrect in terms of the wildcard detection.

Regards,

Rob.