0
votes

For auditing purposes we want to query the Active Directory to determine whether higher risk delegated access rights are assigned via OUs, Groups or Users.

We developed a Powershell script which does exactly that, however, we are running into performance issues and we would like to optimize the script.

$objectList = (Get-ADObject -Filter 'ObjectClass -eq "organizationalUnit" -or ObjectClass -eq "group" -or ObjectClass -eq "user"')

ForEach($object in $objectList){
    $delegated_rights += (Get-Acl -Path "AD:\$object" |
         Select-Object -ExpandProperty Access).Where({($_.objectType.ToString() -eq '00000000-0000-0000-0000-000000000000' <# All #>`
         -or $_.objectType.ToString() -eq 'bf967aba-0de6-11d0-a285-00aa003049e2' <# User #>`
         -or $_.objectType.ToString() -eq '00299570-246d-11d0-a768-00aa006e0529' <# User-Force-Change-Password #>`
         -or $_.objectType.ToString() -eq 'bf967a9c-0de6-11d0-a285-00aa003049e2' <# Group #>`
         -or $_.objectType.ToString() -eq 'f30e3bbe-9ff0-11d1-b603-0000f80367c1' <# GP-Link #>`
         -or $_.objectType.ToString() -eq 'f30e3bbf-9ff0-11d1-b603-0000f80367c1' <# GP-Options #>`
         -or ($_.objectType.ToString() -eq 'bf9679c0-0de6-11d0-a285-00aa003049e2'-and $_.inheritedObjectType -eq 'bf967a9c-0de6-11d0-a285-00aa003049e2') <# Member in combination with Group #> )}) | 

         Select-Object @{name='Type';expression={'Object'}}, `
                       @{name='DistinguishedName';expression={$object}}, `
                       @{name='objectTypeName';expression={$schemaIDGUID.Item($_.objectType)}}, `
                       @{name='inheritedObjectTypeName';expression={$schemaIDGUID.Item($_.inheritedObjectType)}}, `
                       *
    }

On larger Active Directories the above code takes too long to perform. How can we improve the logic to make it more efficient?

1
As a start I would avoid all the "toString" operations, and next I would get rid of the -or. Construct actual GUID objects up-front so you can compare for equality without conversations, put them in an array, and use an .IndexOf($_.objectType) to find out if there are any hits.Tomalak
*without conversions, I meant to say.Tomalak

1 Answers

0
votes

If this works exactly as you need it but is just slow you might want to look at trying a powershell workflow, which will allow for a parallel foreach. This is also probably a micro optimization at best but it might not hurt to try making all of those strings into an array and using -contains against $_.objectType.ToString(), could shave off some time.