Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

script for automatic change network printers

Status
Not open for further replies.

gisterennogwel

Technical User
Nov 1, 2007
13
0
0
NL
Hi there,

I'm looking for a way to change the printers for +100 users. They need to delete the printers on SERVER1 and then add the same printer from SERVER2. Any additional printers on other servers should not be touched.

I came across a script on
which should do the job for me, but this seems to run on windows XP. That is my issue; these users are on a terminal server running Windows 2003 (64 bit).

As I don't have any VBS experience worth telling I'm looking for someone who can adjust the original script to run on a W2K3 server.

Any input would be helpful.

Thanks in advance.

Ronald Groenewegen.
 
Sample code here: faq329-5798

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 

R E S P E C T markdmac
There are definitely interesting parts in your FAQ.

But for my issue it does not fit. I have a bunch of users with multiple network printers on different servers. Say;
[ul]
[li]\\server1\printer1[/li]
[li]\\server1\printer2[/li]
[highlight][li]\\server2\printer3[/li] [/highlight]
[/ul]
now [blue]server2[/blue] has to go, so we have a new[blue] \\server3\[/blue] and that’s why I’m looking for a script that will search all network printers for[blue] \\server2\ [/blue] printers, remove these connections and add the same printer but then via[blue] \\server3\[/blue]
[ul]
[li]\\server1\printer1[/li]
[li]\\server1\printer2[/li]
[highlight][li]\\server3\printer3[/li] [/highlight]
[/ul]
As I don’t want to add 170 shared printers into a script, I was very interested in the piece with the changes.txt file containing a column with old & a column with new printers.

®
 
Near the bottom of my FAQ is a section "Moving Shares To A New Server" which demos using mapped drives. You can use that to remap your printers.

Another option is if that server is goign off line permanently, use PrintMig to export all printer settings, then import those settings on the new server and modify DNS to point server2 to the new server. Then no changes are needed at the clients.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Mark,

The server will go offline, but both servers will be running side by side for at least 2 weeks. And then when [blue]server2[/blue] is down I can use a CNAME to [blue]server3[/blue] to host the original shares from [blue]server2[/blue] on [blue]server3[/blue].

But this does not help me with an automated cleanup on old [blue]server2[/blue] printers.

®
 
As referenced above, the code in the FAQ will do the cleanup.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
delete the old printer connections using the registry, dont bother with the network.removeprinter method, it is horrid and slow. for that matter when enumerating printers go straight for the registry, if the user has a printer connection which cannot be communicated with it will make your script (logon) flippin slow:

'######### sWAP PRINTERS
Private Sub swapPrintServer(str2Swap)
On Error Resume Next
Dim sPSArray, sPrinter
If blnRegPrinter = False Then
'msgbox "init printers"
Dim strSPRootKey, arrSPSubKeys, refSPRegistry, subSPKey, strSPPrinterMapping

Set enumSPPrinters = WScript.CreateObject("Scripting.Dictionary")
Set refSPRegistry = GetObject("winmgmts:root\default:StdRegProv")
Const HKEY_CURRENT_USER = &H80000001
strSPRootKey = "Printers\Connections"
'Msgbox enumSPPrinters.Count
If refSPRegistry.EnumKey(HKEY_CURRENT_USER, strSPRootKey, arrSPSubKeys) = 0 Then
'init dictionary object of printers
For Each subSPKey In arrSPSubKeys
strSPPrinterMapping = ""
strSPPrinterMapping = Trim(LCase(CStr(subSPKey)))
'Wscript.Echo strSPPrinterMapping
If InStr(strSPPrinterMapping, ",,") = 1 Then
'Wscript.Echo strSPPrinterMapping & " has a ,,"
strSPPrinterMapping = Replace(strSPPrinterMapping, ",", "\")
'Wscript.Echo strSPPrinterMapping & enumSPPrinters.Count
If enumSPPrinters.Exists(strSPPrinterMapping) Then
'already have this one, unlikely
Else
'Wscript.Echo "adding " & strSPPrinterMapping & " to enumPrinters"
enumSPPrinters.Add strSPPrinterMapping, "1"
End If
End If
Next
End If
Set refSPRegistry = Nothing
blnRegPrinter = True
End If

Call LOG_BUFFER("SWAP PRINTER SUB, TRYING TO SWAP/DISCONNECT " & str2Swap, "full", "full")

'aCGC = "\\braps01a&\\172.25.12.254"
sPSArray = Split(str2Swap, "&", -1, 1)

If UBound(sPSArray) = 0 Then
'msgbox "only dlete not readd"
'just want to delete old printers
For Each sPrinter In enumSPPrinters
'wscript.Echo sPrinter & " " & sPSArray(0)
If Left(LCase(sPrinter), Len(sPSArray(0))) = LCase(CStr(sPSArray(0))) Then
'Wscript.Echo "found our server in the string " & LCase(CStr(sPrinter))
Call LOG_BUFFER("ONLY GOING TO REMOVE PRINTER CALLED " & LCase(CStr(sPrinter)), "FULL", "FULL")
WshShell.RegDelete "HKCU\Printers\Connections\" & Replace(LCase(CStr(sPrinter)), "\", ",") & "\"
Call LOG_BUFFER("Err Number = " & Err.Number, "FULL", "FULL")
Call LOG_BUFFER("AFTER REMOVE PRINTER CALL " & LCase(CStr(sPSArray(0))), "FULL", "FULL")
End If
Next
End If

If UBound(sPSArray) = 1 Then
'msgbox "delete and re add"
For i = 0 to enumSPPrinters.Count -1
If Left(LCase(CStr(enumSPPrinters.Item(i))), Len(sPSArray(0))) = LCase(CStr(sPSArray(0))) Then
'msgbox wshPrinters.Item(i)
'msgbox Right(LCase(CStr(wshPrinters.Item(i))), Len(CStr(wshPrinters.Item(i))) - Len(sPSArray(0)) - 1)
Call LOG_BUFFER("GOING TO REMOVE THEN RE-MAP TO NEW SERVER", "FULL", "FULL")
Call LOG_BUFFER("GOING TO REMOVE " & enumSPPrinters.Item(i), "FULL", "FULL")
WshShell.RegDelete "HKCU\Printers\Connections\" & Replace(LCase(CStr(enumSPPrinters.Item(i))), "\", ",") & "\"
Call LOG_BUFFER("AFTER REMOVE PRINTER CALL " & enumSPPrinters.Item(i), "FULL", "FULL")
Call LOG_BUFFER("BEFORE RE-MAP PRINTER CALL TO SERVER " & sPSArray(1), "FULL", "FULL")
waspMach.MapPrinter sPSArray(1) & "\" & Right(LCase(CStr(enumSPPrinters.Item(i))), Len(CStr(enumSPPrinters.Item(i))) - Len(sPSArray(0)) - 1), "False"
Call LOG_BUFFER("AFTER RE-MAP PRINTER CALL TO SERVER " & sPSArray(1), "FULL", "FULL")
End If
Next
End If

End Sub


Public Function MapPrinter(strPrinter, blnDisconnect)
'initilize printers dicObject
On Error Resume Next
If blnMapPrinter = False Then
'msgbox "init printers"
Dim strRootKey, arrSubKeys, refRegistry, subKey, strPrinterMapping

Set enumPrinters = WScript.CreateObject("Scripting.Dictionary")
Set refRegistry = GetObject("winmgmts:root\default:StdRegProv")
Const HKEY_CURRENT_USER = &H80000001
strRootKey = "Printers\Connections"

If refRegistry.EnumKey(HKEY_CURRENT_USER, strRootKey, arrSubKeys) = 0 Then
'init dictionary object of printers
For Each subKey In arrSubKeys
strPrinterMapping = ""
strPrinterMapping = Trim(LCase(CStr(subKey)))
If InStr(strPrinterMapping, ",,") = 1 Then
strPrinterMapping = Replace(strPrinterMapping, ",", "\")
If enumPrinters.Exists(strPrinterMapping) Then
'already have this one, unlikely
Else
'Wscript.Echo "adding " & strPrinterMapping & " to enumPrinters"
enumPrinters.Add strPrinterMapping, "1"
End If
End If
Next
End If
Set refRegistry = Nothing
blnMapPrinter = True
End If

Dim blnConnected
Dim i
blnConnected = False

If enumPrinters.Exists(LCase(strPrinter)) Then
blnConnected = True
End If
'Wscript.Echo strPrinter
'Wscript.Echo blnDisconnect & " disconnect"
'Wscript.Echo blnConnected & " already connected"
'can i check if printer is already available???

If blnConnected = False Then
'msgbox strPrinter
On Error Resume Next
Err.Clear
WshNetwork.AddWindowsPrinterConnection strPrinter
If Err.Number = 0 Then
MapPrinter = 0
Else
MapPrinter = 4
'msgbox "couldnt map printer"
End If
On Error Goto 0
ElseIf blnConnected = True And blnDisconnect = "False" Then
'msgbox "cant map printer " & strPrinter & " already in use and disconnect set to false."
MapPrinter = 8
ElseIf blnConnected = True And blnDisconnect = "True" Then
'msgbox strPrinter

WshShell.RegDelete "HKCU\Printers\Connections\" & Replace(strPrinter, "\", ",") & "\"
'Wscript.Echo Err.Number & " after remove registry printer"
On Error Resume Next
'msgbox ""
WshNetwork.AddWindowsPrinterConnection strPrinter
If Err.Number = 0 Then
MapPrinter = 0
Else
MapPrinter = 2
'msgbox "couldnt map printer"
End If
On Error Goto 0
End If

End Function
 
Here is a script I wrote to do something simular.

It just removes any network printers configured for the user and then enumerates the printers on the printer servers defigned in the arrPrintServers array and connectects to them. The issue I am still working on is how to decide which printer will be default for any given user.

Hope this helps.

Code:
'****************************************************
'*  Script by:  John Fuhrman
'*  Date:       2008, August 21
'****************************************************

Dim WSHShell: Set WSHShell = CreateObject("WScript.Shell")
Dim WSHNetwork: Set WSHNetwork = CreateObject("WScript.Network")
Dim fso: Set fso = CreateObject("scripting.filesystemobject")

'Grab the user name
Dim strUserName: strUserName = WSHNetwork.UserName
 
Dim objDictPrnts: Set objDictPrnts = CreateObject("Scripting.Dictionary")
objDictPrnts.CompareMode = vbTextCompare

Dim arrPrintServers(1): arrPrintServers(0) = "Pserver1": arrPrintServers(1) = "Pserver2"
For Each PrintServer In arrPrintServers
'WScript.Echo PrintServer

Dim strPrnServer: strPrnServer = PrintServer
Dim objWMIService: Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strPrnServer & "\root\cimv2")

Dim colInstalledPrinters: Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_Printer")

Dim objPrinter
For Each objPrinter In colInstalledPrinters
' create a dictionary to store our printer paths
objDictPrnts.Add "\\" & strPrnServer & "\" & objPrinter.Name, UCase(objPrinter.Name)
Next

' loop through the path's that were not found and add them
Dim PrinterPath
For Each PrinterPath In objDictPrnts.Keys
	       	WSHNetwork.AddWindowsPrinterConnection PrinterPath
Next
Next 

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function GetDistinguishedName(strUserName)
'     On Error Resume Next

    Const ADS_SCOPE_SUBTREE = 2
    
    Dim objConnection, objCommand, strDomain, objRoot, objRecordSet
    
    Set objRoot = GetObject("LDAP://rootDSE")
    strDomain = objRoot.Get("defaultNamingContext")
    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand = CreateObject("ADODB.Command")
    objConnection.Provider = ("ADsDSOObject")
    objConnection.Open "Active Directory Provider"
    objCommand.ActiveConnection = objConnection
    objCommand.CommandText = "SELECT distinguishedName FROM " & _
                             "'LDAP://" & strDomain & "' " & _
                             "WHERE samAccountName = '" & strUserName & "'"
    objCommand.Properties("SearchScope") = ADS_SCOPE_SUBTREE
    Set objRecordSet = objCommand.Execute
    If Not objRecordSet.EOF Then
        GetDistinguishedName = objRecordSet.Fields.Item("distinguishedName").Value
    End If
End Function



Thanks

John Fuhrman
Titan Global Services
faq329-6766
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top