ActiveDirectoryRights : CreateChild, DeleteChild
InheritanceType : None
ObjectType : bf967aa8-0de6-11d0-a285-00aa003049e2
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : S-1-5-32-550
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Here, you can see many of the enumerations are decoded into text, but we have guid's and SID's that may show up without translation. With BSonPosh, there is a function for converting SID's already, though in this case I'm modifying it to handle SID's that do not translate with that code. Combining that with another helper function to decode the GUID's to the ldap display attribute listed in the schema, you can get a result that is more readable like this:
Get-ADACL -distinguishedname "dc=contoso,dc=com" | convert-adacl
ActiveDirectoryRights : ReadProperty, WriteProperty, Delete
InheritanceType : Descendents
ObjectType : msRTCSIP-UserPolicies
InheritedObjectType : user
ObjectFlags : ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType : Allow
IdentityReference : CONTOSO\RTCDomainUserAdmins
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : InheritOnly
Below is the code. One function was changed (ConvertTO-Name). The rest is added to BSActiveDirectory.psm1. It is important to note, that this conversion function creates its own custom PSobject, so it is not longer an ACL that you can play with and try to write back. This was more designed for auditing purposes.
#region Convert-ADACL function Convert-ADACL { <# .Synopsis Translates the AD Object ACL to a more readable format by converting SID and GUID values to text .Description Translates the AD Object ACL to a more readable format by converting SID and GUID values to tex .Parameter ACL ACL Object to Apply .OUTPUTS Object #> [cmdletbinding()] Param( [Parameter(ValueFromPipeline=$true)] [System.DirectoryServices.ActiveDirectoryAccessRule]$ACL ) Begin { $results = @() } process { if ($_.ActiveDirectoryRights -eq "ExtendedRight") { $myresult = New-Object PSobject -Property @{ ActiveDirectoryRights = $_.ActiveDirectoryRights InheritanceType = $_.InheritanceType ObjectType = Convert-GUIDToName -guid $_.objecttype -extended
InheritedObjectType = Convert-GUIDToName -guid $_.inheritedobjecttype ObjectFlags = $_.ObjectFlags AccessControlType = $_.accesscontroltype IdentityReference = ConvertTo-Name -sid $_.identityReference IsInherited = $_.isinherited InheritanceFlags = $_.InheritanceFlags PropagationFlags = $_.PropagationFlags } } else { $myresult = New-Object PSobject -Property @{ ActiveDirectoryRights = $_.ActiveDirectoryRights InheritanceType = $_.InheritanceType ObjectType = Convert-GUIDToName -guid $_.objecttype InheritedObjectType = Convert-GUIDToName -guid $_.inheritedobjecttype
ObjectFlags = $_.ObjectFlags AccessControlType = $_.accesscontroltype IdentityReference = ConvertTo-Name -sid $_.identityReference IsInherited = $_.isinherited InheritanceFlags = $_.InheritanceFlags PropagationFlags = $_.PropagationFlags } } $results += $Myresult } end { $results |Select-Object ActiveDirectoryRights,InheritanceType,ObjectType,InheritedObjectType,ObjectFlags,` AccessControlType,IdentityReference,IsInherited,InheritanceFlags,PropagationFlags } } #endregion #region ConvertTo-Name function ConvertTo-Name { param($sid) Write-Verbose $sid try { $ID = New-Object System.Security.Principal.SecurityIdentifier($sid) $User = $ID.Translate( [System.Security.Principal.NTAccount]) $User.Value } catch { switch($sid) { #Reference http://support.microsoft.com/kb/243330 "S-1-0" { "Null Authority" } "S-1-0-0" { "Nobody" } "S-1-1" {"World Authority" } "S-1-1-0" { "Everyone" } "S-1-2" { "Local Authority" } "S-1-2-0" { "Local" } "S-1-2-1" { "Console Logon" } "S-1-3" { "Creator Authority" } "S-1-3-0" { "Creator Owner" } "S-1-3-1" { "Creator Group" } "S-1-3-4" { "Owner Rights" } "S-1-5-80-0" {"All Services" } "S-1-4" { "Non Unique Authority" } "S-1-5" { "NT Authority" } "S-1-5-1" { "Dialup" } "S-1-5-2" { "Network" } "S-1-5-3" { "Batch" } "S-1-5-4" { "Interactive" } "S-1-5-6" { "Service" } "S-1-5-7" { "Anonymous" } "S-1-5-9" { "Enterprise Domain Controllers"} "S-1-5-10" { "Self" } "S-1-5-11" { "Authenticated Users" } "S-1-5-12" { "Restricted Code" } "S-1-5-13" { "Terminal Server Users" } "S-1-5-14" { "Remote Interactive Logon" } "S-1-5-15" { "This Organization" } "S-1-5-17" { "This Organization" } "S-1-5-18" { "Local System" } "S-1-5-19" { "NT Authority Local Service" } "S-1-5-20" { "NT Authority Network Service" } "S-1-5-32-544" { "Administrators" } "S-1-5-32-545" { "Users"} "S-1-5-32-546" { "Guests" } "S-1-5-32-547" { "Power Users" } "S-1-5-32-548" { "Account Operators" } "S-1-5-32-549" { "Server Operators" } "S-1-5-32-550" { "Print Operators" } "S-1-5-32-551" { "Backup Operators" } "S-1-5-32-552" { "Replicators" } "S-1-5-32-554" { "Pre-Windows 2000 Compatibility Access"} "S-1-5-32-555" { "Remote Desktop Users"} "S-1-5-32-556" { "Network Configuration Operators"} "S-1-5-32-557" { "Incoming forest trust builders"} "S-1-5-32-558" { "Performance Monitor Users"} "S-1-5-32-559" { "Performance Log Users" } "S-1-5-32-560" { "Windows Authorization Access Group"} "S-1-5-32-561" { "Terminal Server License Servers"} "S-1-5-32-561" { "Distributed COM Users"} "S-1-5-32-569" { "Cryptographic Operators" } "S-1-5-32-573" { "Event Log Readers" } "S-1-5-32-574" { "Certificate Services DCOM Access" } "S-1-5-32-575" { "RDS Remote Access Servers" } "S-1-5-32-576" { "RDS Endpoint Servers" } "S-1-5-32-577" { "RDS Management Servers" } "S-1-5-32-575" { "Hyper-V Administrators" } "S-1-5-32-579" { "Access Control Assistance Operators" } "S-1-5-32-580" { "Remote Management Users" } default {$sid} } } } #endregion #region Convert-GUIDToName #helper module to convert schema GUID's to readable names function Convert-GUIDToName { param( [parameter(mandatory=$true)][string]$guid, [switch]$extended ) $guidval = [Guid]$guid $bytearr = $guidval.tobytearray() $bytestr = "" foreach ($byte in $bytearr) { $str = "\" + "{0:x}" -f $byte $bytestr += $str } if ($extended) { #for extended rights, we can check in the configuration container $de = new-object directoryservices.directoryentry("LDAP://" + ([adsi]"LDAP://rootdse").psbase.properties.configurationnamingcontext) $ds = new-object directoryservices.directorysearcher($de) $ds.propertiestoload.add("displayname")|Out-Null $ds.filter = "(rightsguid=$guid)" $result = $ds.findone() } else { #Search schema for possible matches for this GUID $de = new-object directoryservices.directoryentry("LDAP://" + ([adsi]"LDAP://rootdse").psbase.properties.schemanamingcontext) $ds = new-object directoryservices.directorysearcher($de) $ds.filter = "(|(schemaidguid=$bytestr)(attributesecurityguid=$bytestr))" $ds.propertiestoload.add("ldapdisplayname")|Out-Null $result = $ds.findone() } if ($result -eq $null) { $guid } else { if ($extended) { $result.properties.displayname } else { $result.properties.ldapdisplayname } } } #endregion
Update: 1/29/2013
Just an additional note. Since you need distinguishednames for the commandlets, this can be a pain at times. If you like to use dsquery for quick and short results you can pipe these in, however you need to deal with the quotations that are put around the dsquery output. Example:
dsquery group -name Mygroup | foreach {$_.replace("`"","")} | get-adacl | where {$_.isinhertied -eq $false} |convert-adacl
Update: Sept 2020
It looks like all the links to the BSOnPosh module are broken now. Below is the functions that were referenced from there.
function Get-ADACL { <# .Synopsis Gets ACL object or SDDL for AD Object .Description Gets ACL object or SDDL for AD Object .Parameter DistinguishedName DistinguishedName of the Object to Get the ACL from .Parameter SDDL [switch] If passed it will return the SDDL string .Example Get ACL for ‘cn=users,dc=corp,dc=lab’ Get-ADACL ‘cn=users,dc=corp,dc=lab’ Get SDDL for ‘cn=users,dc=corp,dc=lab’ Get-ADACL ‘cn=users,dc=corp,dc=lab’ -sddl .Outputs Object .Link N/A .Notes NAME: Get-ADACL AUTHOR: YetiCentral\bshell Website: www.bsonposh.com #Requires -Version 2.0 #> [Cmdletbinding()] Param( [Alias('dn')] [ValidatePattern('^((CN|OU)=.*)*(DC=.*)*$')] [Parameter(ValueFromPipeline=$true,Mandatory=$True)] [string]$DistinguishedName, [Parameter()] [switch]$SDDL ) Write-Verbose " + Processing Object [$DistinguishedName]" $DE = [ADSI]"LDAP://$DistinguishedName" Write-Verbose " - Getting ACL" $acl = $DE.psbase.ObjectSecurity if($SDDL) { Write-Verbose " - Returning SDDL" $acl.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::All) } else { Write-Verbose " - Returning ACL Object [System.DirectoryServices.ActiveDirectoryAccessRule]" $acl.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) } }