Powershell and Unknown User SIDs
Once again, my apologies for my lack of posting..
Anyway…
An interesting thing came up at work the other day when one of my fellow administrators asked me if I could resolve an unknown SID he was seeing in some logs to see what the heck it belonged to.
Since I had been telling him that Powershell could do ANYTHING (slight exaggeration, I know)… that it should be able to do this.
Well, it certainly is an interesting notion.
I know that I have run into this in the past where you have file system ACLs set and there are a bunch of SIDs sitting in there that nobody seems to know who they belong to.
While it isn’t THAT important to resolve them since the user account is most likely no longer around, it IS an interesting thought exercise.
After perusing the web looking for others who have done something similar, I feel I had enough to throw something together..
Basically when an Active Directory object (like a user) is “deleted”, it is really just Tombstoned for a period of time and is moved to the hidden container “Deleted Objects” and then removed after like 90 days or so.
Here is my solution to “finding” those objects.
First you will have to know what Domain you want to look at for this object AND you have know the SID you are looking for.
function Resolve-DeletedUserSID($Domain, $UserSID) { ## This is kind of a mashup of a few different scripts I found online in some forums. ## Unfortunately I don't remember who did them. If it was you, point me to your post and I will ## give you the credit for your piece. ## ## Returns User information for deleted account with the specified SID and User Domain $DomainRoot = "LDAP://" + $Domain.trim() $DomainDN = ([adsi] ( $DomainRoot )).DistinguishedName $adspath = "LDAP://" + $DomainDN $root = [system.directoryservices.Directoryentry] $Adspath $root.psbase.AuthenticationType = [system.directoryservices.authenticationtypes]::Fastbind ## We will be looking in the "Deleted Objects" container which is normally hidden, etc. ## You will need to execute this with an account that has DomainAdmin rights to the domain you are ## querying. $root.psbase.path = "LDAP://cn=Deleted Objects," + $DomainDN $search = [system.directoryservices.directorysearcher] $root $search.filter = "(&(isDeleted=TRUE)(!(objectClass=computer))(objectclass=user))" $search.Tombstone = $true # If you have more than 1000 users, you must NOT define SizeLimit (we haven't) # and PageSize must be less than the default value (of 1000). # I found this a bit strange...but as long as we understand it, I guess it is okay $Search.PageSize = 500 # Only look in the top level of the Deleted Objects container. $search.SearchScope = [system.directoryservices.searchscope]::OneLevel $result = $search.FindAll() # If the SID isn't found, you will get nothing returned. $result | Select-Object @{ Name = "Name" ; Expression = { $_.Properties.Item("Name")[0].split("`n")[0] } }, ` @{ Name = "SAMAccountName" ; Expression = { $_.Properties.Item("SAMAccountName") } }, ` @{ Name = "SID" ; Expression = { New-Object System.Security.Principal.SecurityIdentifier($_.Properties.Item("ObjectSID")[0], 0) } }, ` @{ Name = "WhenChanged" ; Expression = { $_.Properties.Item("WhenChanged") } } ` | where-Object { $_.SID -ieq $UserSid.Trim() } }
As always…
Happy Scripting!!!! and let me know if you have questions or problems.
– Mark