Resetting inheritance flag for unprotected accounts

Resetting inheritance flag for unprotected accounts

Recently Jorge had posted about this on his blog here.
It was of real importance to me as we had recently migrated some 40 to50 domain into single domain, and searching for such account I foundcouple of thousand users. And the script mentioned in Jorge’s articleonly did 25% of job that is resetting inheritance on single useraccount. So I thought lets give it a try and automate the wholeprocess. Basic algorithm developed with the help of Jorge is

  • Find out all the nested members ofprotected groups (protgrps.txt)
  • Find out all the users and groupsaccount with admincount=1  (megalist.txt)
  • Remove accounts which are protectedaccording to protgrps.txt from megalist.txt and put into needtochange.txt
  • Feed this needtochange.txt to VBScriptwhich will set Inheritance flag and admincount=0

Also, I have made the scripts in two parts, one is finding out allunprotected accounts, and then feeding  those  account toa  vbscript  which  will take care of resetting theinheritance flag and admincount to 0. I have tried to use the toolsavailable on each DC.

So here is the first Batch file which takes care of finding all unprotected accounts and feeds that to vbscript.

REM ********************************************************
REM Objective: Find all unprotected accounts in domain
REM ********************************************************
@echo off
Title Reset Unprotected groups and users…

REM *** Put members of protected groups into protgrps.txt
Echo Collecting Protected Group membership …
dsquery group -samid “administrators” | dsget group -members -expand > protgrps.txt
dsquery group -samid “Domain Admins” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Enterprise Admins”  | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Schema Admins” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Backup Operators” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Server Operators” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Account Operators” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Print Operators” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Cert Publishers” | dsget group -members -expand >> protgrps.txt
dsquery group -samid “Replicator” | dsget group -members -expand >> protgrps.txt

REM *** Put TOP level protected groups into protgrps.txt
REM *** user account krbtgt is also protected (KB : 817433)

dsquery user -samid krbtgt >> protgrps.txt
dsquery group -samid “administrators” >> protgrps.txt
dsquery group -samid “Domain Admins”>> protgrps.txt
dsquery group -samid “Enterprise Admins” >> protgrps.txt
dsquery group -samid “Schema Admins” >> protgrps.txt
dsquery group -samid “Backup Operators”>> protgrps.txt
dsquery group -samid “Server Operators”>> protgrps.txt
dsquery group -samid “Account Operators”>> protgrps.txt
dsquery group -samid “Print Operators”>> protgrps.txt
dsquery group -samid “Cert Publishers”>> protgrps.txt
dsquery group -samid “Domain Controllers”>> protgrps.txt
dsquery group -samid “Replicator”>> protgrps.txt

REM *** Now find the groups and users with attribute admincount=1 into megalist.txt

Echo Collecting groups and users with admincount=1 …

dsquery * -filter”&(|(objectcategory=user)(objectcategory=group))(admincount=1)” -l-attr distinguishedname -limit 0 > Megalist.txt

REM *** Now search for each entry of megalist into protgrps.txt,
REM *** If not found then we should reset that entry
REM *** so put it in separate file : needtochange.txt

Echo separating groups and users who need to be unprotected …

del needtochange.txt /q /f

SETLOCAL ENABLEDELAYEDEXPANSION
for /F “Tokens=* skip=1” %%A in (megalist.txt) do (
find /i “%%A” protgrps.txt >nul
if !ERRORLEVEL! neq 0 echo %%A >> needtochange.txt
)

REM *** Now we will feed this needtochange.txt to our VBScript,
REM *** which will set inheritance flag and admincount=0

Echo Setting inheritance flag and admincount=0 …

cscript ResetUnprotected.vbs needtochange.txt

Echo Done

Now comes the vbscript code

‘********************************************************************
‘*
‘* File:           ResetUnprotected.vbs
‘* Created:        November 2005
‘* Version:        1.0
‘*
‘*  Main Function:  For all accounts specified in argument file
‘*  enables the inheritance flag and Resets admincount to 0
‘*
‘********************************************************************

Const SE_DACL_PROTECTED = 4096

On Error Resume Next

‘// Verify command line argument is provided

If WScript.Arguments.Count <> 1 Then
    WScript.Echo “ERROR: No filename specified as command line argument”
    WScript.Quit 1
Else
‘// Read content of the file specified on commandline and put its content in Array
    Dim oFile, oFSO,ArrObjects
    Set oFSO = CreateObject(“scripting.filesystemobject”)
    set oFile = oFSO.OpenTextFile (WScript.Arguments.Item(0),1)
    ArrObjects = split(oFile.ReadAll,VbCrLf)
End If

For Each strADsPath In ArrObjects
    WScript.Echo  “found account ” & strADsPath
    If SetInheritanceFlag(Trim(strADsPath)) = 0 Then WScript.Echo “Inheritance flag set”
    If SetAdminCount(Trim(strADsPath), 0) = 0 Then WScript.Echo “adminCount set to 0”
    WScript.Echo  “==========================================”
Next

‘// ***********************************************************
Private Function SetInheritanceFlag(DSObjectPath)
‘// ***********************************************************
    Dim oSD, oDACL, lFlag, oIADs

    Set oIADs = GetObject(“LDAP://”&DSObjectPath)

    Set oSD = oIADs.Get(“nTSecurityDescriptor”)

    If oSD.Control And SE_DACL_PROTECTED Then
        oSD.Control = oSD.Control + SE_DACL_PROTECTED
    End If

    oIADs.Put “nTSecurityDescriptor”, oSD
    oIADs.SetInfo

    If Err.Number <> 0 Then
        SetInheritanceFlag = Err.Number
    Else
        SetInheritanceFlag = 0
    End If

End Function

‘// ***********************************************************
Private Function SetAdminCount(DSObjectPath, AdminCoun)
‘// ***********************************************************
    Dim oIADs, iAdminCount

    Set oIADs = GetObject(“LDAP://”&DSObjectPath)

    iAdminCount = oIADs.Get(“adminCount”)

    If iAdminCount = 1 Then iAdminCount = 0

    oIADs.Put “adminCount”, iAdminCount
    oIADs.SetInfo
    If Err.Number <> 0 Then
        SetAdminCount = Err.Number
    Else
        SetAdminCount = 0
    End If

End Function

Notes

Leave a Reply

Your email address will not be published. Required fields are marked *