Solved

Update "Managed By" tab for several Distribution Lists

Posted on 2012-03-20
5
664 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
  • 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 500 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

Join & Write a Comment

Resolve DNS query failed errors for Exchange
Synchronize a new Active Directory domain with an existing Office 365 tenant
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…

760 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now