Thursday, January 2, 2014

Options for Automating per-location printer deployment

I had an interesting chat with a customer last week.  They have a large number (400+) of stores with Windows XP and Windows 7 workstations.  These workstations are all joined to Active Directory, but the users have historically logged in with shared local accounts.  That's kind of a fiddly configuration, but hey.. it works for them.

Anyway, they are switching all their users to login with AD accounts.  Yeah!  Unfortunately they are getting a lot of helpdesk calls from the users because their network printers aren't being mapped automatically.  Booh!

So we talked through a few solutions.

The "Right" ® ™ solution is to push the printers through group policy from AD.  I did not particularly relish the thought of creating 400 discrete group policies





Another solution would be to User State Migration Tool the printer over.  Well, that would be a solution if the USMT supported network printers on WinXp.  So that's a "no."

A third solution is a logon script, and I think that's what he's leaning towards doing.  Their OU structure is what really makes this work.  It starts with the domain at the top, then "Locations", then the 4 digit store numbers, then an OU for workstations where the Computer accounts live.  What is great about this solution is that one logon script can look at the OU information to determine which store the machine is in, and then map the per-user printer settings accordingly.  Nice!  One script vs. 400+ GPOs?  That isn't a hard question.

Here is the sample script I cooked up for him.

' This code is provided as a sample, and not guaranteed
' or supported any way.
' This determines the OU of a workstation, and maps one

or more network printers based on the OU information.

Set objSysInfo = CreateObject("ADSystemInfo")
strComputer = objSysInfo.ComputerName

Set objComputer = GetObject("LDAP://" & strComputer)

arrOUs = Split(objComputer.Parent, ",")

'Uncommenting this command will print the full
' workstation OU path
' wscript.Echo "Machine path is " + objComputer.Parent

'arrOUs is an array created from the LDAP path split up
'by commas. i.e. on a machine in Location A01 it may contain
'arrOUs(0) = LDAP://OU=Workstations
'arrOUs(1) = OU=A01    < This is the one you care about
'arrOUs(2) = OU=Locations
'arrOUs(3) = DC=YourDomain
'arrOUs(4) = DC=com

'This command chooses which array element is the
OU containing the Location name
strOUName = arrOUs(1)

'Uncommenting this command will print the OU name
' wscript.Echo "The OU Name is " + strOUName

'This takes the OU= part off and puts it in a new variable

arrMainOU = Split(strOUName, "=")
strLocationName = arrMainOU(1)

'Uncommenting this command will print the Location name
' wscript.Echo "The Location Name is " + strLocationName

' Now a large case statement executes to create the
printers based on the Location name.

Set WshNetwork = CreateObject("WScript.Network")

Select Case strLocationName

    Case "A001"
        PrinterPath = "\\Server\Printer1"
        PrinterDriver = "PrinterDriver"
        ' See note in
regarding the PrinterDriver attribute.
        WshNetwork.AddWindowsPrinterConnection PrinterPath, PrinterDriver

        WshNetwork.SetDefaultPrinter "\\Server\Printer1"
    Case "A002"
        PrinterPath = "\\Server\Printer2"
        PrinterDriver = "PrinterDriver"
        WshNetwork.AddWindowsPrinterConnection PrinterPath, PrinterDriver

        WshNetwork.SetDefaultPrinter "\\Server\Printer2"
    Case "A003"
        PrinterPath = "\\Server\Printer3"
        PrinterDriver = "PrinterDriver"
        WshNetwork.AddWindowsPrinterConnection PrinterPath, PrinterDriver

        WshNetwork.SetDefaultPrinter "\\Server\Printer3"       
End Select

Full Disclosure: this contains code shamelessly stolen from:
Hey Scripting Guy - "Identifying a Workstation’s OU (wscript)" from
Mapping a network printer via logon script.

Hope this helps someone.

If you have questions like this, Post a comment!  I like fun challenges like this.


No comments: