?
Solved

Update "Managed By" tab for several Distribution Lists

Posted on 2012-03-20
5
Medium Priority
?
707 Views
Last Modified: 2012-05-22
Hello,
i'm looking for a quick way to update the "Managed By" tab of around 150 distribution lists, i have several new managers and looking for a way to input distribution lists and manager name (more then 1) and have it updated via vbs or powershell with the check mark that allows the manager to update the distribution lists members.
Any ideas?
0
Comment
Question by:johnnyjonathan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 65

Expert Comment

by:RobSampson
ID: 37745695
Hi, I believe the script will do the job:
http://www.experts-exchange.com/Programming/Languages/Q_26268959.html

test it with one group in the file first.

Regards,

Rob.
0
 
LVL 7

Expert Comment

by:sekar_raj32
ID: 37745891
You can run this command to apply managedby for starts from Man DL group

Get-DistributionGroup -Identity Man* | Set-DistributionGroup -BypasssecurityGroupManagercheck -Managedby Test,Administrator

If you want to specify only one group,

Get-DistributionGroup -Identity Managers | Set-DistributionGroup -BypasssecurityGroupManagercheck -Managedby Test,Administrator
0
 

Author Comment

by:johnnyjonathan
ID: 37748609
Hi Rob,
it works but with errors...
it fails after the 2nd distribution list with this error -
(51, 7) Microsoft VBScript runtime error: Name redefined: 'ADS_PROPERTY_CLEAR'
0
 
LVL 65

Accepted Solution

by:
RobSampson earned 2000 total points
ID: 37750190
Oh yeah, that Const ADS_PROPERTY__CLEAR shouldn't be in a loop.  I've moved it up the top.

Rob.

strInputFile = "Groups_For_Users_To_Manage.txt"

If Right(LCase(WScript.FullName), 11) = "wscript.exe" Then
	Set objShell = CreateObject("WScript.Shell")
	objShell.Run "cmd /k cscript """ & WScript.ScriptFullName & """", 1, False
	Set objShell = Nothing
	WScript.Quit
End If

Set objFSO = CreateObject("Scripting.FileSystemObject")
Const intForReading = 1
Const ADS_PROPERTY_CLEAR = 1

WScript.Echo ""

Set objInputFile = objFSO.OpenTextFile(strInputFile, intForReading, False)
While Not objInputFile.AtEndOfStream
	strLine = objInputFile.ReadLine
	If Trim(strLine) <> "" And InStr(strLine, ";") > 0 Then
		strUserName = Left(strLine, InStr(strLine, ";") - 1)
		arrGroups = Split(Mid(strLine, InStr(strLine, ";") + 1), ";")
		
		For Each strGroupName In arrGroups
			strGroupAdsPath = Get_LDAP_User_Properties("Group", "cn", strGroupName, "adsPath")
			If Trim(strGroupAdsPath) <> "" Then
				Set objGroup = GetObject(strGroupAdsPath)
				
				Set objSecurityDescriptor = objGroup.Get("ntSecurityDescriptor")
				Set objDACL = objSecurityDescriptor.DiscretionaryACL
				
				On Error Resume Next
				Set objUser = GetObject("LDAP://" & objGroup.Get("managedBy"))
				If Err.Number = 0 Then
					On Error GoTo 0
					boolSetACE = True
					For Each objACE in objDACL
					      If InStr(LCase(objACE.Trustee), LCase(strUserName)) > 0 Then
					            ' Just to demonstrate Enumeration of the ACE and to stop it adding it a second time
					            'WScript.Echo objACE.Trustee
					            'WScript.Echo objACE.AccessMask
					            'WScript.Echo objACE.AceFlags
					            'WScript.Echo objACE.AceType
					            boolSetACE = False
					      End If
					Next
					If boolSetACE = False Then
					      WScript.Echo "User " & strUserName & " is already the manager of group " & strGroupName
					Else
						' Need to clear the existing manager
						WScript.Echo "Clearing " & objUser.Get("sAMAccountName") & " from the ManagedBy list of " & objGroup.cn
						objGroup.PutEx ADS_PROPERTY_CLEAR, "managedBy", 0
						objGroup.SetInfo
						strUserAdsPath = Get_LDAP_User_Properties("User", "samAccountName", strUserName, "adsPath")
						If Trim(strUserAdsPath) <> "" Then
							Set objUser = GetObject(strUserAdsPath)
							AddACE objGroup, objUser, objSecurityDescriptor, objDACL
						Else
							WScript.Echo "The path for the user " & strUserName & " could not be found. Can not add user to group " & strGroupName
						End If
					End If
				ElseIf Err.Number = -2147463155 Then
					Err.Clear
					On Error GoTo 0
					Set objUser = GetObject(Get_LDAP_User_Properties("User", "samAccountName", strUserName, "adsPath"))
					AddACE objGroup, objUser, objSecurityDescriptor, objDACL
				Else
					WScript.Echo Err.Number & ": " & Err.Description
					Err.Clear
					On Error GoTo 0
				End If
			Else
				WScript.Echo "The path for the group " & strGroupName & " could not be found. User " & strUserName & " could not be added."
			End If
		Next
	End If
Wend

WScript.Echo ""
WScript.Echo "Finished adding managers to groups."
MsgBox "Done"

Sub AddACE(objGroup, objUser, objSecurityDescriptor, objDACL)
	' ACE Types
	Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &H5
	Const ADS_OBJECT_WRITE_MEMBERS = "{BF9679C0-0DE6-11D0-A285-00AA003049E2}"
	Const ADS_ACEFLAG_INHERIT_ACE = &H00002
	Const ADS_ACEFLAG_DONT_INHERIT_ACE = &H0
	' Access Masks
	Const ADS_RIGHT_DS_WRITE_PROP = &H20
	' ACE Flags
	Const ADS_FLAG_OBJECT_TYPE_PRESENT = &H01
	
	strDomainName = Replace(Replace(Mid(objUser.AdsPath, InStr(objUser.AdsPath, "DC")), "DC=", ""), ",", ".")
	strUserAccount = objUser.Get("sAMAccountName")
	'WScript.Echo objGroup.AdsPath & VbCrLf & strDomainNAme & VbCrLf & strUserAccount & VbCrLf & TypeName(objSecurityDescriptor) & VbCrLf & TypeName(objDACL)
	
	objgroup.ManagedBy = Replace(objUser.AdsPath, "LDAP://", "")
	On Error Resume Next
	objGroup.SetInfo
	If Err.Number <> 0 Then
		boolUserAdded = False
		WScript.Echo Err.Number & ": " & Err.Description & " - cannot add " & Replace(objUser.AdsPath, "LDAP://", "") & " to " & objGroup.adspath
		Err.Clear
		On Error GoTo 0
		Set objDomUser = GetObject("WinNT://" & strDomainName & "/" & strUserAccount & ",user")
		WScript.Echo "Trying: " & objDomUser.AdsPath
		objGroup.ManagedBy = objDomUser.AdsPath
		On Error Resume Next
		objGroup.SetInfo
		If Err.Number <> 0 Then
			boolUserAdded = False
			'WScript.Echo Err.Number & ": " & Err.Description & " - cannot add " & Replace(objDomUser.AdsPath, "WinNT://", "") & " to " & objGroup.adspath
			WScript.Echo Err.Number & ": " & Err.Description & " - cannot add " & objDomUser.AdsPath & " to " & objGroup.adspath
			Err.Clear
			On Error GoTo 0
		Else
			boolUserAdded = True
		End If
	Else
		boolUserAdded = True
	End If
	
	If boolUserAdded = True Then
		Set objACE = CreateObject("AccessControlEntry")
		
		objACE.Trustee = strDomainName & "\" & strUserAccount
		objACE.AccessMask = ADS_RIGHT_DS_WRITE_PROP
		objACE.AceFlags = ADS_ACEFLAG_DONT_INHERIT_ACE
		objACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
		objACE.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
		objACE.objectType = ADS_OBJECT_WRITE_MEMBERS
		
		objDACL.AddAce(objACE)
		objSecurityDescriptor.DiscretionaryACL = objDACL
		objGroup.Put "ntSecurityDescriptor", Array(objSecurityDescriptor)
		objGroup.SetInfo
		
		WScript.Echo "User " & strUserName & " added as a manager of group " & strGroupName
	End If
End Sub

Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
	
	If InStr(strObjectToGet, "\") > 0 Then
		arrGroupBits = Split(strObjectToGet, "\")
		strDC = arrGroupBits(0)
		strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
		strObjectToGet = arrGroupBits(1)
	Else
		Set objRootDSE = GetObject("LDAP://RootDSE")
		strDNSDomain = objRootDSE.Get("defaultNamingContext")
	End If

	strBase = "<LDAP://" & strDNSDomain & ">"
	' Setup ADO objects.
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	adoCommand.ActiveConnection = adoConnection

 
	' Filter on user objects.
	'strFilter = "(&(objectCategory=person)(objectClass=user))"
	strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"

	' Comma delimited list of attribute values to retrieve.
	strAttributes = strCommaDelimProps
	arrProperties = Split(strCommaDelimProps, ",")

	' Construct the LDAP syntax query.
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 100
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False

	WScript.Echo ""
	WScript.Echo "Executing " & strQuery
	' Run the query.
	Set adoRecordset = adoCommand.Execute
	' Enumerate the resulting recordset.
	Do Until adoRecordset.EOF
	    ' Retrieve values and display.    
	    For intCount = LBound(arrProperties) To UBound(arrProperties)
	    	If strDetails = "" Then
	    		strDetails = adoRecordset.Fields(intCount).Value
	    	Else
	    		strDetails = strDetails & VbCrLf & adoRecordset.Fields(intCount).Value
	    	End If
	    Next
	    ' Move to the next record in the recordset.
	    adoRecordset.MoveNext
	Loop

	' Clean up.
	adoRecordset.Close
	adoConnection.Close
	Get_LDAP_User_Properties = strDetails

End Function

Open in new window

0
 

Author Closing Comment

by:johnnyjonathan
ID: 37998278
Works perfectly! thank you!
0

Featured Post

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Always backup Domain, SYSVOL etc.using processes according to Microsoft Best Practices. This is meant as a disaster recovery process for small environments that did not implement backup processes and did not run a secondary domain controller that ne…
Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Suggested Courses

777 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