View Single Post
Old 07-06-2009   #10 (permalink)
Rich


 
 

Re: Map network printers based on OU user is in within Active Dire

OK, so if I understand right, I want to use the following piece of code, but
then just keep copying and pasting the If statement at the end while tweaking
the CN and printer names, right?

In the IF's parentheses, do I have to put the entire path, or could i just
put the Group name alone? I noticed in your IsMember links it just had the
Group name, which is a little easier on the eyes.

==========
Option Explicit

Dim objSysInfo, objUser, strUserDN
Dim objGroupList, colstrGroups, strDN
Dim objNetwork

' Bind to current user object.
Set objSysInfo = CreateObject("ADSystemInfo")
strUserDN = objSysInfo.UserName
Set objUser = GetObject("LDAP://" & strUserDN)

' Create dictionary object to track groups.
Set objGroupList = CreateObject("Scripting.Dictionary")
objGroupList.CompareMode = vbTextCompare

' Retrieve group memberships (Distinguished Names).
colstrGroups = objUser.memberOf
Select Case TypeName(colstrGroups)
Case "String"
' One group DN in collection.
objGroupList.Add colstrGroups, True
Case "Variant()"
' More than one group DN in collection.
For Each strDN In colstrGroups
objGroupList.Add strDN, True
Next
Case "Empty"
' No group DN's.
End Select

' Map printer per group membership. Repeat for each group.
Set objNetwork = CreateObject("Wscript.Network")
If objGroupList.Exists("cn=Test Group,ou=West,dc=MyDomain,dc=com") Then
objNetwork.AddWindowsPrinterConnection "\\PrintServer\HPLaser2"
objNetwork.SetDefaultPrinter "\\PrintServer\HPLaser2"
End If


"Richard Mueller [MVP]" wrote:
Quote:

> The key for performance is to limit the number of objects bound across the
> WAN (in AD). Binding to local objects is not a problem. The example I posted
> requires binding to each of the group objects to be tested. 30 such objects
> would be a lot.
>
> I retrieve group memberships once and keep them in a dictionary object. This
> involves binding just to the user object and retrieving the memberOf
> attribute. I must deal with the group DN's, but the code should be fast. For
> example:
> ==========
> Option Explicit
>
> Dim objSysInfo, objUser, strUserDN
> Dim objGroupList, colstrGroups, strDN
> Dim objNetwork
>
> ' Bind to current user object.
> Set objSysInfo = CreateObject("ADSystemInfo")
> strUserDN = objSysInfo.UserName
> Set objUser = GetObject("LDAP://" & strUserDN)
>
> ' Create dictionary object to track groups.
> Set objGroupList = CreateObject("Scripting.Dictionary")
> objGroupList.CompareMode = vbTextCompare
>
> ' Retrieve group memberships (Distinguished Names).
> colstrGroups = objUser.memberOf
> Select Case TypeName(colstrGroups)
> Case "String"
> ' One group DN in collection.
> objGroupList.Add colstrGroups, True
> Case "Variant()"
> ' More than one group DN in collection.
> For Each strDN In colstrGroups
> objGroupList.Add strDN, True
> Next
> Case "Empty"
> ' No group DN's.
> End Select
>
> ' Map printer per group membership. Repeat for each group.
> Set objNetwork = CreateObject("Wscript.Network")
> If objGroupList.Exists("cn=Test Group,ou=West,dc=MyDomain,dc=com") Then
> objNetwork.AddWindowsPrinterConnection "\\PrintServer\HPLaser2"
> objNetwork.SetDefaultPrinter "\\PrintServer\HPLaser2"
> End If
> =======
> If you want to deal with the "pre-Windows 2000" names (sAMAccountName) of
> the groups, then you must bind to each group the user is a member of.
> However, this should be a much smaller number (hopefully) than the 30 groups
> you want to test. Two VBScript examples of functions that tests group
> membership by sAMAccountName, and also handle membership due to group
> nesting, are linked here:
>
> http://www.rlmueller.net/IsMember2.htm
>
> http://www.rlmueller.net/IsMember4.htm
>
> --
> Richard Mueller
> MVP Directory Services
> Hilltop Lab - http://www.rlmueller.net
> --
>
> "Rich" <richjone@xxxxxx> wrote in message
> news:8D9FFECF-3220-423C-B740-38D7FE321166@xxxxxx
Quote:

> > My scripting knowledge is limited, so please bare with me. How would I do
> > this for multiple groups, determining multiple sets of printers? Do I
> > just
> > keep copying and pasting over and over from the setObjGroup line till the
> > end?
> >
> > or could i just make a huge If or case type statement saying if in group
> > Group1 map these printers, if in group Group2 map these printers, etc etc
> >
> > I understand what your script is doing I think, just not sure how to best
> > scale it to probably 30 groups without increasing my users login time
> > because
> > of a script. It already takes them log enough to log in because of old
> > hardware, if it takes longer i might have a mutiny on my hands ;-)
> >
> > "Richard Mueller [MVP]" wrote:
> >
Quote:

> >> You would create a group for each printer. Then to test for user
> >> membership
> >> in the group the code could be similar to:
> >> =======
> >> Option Explicit
> >> Dim objSysInfo, strUserDN, objUser
> >> Dim objGroup, objNetwork
> >>
> >> ' Retrieve DN of current user.
> >> Set objSysInfo = CreateObject("ADSystemInfo")
> >> strUserDN = objSysInfo.UserName
> >>
> >> ' Bind to current user object.
> >> Set objUser = GetObject("LDAP://" & strUserDN)
> >>
> >> Set objNetwork = CreateObject("Wscript.Network")
> >> ' Bind to group.
> >> Set objGroup = GetObject("LDAP://cn=Test
> >> Group,ou=West,dc=MyDomain,dc=com")
> >>
> >> ' Check for membership in the group.
> >> If (objGroup.IsMember(objUser.AdsPath) = True) Then
> >> objNetwork.AddWindowsPrinterConnection "\\PrintServer\HPLaser2"
> >> objNetwork.SetDefaultPrinter "\\PrintServer\HPLaser2"
> >> End If
> >> ========
> >> I say this method is better because users should be placed in OU's for
> >> two
> >> purposes. To organize them as you wish in your organization, and to apply
> >> the proper Group Policy. It makes things complicated to also use OU's to
> >> define printers. You probably have many more printers than logical units
> >> in
> >> your organization. Groups just have more flexibility.
> >>
> >> Also, if users can use any computer (or many computers), and computers
> >> are
> >> fixed (not laptops that roam with the users), it can make sense to map
> >> printers according to the group the computer object is a member of. I did
> >> this for years. I made my desktop computers member of the appropriate
> >> group
> >> for the nearest printer. In the logon script I used code similar to:
> >> ==========
> >> ' Retrieve DN of computer object.
> >> Set objSysInfo = CreateObject("ADSystemInfo")
> >> strComputerDN = objSysInfo.ComputerName
> >>
> >> ' Bind to computer object.
> >> Set objComputer = GetObject("LDAP://" & strComputerDN)
> >>
> >> Set objNetwork = CreateObject("Wscript.Network")
> >>
> >> ' Bind to group.
> >> Set objGroup = GetObject("LDAP://cn=Test
> >> Group,ou=West,dc=MyDomain,dc=com")
> >>
> >> ' Check for membership in the group.
> >> If (objGroup.IsMember(objComputer.AdsPath) = True) Then
> >> objNetwork.AddWindowsPrinterConnection "\\PrintServer\HPLaser2"
> >> objNetwork.SetDefaultPrinter "\\PrintServer\HPLaser2"
> >> End If
> >> ======
> >> There are many methods to check for group membership, but the above is
> >> the
> >> simplest if you are only concerned with direct membership (you don't care
> >> about membership due to group nesting).
> >>
> >> --
> >> Richard Mueller
> >> MVP Directory Services
> >> Hilltop Lab - http://www.rlmueller.net
> >> --
> >>
> >> "Rich" <richjone@xxxxxx> wrote in message
> >> news:78DFCE10-EC54-48CD-9BB7-4EE060B6C7BC@xxxxxx
> >> >I never thought of doing it based on group membership, I might be able
> >> >to
> >> >do
> >> > it like that since you said it's better. How would I do it based on
> >> > group
> >> > membership?
> >> >
> >> > "Richard Mueller [MVP]" wrote:
> >> >
> >> >> Rich wrote:
> >> >>
> >> >> >I have users spread out in Active Directory under 20 sub-OU's of a
> >> >> >Users
> >> >> >OU.
> >> >> > What I'd like to do is have a GPO on Users call a script that will
> >> >> > map
> >> >> > different printers based on what sub-OU the user account is in.
> >> >> > Does
> >> >> > anyone
> >> >> > have a script that will do that? I'm assuming its possible to do.
> >> >>
> >> >> It's more common to map printers according to group membership. To
> >> >> determine
> >> >> the parent OU you can use the Parent method of the user object, which
> >> >> returns the Distinguished Name of the OU. For example:
> >> >> ========
> >> >> Option Explicit
> >> >> Dim objSysInfo, strUserDN, objUser
> >> >> Dim strParentDN, objNetwork
> >> >>
> >> >> ' Retrieve DN of current user.
> >> >> Set objSysInfo = CreateObject("ADSystemInfo")
> >> >> strUserDN = objSysInfo.UserName
> >> >> ' Escape any forward slash characters.
> >> >> strUserDN = Replace(strUserDN, "/", "\/")
> >> >>
> >> >> ' Bind to current user object.
> >> >> Set objUser = GetObject("LDAP://" & strUserDN)
> >> >>
> >> >> ' Retrieve DN of parent OU/Container.
> >> >> strParentDN = objUser.Parent
> >> >>
> >> >> ' Map printers according to parent OU.
> >> >> Set objNetwork = CreateObject("Wscript.Network")
> >> >> Select Case LCase(strParentDN)
> >> >> Case "ou=west,ou=users,dc=mydomain,dc=com"
> >> >> objNetwork.AddWindowsPrinterConnection
> >> >> "\\PrintServer1\HPLaser2"
> >> >> objNetwork.SetDefaultPrinter "\\PrintServer1\HPLaser2"
> >> >> Case "ou=east,ou=users,dc=mydomain,dc=com"
> >> >> objNetwork.AddWindowsPrinterConnection
> >> >> "\\PrintServer2\HPLaser3"
> >> >> objNetwork.SetDefaultPrinter "\\PrintServer2\HPLaser3"
> >> >> End Select
> >> >> =======
> >> >> Using the DN of the parent OU makes sure the name is unique. You can
> >> >> also
> >> >> parse for the Relative Distinguished Name (RDN), but that may not be
> >> >> unique.
> >> >> Code to parse for the RDN could be similar to:
> >> >> =========
> >> >> Dim objSysInfo, strUserDN, objUser
> >> >> Dim strOUPath, arrContainers, arrOU, strOU
> >> >>
> >> >> ' Retrieve DN of current user.
> >> >> Set objSysInfo = CreateObject("ADSystemInfo")
> >> >> strUserDN = objSysInfo.UserName
> >> >> ' Escape any forward slash characters.
> >> >> strUserDN = Replace(strUserDN, "/", "\/")
> >> >>
> >> >> ' Bind to current user object.
> >> >> Set objUser = GetObject("LDAP://" & strUserDN)
> >> >>
> >> >> ' Retrieve DN of parent OU/Container.
> >> >> strOUPath = objUser.Parent
> >> >>
> >> >> ' Replace any escaped commas with Chr(164).
> >> >> strOUPath = Replace(strOUPath, "\,", Chr(164))
> >> >>
> >> >> ' Parse Parent DN into comma delimited components.
> >> >> arrContainers = Split(strOUPath, ",")
> >> >>
> >> >> ' Parse the first component to retrieve name of the OU/Container.
> >> >> arrOU = Split(arrContainers(0), "=")
> >> >> strOU = arrOU(1)
> >> >>
> >> >> ' Restore any escaped commas.
> >> >> strOU = Replace(strOU, Chr(164), "\,")
> >> >>
> >> >> Wscript.Echo "User is in OU/Container " & strOU
> >> >> ========
> >> >> Again, you can use a Select Case construction to map printers. If you
> >> >> know
> >> >> your AD has no DN's with embedded commas or forward slashes you can
> >> >> eliminate the code that accounts for that, but it doesn't hurt in any
> >> >> case.
> >> >>
> >> >> --
> >> >> Richard Mueller
> >> >> MVP Directory Services
> >> >> Hilltop Lab - http://www.rlmueller.net
> >> >> --
> >> >>
> >> >>
> >> >>
> >>
> >>
> >>
>
>
>
My System SpecsSystem Spec