Solved

Vbscript to delete old printers

Posted on 2011-02-22
18
1,198 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
  • 8
  • 7
  • 2
  • +1
18 Comments
 
LVL 7

Expert Comment

by:frajico
Comment Utility
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
Comment Utility
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
Comment Utility
objNetwork.EnumPrinterConnections only enumerates the connected printers - it does not include disconnected printers.
0
 
LVL 37

Expert Comment

by:Neil Russell
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
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 500 total points
Comment Utility
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
Comment Utility
Hi Rob,

That did the trick!

Many thanks,

Leigh
0
 
LVL 65

Expert Comment

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

Regards,

Rob.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Issue: Unstable cursor in Windows XP and Windows runs extremely slow in that any click will bring up the Hour glass (sometimes for several seconds before giving you what you want) . Troubleshooting Process and the FINAL FIX: This issue see…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This tutorial will give a short introduction and overview of Backup Exec 2012 and how to navigate and perform basic functions. Click on the Backup Exec button in the upper left corner. From here, are global settings for the application such as conne…
This tutorial will walk an individual through configuring a drive on a Windows Server 2008 to perform shadow copies in order to quickly recover deleted files and folders. Click on Start and then select Computer to view the available drives on the se…

763 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now