Get-DsAcl
The goal of this PowerShell function is to create a report of permissions assigned to objects in Active Directory in much the same way as DsRevoke.
The names for extended rights and object types are read from the schema allowing the script to display friendly names.
Properties
| Property | Description |
|---|---|
| Name | The name of the Object; by default this will be an OU, but I made this configurable (see examples). |
| DN | The DN of the Object; equivalent to Object (DsRevoke) |
| ObjectClass | Object class |
| SecurityPrincipal | The User or Group (or Computer) the Access Control Entry is for; used as the search using DsRevoke |
| AccessType | Allow or Deny; equivalent to ACE Type |
| Permissions | Same as Permissions list in DsRevoke |
| AppliesTo | What the ACE applies to; equivalent to “ACE inherited by all child objects” entry |
| AppliesToObjectType | The object class the ACE applies to; equivalent to “ACE inherited by all child objects of Class …” |
| AppliesToProperty | The specific property or Property Set an ACE applies to, or the Extended Right an ACE grants (if defined) |
| Inherited | True if the Access Control Entry was inherited. Only applies with -Inherited switch. |
Usage examples
Standard output (reporting on organizational units in the current domain):
Get-DsAcl
Format Table:
Get-DsAcl | Format-Table
Store in a variable:
ACLs = Get-DsAcl
Export to CSV:
Get-DsAcl | Export-CSV "Rights.csv"
Reporting on User objects:
Get-DsAcl -ObjectType "user"
Reporting on a sub-OU:
Get-DsAcl "OU=Test,DC=domain,DC=com" # Or Get-DsAcl -SearchRoot "OU=Test,DC=domain,DC=com"
Reporting on contacts in a sub-OU:
Get-DsAcl "OU=Test,DC=domain,DC=com" -ObjectType "contact"
Using a custom LDAP filter:
Get-DsAcl -LdapFilter "(objectClass=*)"
Including Inherited entries:
Get-DsAcl -LdapFilter "(name=Chris Dent)" -Inherited | Format-Table
Get-DsAcl
Function Get-DSACL {
# Function to list permissions assigned to objects in Active Directory
# This function reports on organizationalUnits within the domain by default.
Param(
$SearchRoot = ([ADSI]"LDAP://RootDSE").Get("defaultNamingContext"),
$ObjectType = "organizationalUnit",
$LdapFilter = "(&(objectClass=$ObjectType)(objectCategory=$ObjectType))",
[Switch]$Inherited = $False
)
# Set the output field separator (default is " ")
$OFS = "\"
# Connect to RootDSE
$RootDSE = [ADSI]"LDAP://RootDSE"
# Connect to the Schema
$Schema = [ADSI]"LDAP://$($RootDSE.Get('schemaNamingContext'))"
# Connect to the Extended Rights container
$Configuration = $RootDSE.Get("configurationNamingContext")
$ExtendedRights = [ADSI]"LDAP://CN=Extended-Rights,$Configuration"
# Find objects based on $SearchRoot and $ObjectType
$Searcher = New-Object DirectoryServices.DirectorySearcher(`
[ADSI]"LDAP://$SearchRoot", `
$LdapFilter)
$Searcher.FindAll() | %{
$Object = $_.GetDirectoryEntry()
# Retrieve all Access Control Entries from the AD Object
$ACL = $Object.PsBase.ObjectSecurity.GetAccessRules(`
$True, `
$Inherited, `
[Security.Principal.NTAccount])
# Get interesting values
$ACL | Select-Object @{n='Name';e={ $Object.Get("name") }}, `
@{n='DN';e={ $Object.Get("distinguishedName") }}, `
@{n='ObjectClass';e={ $Object.Class }}, `
@{n='SecurityPrincipal';e={ $_.IdentityReference.ToString() }}, `
@{n='AccessType';e={ $_.AccessControlType }}, `
@{n='Permissions';e={ $_.ActiveDirectoryRights }}, `
@{n='AppliesTo';e={
#
# Change the values for InheritanceType to friendly names
#
Switch ($_.InheritanceType) {
"None" { "This object only" }
"Descendents" { "All child objects" }
"SelfAndChildren" { "This object and one level Of child objects" }
"Children" { "One level of child objects" }
"All" { "This object and all child objects" }
} }}, `
@{n='AppliesToObjectType';e={
If ($_.InheritedObjectType.ToString() -NotMatch "0{8}.*") {
#
# Search for the Object Type in the Schema
#
$LdapFilter = `
"(SchemaIDGUID=\$($_.InheritedObjectType.ToByteArray() | `
%{ '{0:X2}' -f $_ }))"
$Result = (New-Object DirectoryServices.DirectorySearcher(`
$Schema, $LdapFilter)).FindOne()
$Result.Properties["ldapdisplayname"]
} Else { "All" } }}, `
@{n='AppliesToProperty';e={
If ($_.ObjectType.ToString() -NotMatch "0{8}.*") {
#
# Search for a possible Extended-Right or Property Set
#
$LdapFilter = "(rightsGuid=$($_.ObjectType.ToString()))"
$Result = (New-Object DirectoryServices.DirectorySearcher(`
$ExtendedRights, $LdapFilter)).FindOne()
If ($Result) {
$Result.Properties["displayname"]
} Else {
#
# Search for the attribute name in the Schema
#
$LdapFilter = "(SchemaIDGUID=\$($_.ObjectType.ToByteArray() | `
%{ '{0:X2}' -f $_ }))"
$Result = (New-Object DirectoryServices.DirectorySearcher(`
$Schema, $LdapFilter)).FindOne()
$Result.Properties["ldapdisplayname"]
}
} Else { "All" } }}, `
@{n='Inherited';e={ $_.IsInherited }}
}
}
Related posts:
- Changing the Primary Group with PowerShell Exactly as the title says, an example of how to...
- Accept or reject messages from This function reads delivery restrictions from objects in Active Directory....
- Building LDAP filters for date based attributes Active Directory contains a number of attributes which hold date...
Related posts brought to you by Yet Another Related Posts Plugin.
Respond to this post