![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| Guest | Map network printers based on OU user is in within Active Director 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. |
My System Specs![]() |
| | #2 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Director Rich wrote: Quote: >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. 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 Specs![]() |
| | #3 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire 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: Quote: > Rich wrote: > Quote: > >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 Specs![]() |
| | #4 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire 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 Quote: >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: > Quote: >> Rich wrote: >> Quote: >> >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 Specs![]() |
| | #5 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire 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 Quote: > >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: > > Quote: > >> 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 Specs![]() |
| | #6 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire 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 Quote: >> >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 Specs![]() |
| | #7 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire Hi Richard, We have a similar approach in both favoring using groups to assign printers. I've noticed though that you seem to prefer to bind to each group so you can use IsMember where I prefer to bind to the user and enumerate the groups they are a member of. http://www.tek-tips.com/faqs.cfm?fid=5798 I'm wondering if you have any opinion on which might perform faster. I'm thinking that binding to a single object and then iterating through the array of groups would be quicker but that will really depend on how many groups a user is a member of. Coding wise, I think using a Select Case is easier than a whole bunch of If Then statements. So, I see advantages to both approaches and welcome your expert opinion. Regards, Mark D. MacLachlan |
My System Specs![]() |
| | #8 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire I often suggest binding to the group object and using the IsMember method because it is the most straightforward approach. It is not the most efficient unless you have only one or two groups to check. The slowest step in any script is binding to objects in AD. Binding to local objects, like the dictionary object, is much faster. The method that binds to the fewest objects in AD should be the fastest. Using the Groups method of the user object is very convenient. You get an object reference for every group, so you can retrieve any attribute desired. However, the method must bind to each group object. Also, using the WinNT provider has the following disadvantages: 1. It is slower (I don't know why). 2. It cannot reveal nested domain group membership. 3. It reveals fewer attributes (although that generally doesn't matter in logon scripts). A better approach is to enumerate the memberOf attribute exposed by the LDAP provider. This is a collection of group DN's (Distinguished Names) the user belongs to (direct group membership). It does not include the "primary" group of the user. You must compare the group DN, but you only bind to the user object, not to the group objects. I keep track of the group DN's in a dictionary object, so they only need to be enumerated once. If you want to compare with group sAMAccountName's (pre-Windows 2000 names), use the NameTranslate object. This is much more efficient than binding to the group object so you can retrieve sAMAccountName. For information on NameTranslate see this link: http://www.rlmueller.net/NameTranslateFAQ.htm If you enumerate memberOf and need to account for group nesting, you still need to bind to the group objects. In that case, it might be more efficient to use ADO to retrieve all group objects where the member attribute matches the DN of the user. You can retrieve the group DN or sAMAccountName. You can search with ADO recursively to retrieve all memberships due to nesting. I have an example linked here: http://www.rlmueller.net/IsMember7.htm One query is required for each level of group nesting, but the server returns all of the information requested in each query in one operation. Another method if you need to check nested groups is the tokenGroups attribute of the user. This is a collection of group SID's. It includes all security group memberships, including the "primary" group and all memberships due to group nesting. It does not include security groups. The problem is that you must bind to the corresponding objects to retrieve the group names. This method is marginally more efficient that enumerating the memberOf attribute and binding to each group. -- Richard Mueller MVP Directory Services Hilltop Lab - http://www.rlmueller.net -- "Mark D. MacLachlan" <markdmac@xxxxxx> wrote in message news:OEKV5JI$JHA.1608@xxxxxx Quote: > Hi Richard, > > We have a similar approach in both favoring using groups to assign > printers. I've noticed though that you seem to prefer to bind to each > group so you can use IsMember where I prefer to bind to the user and > enumerate the groups they are a member of. > > http://www.tek-tips.com/faqs.cfm?fid=5798 > > I'm wondering if you have any opinion on which might perform faster. > I'm thinking that binding to a single object and then iterating through > the array of groups would be quicker but that will really depend on how > many groups a user is a member of. Coding wise, I think using a Select > Case is easier than a whole bunch of If Then statements. > > So, I see advantages to both approaches and welcome your expert opinion. > > Regards, > > Mark D. MacLachlan |
My System Specs![]() |
| | #9 (permalink) |
| Guest | Re: Map network printers based on OU user is in within Active Dire Thanks for sharing this Richard. You confirmed a lot of my own observations. I'm typically working in the Small/Medium IT space where nested groups are not an issue with respect to login scripts. Even the few enterprise customers that I have don't typically nest groups for printer memberships or departmental groups which is what I would be using for mapping drives and printers. When I have an opportunity I'm going to try and get some benchmarks to compare using memberOf versus binding to the same number of groups and checking IsMember. Have a great day and happy 4th of July. Mark D. MacLachlan |
My System Specs![]() |
| | #10 (permalink) |
| Guest | 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 Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| HELP! Vista Business - Active Director | Vista General | |||
| Script to query user information based upon group membership | VB Script | |||
| Still can't consistently network between XP/Vista based PCs | Vista networking & sharing | |||
| Attempt to Network Vista Home on Domain Based Network (W2K -Server | Vista networking & sharing | |||
| Belkin Web-based User Interface access issue following Vista upgra | Vista networking & sharing | |||