<# Get-ADobjPermissions.ps1 Alan Kaplan 9/29/20, 10/1/20 Convert-GuidToName is varation code in Convert-ADACL by Nathan Linley - http://myitpath.blogspot.com/2012/04/decoding-ad-acls-powershell.html #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] #DistinguishedName of object [String]$objDN ) #Some fluff. resize console window and set title $Console = $host.ui.rawui $Buffer = $Console.BufferSize $ConSize = $Console.WindowSize $Height = 10 ; $Width = 100 If ($Buffer.Width -gt $Width ) { $ConSize.Width = $Width; $Console.WindowSize = $ConSize } $Buffer.Width = $Width ; $ConSize.Width = $Width $Buffer.Height = 3000; $Console.BufferSize = $Buffer $ConSize = $Console.WindowSize $ConSize.Width = $Width; $ConSize.Height = $Height $Console.WindowSize = $ConSize $Console.WindowTitle = 'Getting requested information' #Create a hashtable for GUIDs so repeat values aren't looked up twice $Script:schemaIDGUID = @{} #add common / confusing names $schemaIDGUID.add('00000000-0000-0000-0000-000000000000', 'All') $schemaIDGUID.Add('c7407360-20bf-11d0-a768-00aa006e0529', 'Domain Password Information') $schemaIDGUID.Add('E45795B2-9455-11d1-AEBD-0000F80367C1', 'Email Information') $schemaIDGUID.Add('59ba2f42-79a2-11d0-9020-00c04fc2d3cf', 'General Information') $schemaIDGUID.Add('bc0ac240-79a9-11d0-9020-00c04fc2d4cf', 'Membership') $schemaIDGUID.Add('4c164200-20c0-11d0-a768-00aa006e0529', 'User Account Restrictions') $schemaIDGUID.Add('77B5B886-944A-11d1-AEBD-0000F80367C1', 'Personal Information') $schemaIDGUID.Add('e48d0154-bcf8-11d1-8702-00c04fb96050', 'Public Information') $schemaIDGUID.Add('037088f8-0ae1-11d2-b422-00a0c968f939', 'RAS Information') $schemaIDGUID.Add('5f202010-79a5-11d0-9020-00c04fc2d4cf', 'User Logon') $schemaIDGUID.Add('E45795B3-9455-11d1-AEBD-0000F80367C1', 'Web Information') $schemaIDGUID.Add('72e39547-7b18-11d1-adef-00c04fd8d5cd', 'DNS Host Name Attributes') $schemaIDGUID.Add('9b51a1ef-79b7-4ae5-9ac8-d14c47daca46', 'Deleted Exchange GUID: 9b51a1ef-79b7-4ae5-9ac8-d14c47daca46') #hashtable for name lookups $Script:SIDtoName = @{} #Optional #$SIDtoName.add('Broken SID here','Description') $objRootDSE = [System.DirectoryServices.DirectoryEntry] "LDAP://rootDSE" $SchemaNamingNC = $objRootDSE.schemaNamingContext $ConfigurationNC = $objRootDSE.configurationNamingContext function Convert-GUIDToName { param( [parameter(mandatory = $true)][string]$guid, [switch]$extended ) write-Progress "Getting name for property with GUID $guid" if ($schemaIDGUID.ContainsKey($GUID) ) { $schemaIDGUID[$Guid] Return } $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 $Searcher = New-Object System.DirectoryServices.DirectorySearcher $Searcher.SearchRoot = "LDAP://CN=Extended-Rights,$ConfigurationNC" $Searcher.filter = "(|(schemaidguid=$bytestr)(attributesecurityguid=$bytestr))" [void]$Searcher.propertiestoload.add("displayname") $Searcher.filter = "(rightsguid=$guid)" $result = $Searcher.findone() } else { #Search schema for possible matches for this GUID $Searcher = New-Object System.DirectoryServices.DirectorySearcher $Searcher.SearchRoot = "LDAP://$SchemaNamingNC" $Searcher.filter = "(|(schemaidguid=$bytestr)(attributesecurityguid=$bytestr))" [void]$Searcher.propertiestoload.add("ldapdisplayname") $result = $Searcher.findone() } if ($null -eq $result) { Write-Warning "Unable to get name for GUID: $guid" $GuidName = $guid } else { if ($extended) { $GuidName = $result.properties.displayname[0] } else { $GuidName = $result.properties.ldapdisplayname[0] } } if (!$schemaIDGUID.ContainsKey($GUID) ) { $schemaIDGUID.add($GUID, $GUIDname) } $GuidName } Function Test-IsSID($strID) { #Perfect match, does not match O:SID, etc $strRegex = '^S-\d-(\d+-){1,14}\d+$' [RegEx]::IsMatch($strID, $strRegex) } Function Convert-SIDtoNTName($sidVal) { write-Progress "Getting name for user with SID $sidval" if ($SIDtoName.ContainsKey($SidVal) ) { $SIDtoName[$SidVal] Return } $objSID = New-Object System.Security.Principal.SecurityIdentifier ($sidVAl) Try { $Identity = $objSID.Translate([System.Security.Principal.NTAccount]) $Lookup = $Identity.Value } catch { $LDAPpath = "LDAP://" if ([adsi]::Exists($LDAPpath)) { $IDRef = ([adsi]$LDAPpath) $SamName = [string]$IDRef.SamAccountName $DN = [string]$IDRef.distinguishedName $Dom = $DN.Substring($DN.IndexOf(",DC")).Replace(",DC=", ".").Substring(1) $Lookup = "$Dom\$SamName" } Else { Write-warning "User SID $sidVAl not found in AD" $Lookup = $sidVal } } $Lookup if (!$SIDtoName.ContainsKey($SidVal) ) { $SIDtoName.add($SidVal, $Lookup) } } ## Script starts here $o = [adsi]"LDAP://$objDN" $NTS = $o.Psbase.ObjectSecurity.access $PermList = $NTS | foreach-object { $guid = $_.objectType.guid $ID = [string]$_.identityReference $identity = if (Test-IsSID $id) { Convert-SIDtoNTName $ID } Else { $ID } $objectTypeName = if ($_.ActiveDirectoryRights -eq "ExtendedRight") { Convert-GUIDToName $guid -extended } Else { Convert-GUIDToName $guid } [PSCustomObject]@{ IdentityRef = $identity ObjectTypeName = $objectTypeName ActiveDirectoryRights = $_.ActiveDirectoryRights isInherited = $_.isInherited AccessControlType = $_.AccessControlType } } Write-Progress -Completed 'Done' $objName = $o.Name $PermList | Sort-object identityRef, ObjectTypeName | Select-object * -unique | out-gridview -Title "NT Security for $objName`. Selected values are copied to your clipboard" -PassThru | Set-Clipboard