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
Solved

Script that will remove all Managed by from all groups in the Domain.Active directory.

Posted on 2008-10-31
14
559 Views
Last Modified: 2012-06-27
Hi,

Script that will remove all Managed by from all groups in the Domain.Active directory.
Below is the script that removes the managed by for all Computers can the same be changed for the groups. Just though this might help.

Regards
Sharath
:: ===============
:: READ THIS FIRST
:: ===============
:: * This script require "Computers.txt" file from where it will pick computer names.
:: * Copy and paste following script in notepad and save it with any name having .cmd extension.
:: *** SCRIPT START ***
@ECHO OFF
SETLOCAL EnableDelayedExpansion
IF NOT EXIST Computers.txt GOTO ShowErr
FOR %%R IN (Computers.txt) DO IF %%~zR EQU 0 GOTO ShowErr
IF EXIST CompMgr.ldf DEL /F /Q CompMgr.ldf
 
FOR /F %%c IN ('TYPE Computers.txt') Do (
    ECHO Processing: %%c
    DSQuery Computer -Name %%c |FIND /I "CN=">NUL
    IF NOT ERRORLEVEL 1 (
            FOR /F "delims=*" %%d IN ('DSQuery Computer -Name %%c') DO ((
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO replace: managedBy
                  ECHO managedBy: %%~d
                  ECHO -
                  ECHO.
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO delete: managedBy
                  ECHO -
                  ECHO.)>>CompMgr.ldf)
      ) ELSE (ECHO *** ERROR *** %%c: System NOT Found in AD.)
)
ECHO.
IF EXIST CompMgr.ldf LDIFDE -I -K -F CompMgr.ldf
GOTO EndScript
:ShowErr
ECHO "Computers.txt" file does not exist or file is empty!
:EndScript
IF EXIST CompMgr.ldf DEL /F /Q CompMgr.ldf
ENDLOCAL
:: *** SCRIPT END ***

Open in new window

0
Comment
Question by:bsharath
  • 7
  • 5
  • 2
14 Comments
 
LVL 58

Expert Comment

by:tigermatt
ID: 22861366

Well, that should be quite simple by just changing what DSQuery is looking up. I've also changed the input file so it now accepts groups.txt as the input file.

-Matt
:: ===============
:: READ THIS FIRST
:: ===============
:: * This script require "Groups.txt" file from where it will pick group names.
:: * Copy and paste following script in notepad and save it with any name having .cmd extension.
:: *** SCRIPT START ***
@ECHO OFF
SETLOCAL EnableDelayedExpansion
IF NOT EXIST Groups.txt GOTO ShowErr
FOR %%R IN (Groups.txt) DO IF %%~zR EQU 0 GOTO ShowErr
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
 
FOR /F %%c IN ('TYPE Groups.txt') Do (
    ECHO Processing: %%c
    DSQuery Group -Name %%c |FIND /I "CN=">NUL
    IF NOT ERRORLEVEL 1 (
            FOR /F "delims=*" %%d IN ('DSQuery Computer -Name %%c') DO ((
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO replace: managedBy
                  ECHO managedBy: %%~d
                  ECHO -
                  ECHO.
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO delete: managedBy
                  ECHO -
                  ECHO.)>>GroupMgr.ldf)
      ) ELSE (ECHO *** ERROR *** %%c: Group NOT Found in AD.)
)
ECHO.
IF EXIST GroupMgr.ldf LDIFDE -I -K -F GroupMgr.ldf
GOTO EndScript
:ShowErr
ECHO "Groups.txt" file does not exist or file is empty!
:EndScript
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
ENDLOCAL
:: *** SCRIPT END ***

Open in new window

0
 
LVL 58

Expert Comment

by:tigermatt
ID: 22861373

Oops, forgot to replace a token! Try this:

-Matt
:: ===============
:: READ THIS FIRST
:: ===============
:: * This script require "Groups.txt" file from where it will pick group names.
:: * Copy and paste following script in notepad and save it with any name having .cmd extension.
:: *** SCRIPT START ***
@ECHO OFF
SETLOCAL EnableDelayedExpansion
IF NOT EXIST Groups.txt GOTO ShowErr
FOR %%R IN (Groups.txt) DO IF %%~zR EQU 0 GOTO ShowErr
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
 
FOR /F %%c IN ('TYPE Groups.txt') Do (
    ECHO Processing: %%c
    DSQuery Group -Name %%c |FIND /I "CN=">NUL
    IF NOT ERRORLEVEL 1 (
            FOR /F "delims=*" %%d IN ('DSQuery Group -Name %%c') DO ((
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO replace: managedBy
                  ECHO managedBy: %%~d
                  ECHO -
                  ECHO.
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO delete: managedBy
                  ECHO -
                  ECHO.)>>GroupMgr.ldf)
      ) ELSE (ECHO *** ERROR *** %%c: Group NOT Found in AD.)
)
ECHO.
IF EXIST GroupMgr.ldf LDIFDE -I -K -F GroupMgr.ldf
GOTO EndScript
:ShowErr
ECHO "Groups.txt" file does not exist or file is empty!
:EndScript
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
ENDLOCAL
:: *** SCRIPT END ***

Open in new window

0
 
LVL 14

Expert Comment

by:rejoinder
ID: 22892811
This will loop through all domains in the forest and remove the managed by field from any group.
'http://www.experts-exchange.com/Programming/Languages/Q_23866168.html
 
Const adVarChar = 200
Const VarCharMaxCharacters = 255
Const adFldIsNullable = 32
 
Dim arrDomainNames
 
'Uncomment the next line to input your own domain names
'arrDomainNames = array("DOMAIN","DC=subdomain1,DC=domain,DC=com")
 
if NOT IsArray(arrDomainNames) then
    GetDomainNames
End If
 
Sub GetDomainNames
    Const ADS_SCOPE_ONELEVEL = 1
    Const ADS_SCOPE_SUBTREE = 2
    set objRootDSE   = GetObject("LDAP://RootDSE")
    Set objCommand =   CreateObject("ADODB.Command")
    set objConn      = CreateObject("ADODB.Connection")
    objConn.Provider = "ADsDSOObject"
    
    objConn.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConn
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_ONELEVEL
    
    objCommand.CommandText = "SELECT name,trustParent,nCName,dnsRoot,distinguishedName FROM 'LDAP://cn=Partitions," & objRootDSE.Get("ConfigurationNamingContext") & "' WHERE objectcategory='crossRef' AND systemFlags=3"
    Set objRS = objCommand.Execute
    objRS.MoveFirst
    
    set arrDomainNames     = CreateObject("Scripting.Dictionary")
    set dicDomainHierarchy = CreateObject("Scripting.Dictionary")
    set dicDomainRoot      = CreateObject("Scripting.Dictionary")
    
    while not objRS.EOF 
        dicDomainRoot.Add objRS.Fields("name").Value, objRS.Fields("nCName").Value
        if objRS.Fields("trustParent").Value <> "" then
            arrDomainNames.Add objRS.Fields("name").Value, 0
            set objDomainParent = GetObject("LDAP://" & objRS.Fields("trustParent").Value)
            dicDomainHierarchy.Add objRS.Fields("name").Value,objDomainParent.Get("name")
        else 
            arrDomainNames.Add objRS.Fields("name").Value, 1
        end if
        objRS.MoveNext
    wend
    for each strDomain in arrDomainNames
        'msgbox strDomain
    next
End Sub
 
Set GroupMembershipDB = CreateObject("ADOR.Recordset")
GroupMembershipDB.Fields.Append "SAMAccountName", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "PrimaryGroupToken", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "DistinguishedName", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "Type", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Open
 
'Run sub to populate the group members db
FillGroupList
 
RemoveManagedBy
 
Sub FillGroupList
    Set adoCommandGL = CreateObject("ADODB.Command")
    Set adoConnectionGL = CreateObject("ADODB.Connection")
    adoConnectionGL.Provider = "ADsDSOObject"
    adoConnectionGL.Open "Active Directory Provider"
    adoCommandGL.ActiveConnection = adoConnectionGL
    adoCommandGL.Properties("Page Size") = 1000
 
    for each strDomain in arrDomainNames
        strBase = "<LDAP://" & strDomain & ">"        
        strFilter = "(objectCategory=group)"
        strAttributes = "sAMAccountName,primaryGroupToken,distinguishedName,samaccounttype,member,managedby,mail"
        strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
        Set adoRecordsetGL = CreateObject("ADODB.Recordset")
        adoRecordsetGL.CursorLocation = 3
        adoRecordsetGL.Sort = "distinguishedname"
        adoRecordsetGL.Open strQuery, adoConnectionGL, , , 1
        Do Until adoRecordsetGL.EOF
            strNTName            = adoRecordsetGL.Fields("sAMAccountName").Value
            strPrimary           = adoRecordsetGL.Fields("primaryGroupToken").Value
            strdistinguishedName = adoRecordsetGL.Fields("distinguishedName").Value
            strType              = GroupType(adoRecordsetGL.Fields("samaccounttype").Value)
            GroupMembershipDB.AddNew
            GroupMembershipDB("sAMAccountName")          = strNTName
            GroupMembershipDB("primaryGroupToken")       = strPrimary
            GroupMembershipDB("distinguishedName")       = strdistinguishedName
            GroupMembershipDB("Type")                    = strType
            GroupMembershipDB.Update
            adoRecordsetGL.MoveNext
        Loop
    next
End Sub
 
Function GroupType(strType)
    Select Case strType
        Case 2,268435457,4,536870913,8,268435457 'Distribution Groups
            GroupType = "Distribution Group"
        Case -2147483646,268435456,-2147483644,536870912,-2147483640,268435456 'Security Groups
            GroupType = "Security Group"
        Case Else
            GroupType = "Security Group"
    End Select
End Function
 
Sub RemoveManagedBy
    GroupMembershipDB.Filter = ""
    GroupMembershipDB.MoveFirst
    Do While Not GroupMembershipDB.EOF
        strDN = GroupMembershipDB.Fields.Item("distinguishedName").Value
        Set objGroup = GetObject("LDAP://" & strDN)
        objGroup.PutEx 1, "managedby", vbNullString
        objGroup.SetInfo
        GroupMembershipDB.MoveNext
    Loop
End Sub
 
wscript.echo "Done"

Open in new window

0
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 
LVL 11

Author Comment

by:bsharath
ID: 22893090
Will i get in the results on what was removed Matthew & Rejoinder in both the scripts?
0
 
LVL 11

Author Comment

by:bsharath
ID: 22893091
Will i get in the results on what was removed Matthew & Rejoinder in both the scripts?
0
 
LVL 14

Assisted Solution

by:rejoinder
rejoinder earned 100 total points
ID: 22897273
Mine didn't but this version does.
'http://www.experts-exchange.com/Programming/Languages/Q_23866168.html
 
Const adVarChar = 200
Const VarCharMaxCharacters = 255
Const adFldIsNullable = 32
 
strFile     = "remove-managedby-log.txt"
Set objFSO  = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, 2, True)
 
Dim arrDomainNames
 
'Uncomment the next line to input your own domain names
'arrDomainNames = array("DOMAIN","DC=subdomain1,DC=domain,DC=com")
 
if NOT IsArray(arrDomainNames) then
    GetDomainNames
End If
 
Sub GetDomainNames
    Const ADS_SCOPE_ONELEVEL = 1
    Const ADS_SCOPE_SUBTREE = 2
    set objRootDSE   = GetObject("LDAP://RootDSE")
    Set objCommand =   CreateObject("ADODB.Command")
    set objConn      = CreateObject("ADODB.Connection")
    objConn.Provider = "ADsDSOObject"
    
    objConn.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConn
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_ONELEVEL
    
    objCommand.CommandText = "SELECT name,trustParent,nCName,dnsRoot,distinguishedName FROM 'LDAP://cn=Partitions," & objRootDSE.Get("ConfigurationNamingContext") & "' WHERE objectcategory='crossRef' AND systemFlags=3"
    Set objRS = objCommand.Execute
    objRS.MoveFirst
    
    set arrDomainNames     = CreateObject("Scripting.Dictionary")
    set dicDomainHierarchy = CreateObject("Scripting.Dictionary")
    set dicDomainRoot      = CreateObject("Scripting.Dictionary")
    
    while not objRS.EOF 
        dicDomainRoot.Add objRS.Fields("name").Value, objRS.Fields("nCName").Value
        if objRS.Fields("trustParent").Value <> "" then
            arrDomainNames.Add objRS.Fields("name").Value, 0
            set objDomainParent = GetObject("LDAP://" & objRS.Fields("trustParent").Value)
            dicDomainHierarchy.Add objRS.Fields("name").Value,objDomainParent.Get("name")
        else 
            arrDomainNames.Add objRS.Fields("name").Value, 1
        end if
        objRS.MoveNext
    wend
    for each strDomain in arrDomainNames
        'msgbox strDomain
    next
End Sub
 
Set GroupMembershipDB = CreateObject("ADOR.Recordset")
GroupMembershipDB.Fields.Append "SAMAccountName", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "PrimaryGroupToken", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "DistinguishedName", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Fields.Append "Type", adVarChar, VarCharMaxCharacters, adFldIsNullable
GroupMembershipDB.Open
 
'Run sub to populate the group members db
FillGroupList
 
RemoveManagedBy
 
Sub FillGroupList
    Set adoCommandGL = CreateObject("ADODB.Command")
    Set adoConnectionGL = CreateObject("ADODB.Connection")
    adoConnectionGL.Provider = "ADsDSOObject"
    adoConnectionGL.Open "Active Directory Provider"
    adoCommandGL.ActiveConnection = adoConnectionGL
    adoCommandGL.Properties("Page Size") = 1000
 
    for each strDomain in arrDomainNames
        strBase = "<LDAP://" & strDomain & ">"        
        strFilter = "(objectCategory=group)"
        strAttributes = "sAMAccountName,primaryGroupToken,distinguishedName,samaccounttype,member,managedby,mail"
        strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
        Set adoRecordsetGL = CreateObject("ADODB.Recordset")
        adoRecordsetGL.CursorLocation = 3
        adoRecordsetGL.Sort = "distinguishedname"
        adoRecordsetGL.Open strQuery, adoConnectionGL, , , 1
        Do Until adoRecordsetGL.EOF
            strNTName            = adoRecordsetGL.Fields("sAMAccountName").Value
            strPrimary           = adoRecordsetGL.Fields("primaryGroupToken").Value
            strdistinguishedName = adoRecordsetGL.Fields("distinguishedName").Value
            strType              = GroupType(adoRecordsetGL.Fields("samaccounttype").Value)
            GroupMembershipDB.AddNew
            GroupMembershipDB("sAMAccountName")          = strNTName
            GroupMembershipDB("primaryGroupToken")       = strPrimary
            GroupMembershipDB("distinguishedName")       = strdistinguishedName
            GroupMembershipDB("Type")                    = strType
            GroupMembershipDB.Update
            adoRecordsetGL.MoveNext
        Loop
    next
End Sub
 
Function GroupType(strType)
    Select Case strType
        Case 2,268435457,4,536870913,8,268435457 'Distribution Groups
            GroupType = "Distribution Group"
        Case -2147483646,268435456,-2147483644,536870912,-2147483640,268435456 'Security Groups
            GroupType = "Security Group"
        Case Else
            GroupType = "Security Group"
    End Select
End Function
 
Sub RemoveManagedBy
    objFile.WriteLine """GROUP"",""MANAGER"""
    GroupMembershipDB.Filter = ""
    GroupMembershipDB.MoveFirst
    Do While Not GroupMembershipDB.EOF
        strDN = GroupMembershipDB.Fields.Item("distinguishedName").Value
        Set objGroup = GetObject("LDAP://" & strDN)
        strManagedBy = objGroup.managedby
        if strManagedBy <> "" then
            objFile.WriteLine """" & strDN & """,""" & strManagedBy & """"
            objGroup.PutEx 1, "managedby", vbNullString
            objGroup.SetInfo
        end if
        GroupMembershipDB.MoveNext
    Loop
End Sub
 
wscript.echo "Done"

Open in new window

0
 
LVL 58

Expert Comment

by:tigermatt
ID: 22907983

Sharath,

Apologies- I've not been in the office for days.

The script I posted is a copy of the original one you posted in the question, except I obviously changed it to search and process groups, instead of computers. If the original script shows results, my script will; it looks like it does.

-Matthew
0
 
LVL 11

Author Comment

by:bsharath
ID: 22911781
Matthew the script does not query if the group name has spaces...

Rejoinder your script also does not remove managers if groups have spaces...
0
 
LVL 11

Author Comment

by:bsharath
ID: 22911782
Matthew the script does not query if the group name has spaces...

Rejoinder your script also does not remove managers if groups have spaces...
0
 
LVL 58

Expert Comment

by:tigermatt
ID: 22911792

Sharath,

Try this.

-Matt
:: ===============
:: READ THIS FIRST
:: ===============
:: * This script require "Groups.txt" file from where it will pick group names.
:: * Copy and paste following script in notepad and save it with any name having .cmd extension.
:: *** SCRIPT START ***
@ECHO OFF
SETLOCAL EnableDelayedExpansion
IF NOT EXIST Groups.txt GOTO ShowErr
FOR %%R IN (Groups.txt) DO IF %%~zR EQU 0 GOTO ShowErr
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
 
FOR /F %%c IN ('TYPE Groups.txt') Do (
    ECHO Processing: %%c
    DSQuery Group -Name "%%c" |FIND /I "CN=">NUL
    IF NOT ERRORLEVEL 1 (
            FOR /F "delims=*" %%d IN ('DSQuery Group -Name "%%c"') DO ((
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO replace: managedBy
                  ECHO managedBy: %%~d
                  ECHO -
                  ECHO.
                  ECHO DN: %%~d
                  ECHO changetype: modify
                  ECHO delete: managedBy
                  ECHO -
                  ECHO.)>>GroupMgr.ldf)
      ) ELSE (ECHO *** ERROR *** %%c: Group NOT Found in AD.)
)
ECHO.
IF EXIST GroupMgr.ldf LDIFDE -I -K -F GroupMgr.ldf
GOTO EndScript
:ShowErr
ECHO "Groups.txt" file does not exist or file is empty!
:EndScript
IF EXIST GroupMgr.ldf DEL /F /Q GroupMgr.ldf
ENDLOCAL
:: *** SCRIPT END ***

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 22911813
Still says cannot be found

Processing: LC
*** ERROR *** LC: Group NOT Found in AD.
0
 
LVL 58

Accepted Solution

by:
tigermatt earned 400 total points
ID: 22912150

Sharath,

I've completely rewritten this from scratch. It is now a .VBS script, and looks for the group names in C:\groups.txt.

Hopefully this one will work much better ;-)

-Matthew
Const ADS_PROPERTY_CLEAR = 1
 
' Read in file
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim groups: Set groups = fso.OpenTextFile("C:\groups.txt")
 
' Create ADO connection
Dim ado: Set ado = CreateObject("ADODB.Connection")
With ado
  .Provider="ADSDSoObject"
  .Open "ADs Provider"
End With
 
Dim objrootdse: Set objrootdse = Getobject("LDAP://rootDSE")
Dim dn: dn = objrootdse.Get("defaultNamingContext")
 
Do While Not groups.AtEndOfStream
  line = groups.ReadLine
  Set rs = CreateObject("ADODB.Recordset")
  rs.Open "SELECT distinguishedName FROM 'LDAP://" & dn & "' WHERE name = '" & line & "'", ado
  If (Not rs.BOF And Not rs.EOF) Then
    Set objGroup = GetObject("LDAP://" & rs.Fields("distinguishedname").value)
    objGroup.PutEx ADS_PROPERTY_CLEAR, "managedBy", 0
    objGroup.SetInfo
    WScript.Echo "*Cleared Managed By attribute for: " & objGroup.name
  End If
 
Loop

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 22912268
Thank U Both
0
 
LVL 11

Author Comment

by:bsharath
ID: 22912269
Thank U Both
0

Featured Post

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

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

Suggested Solutions

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
This article will show, step by step, how to integrate R code into a R Sweave document
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

839 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