GroupModifyManager.vbs

'=========================================================================
' GroupModifyManager.vbs
' VERSION: 1.0
' AUTHOR: Brian Steinmeyer
' EMAIL: [email protected]
' WEB: https://sigkillit.com
' DATE: 1/4/2013
' COMMENTS: This will set the manager for a group and optionally allow them
' to update group membership. Set the manager by specificying the LDAP path
' or DN of the user you want to set. Set the group to modify by specifying
' the LDAP path or DN of a specific group; you can also set this to an OU
' to make bulk changes. Last, specify whether the manager can update the
' group membership by setting the True/False value.
' EXAMPLE: Modify a Specific Group's Manager and Allow Them to Update Membership
'          Dim strManager: strManager = "LDAP://CN=John Doe,OU=User,DC=domain,DC=com"
'          Dim strGroupPath: strGroupPath = "LDAP://CN=Testgroup,OU=Groups,DC=domain,DC=com"
'          Dim blnUpdateMembership: blnUpdateMembership = True
' EXAMPLE: Modify a Specific Group's Manager and Do Not Allow Them to Update Membership
'          Dim strManager: strManager = "LDAP://CN=John Doe,OU=User,DC=domain,DC=com"
'          Dim strGroupPath: strGroupPath = "LDAP://CN=Testgroup,OU=Groups,DC=domain,DC=com"
'          Dim blnUpdateMembership: blnUpdateMembership = False
' EXAMPLE: Bulk Modify All Group's Managers in an OU and Allow Them to Update Membership
'          Dim strManager: strManager = "LDAP://CN=John Doe,OU=User,DC=domain,DC=com"
'          Dim strGroupPath: strGroupPath = "LDAP://OU=Groups,DC=domain,DC=com"
'          Dim blnUpdateMembership: blnUpdateMembership = True
'=========================================================================
Option Explicit
' ------ START CONFIGURATION ------
Dim strManager: strManager = "LDAP://CN=John Doe,OU=User,DC=domain,DC=com"
Dim strGroupPath: strGroupPath = "LDAP://OU=Groups,DC=domain,DC=com"
Dim blnUpdateMembership: blnUpdateMembership = True
' ------ END CONFIGURATION ------

Dim strLogName: strLogName = Replace(WScript.ScriptName,".vbs",".txt")
Call Logger(strLogName, "", True)
Call ModifyManger(strGroupPath, strManager, blnUpdateMembership, strLogName)
Wscript.Echo "Finished"

Private Sub ModifyManger(groupPath, groupManager, groupUpdateMembership, groupLogName)

    On Error Resume Next

    'Ensure DN not ADS Path
    groupPath = Replace(groupPath,"LDAP://","",1,1,1)
    groupManager = Replace(groupManager,"LDAP://","",1,1,1)

    'Constants/Variables to Set Manager Update List Access
    Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &H5
    Const ADS_RIGHT_DS_WRITE_PROP = &H20
    Const ADS_ACEFLAG_INHERIT_ACE = &H00002 'Not Needed but Kept it here for Reference
    Const ADS_ACEFLAG_DONT_INHERIT_ACE = &H0
    Const ADS_FLAG_OBJECT_TYPE_PRESENT = &H01
    Const ADS_OBJECT_WRITE_MEMBERS = "{BF9679C0-0DE6-11D0-A285-00AA003049E2}"
    Dim objSecurityDescriptor, objDACL, objUser, objACE

    'Connect to AD
    Dim objConnection: Set objConnection = CreateObject("ADODB.Connection")
    Dim objCommand: Set objCommand = CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties("Page Size") = 1000   'Override the Return 1000 Results Default
    Const ADS_SCOPE_SUBTREE = 2
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE    'Include Sub OU's
    objCommand.CommandText = "SELECT ADsPath FROM 'LDAP://" & strGroupPath & "' WHERE objectClass='group'"
    Dim objRecordSet: Set objRecordSet = objCommand.Execute
    If Not objRecordSet.RecordCount > 0 Then
        Call Logger(groupLogName, "Error No Groups Found Quitting Script!", False)
        Exit Sub
    End If
    objRecordSet.MoveFirst
    Dim objGroup
    Do Until objRecordSet.EOF
        Call Logger(groupLogName, objRecordSet.Fields("ADsPath").Value & vbCrLf & "**********************************************", False)
        Set objGroup = GetObject(objRecordSet.Fields("ADsPath").Value)
        objGroup.Put "managedBy", groupManager
        objGroup.SetInfo
        If Err.Number <> 0 Then
            Err.Clear
            Call Logger(groupLogName, "Error Updating Manager to: " & groupManager, False)
        Else
            Call Logger(groupLogName, "Success Updating Manager to: " & groupManager, False)
            If groupUpdateMembership = True Then
                'Allow Manager to Update Member List
                Call Logger(groupLogName, "Allow Manager to Update Member List: True", False)
                Set objSecurityDescriptor = objGroup.Get("ntSecurityDescriptor")
                Set objDACL = objSecurityDescriptor.DiscretionaryACL
                Set objUser = GetObject("LDAP://" & objGroup.Get("managedBy"))
                Set objACE = CreateObject("AccessControlEntry")
                objACE.Trustee = "snapretail\" & objUser.Get("sAMAccountName")
                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
                If Err.Number <> 0 Then
                    Err.Clear
                    Call Logger(groupLogName, "Error Allowing Manager to Update Member List", False)
                Else
                    Call Logger(groupLogName, "Success Allowing Manager to Update Member List", False)
                End If
            End If
        End If

        Call Logger(groupLogName, "" & vbCrLf, False)

        objRecordSet.MoveNext

    Loop

    On Error Goto 0

End Sub

Private Sub Logger(fileName, logMessage, blnNewLog)

    On Error Resume Next

    Const ForReading = 1, ForWriting = 2, ForAppending = 8
    Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject")
    Dim scriptPath: scriptPath = Left(WScript.ScriptFullName,InstrRev(WScript.ScriptFullName,"\"))
    Dim logName
    If InStr(1,fileName,"\",1) > 0 Then
        logName = fileName
        If objFSO.DriveExists(objFSO.GetDriveName(logName)) Then
            If StrComp(objFSO.GetExtensionName(logName), "", 1) = 0 Then
                If Not objFSO.FolderExists(logName) Then
                    If objFSO.FolderExists(objFSO.GetParentFolderName(logName)) Then
                        objFSO.CreateFolder logName 'Create Folder In Current Path
                       Exit Sub
                    Else
                        Call Logger(objFSO.GetParentFolderName(logName), logMessage, blnNewLog) 'Recurse Creating Parent Folder
                       Call Logger(logName, logMessage, blnNewLog) 'Recurse Creating Current Folder
                       Exit Sub
                    End If
                End If
            Else
                If Not objFSO.FileExists(logName) Then
                    If Not objFSO.FolderExists(objFSO.GetParentFolderName(logName)) Then
                        Call Logger(objFSO.GetParentFolderName(logName), logMessage, blnNewLog)  'Recurse Creating Parent Folder
                       Call Logger(logName, logMessage, blnNewLog)  'Recurse Creating Current Folder
                   End If
                End If
            End If
        End If
    Else
        logName = scriptPath & fileName
    End If
    Dim logFile
    If blnNewLog = True Then
        Set logFile = objFSO.CreateTextFile(logName, True)
    Else
        If objFSO.FileExists(logName) Then
            Set logFile = objFSO.OpenTextFile(logName, ForAppending, True)
        Else
            Set logFile = objFSO.CreateTextFile(logName, True)
        End If
    End If
    logFile.WriteLine logMessage
    logFile.Close
    Set objFSO = Nothing

    On Error Goto 0

End Sub