• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 724
  • Last Modified:

Update "Managed By" tab for several Distribution Lists

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
johnnyjonathan
Asked:
johnnyjonathan
  • 2
  • 2
1 Solution
 
RobSampsonCommented:
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
 
Kamalasekar ParthasarathyExchange SpecialistCommented:
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
 
johnnyjonathanAuthor Commented:
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
 
RobSampsonCommented:
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
 
johnnyjonathanAuthor Commented:
Works perfectly! thank you!
0

Featured Post

Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now