Fire up Windows PowerShell and run:
$strSID="S-1-5-21-500000003-1000000000-1000000003-1001"
$uSid = [ADSI]"LDAP://<SID=$strSID>"
echo $uSid
The output should look something like this,
distinguishedName : {CN=John Doe,OU=Domain Admins,OU=People,OU=xxx,DC=xxx}
Path : LDAP://<SID=S-1-5-21-500000003-1000000000-1000000003-1001>
Fire up Windows PowerShell and run:
$strSID="S-1-5-21-500000003-1000000000-1000000003-1001"
$uSid = [ADSI]"LDAP://<SID=$strSID>"
echo $uSid
The output should look something like this,
distinguishedName : {CN=John Doe,OU=Domain Admins,OU=People,OU=xxx,DC=xxx}
Path : LDAP://<SID=S-1-5-21-500000003-1000000000-1000000003-1001>
The "LDAP way" to do this would be to retrieve the base object with the GUID (or SID), which will retrieve only the base object and not have additional class data attached. However, from this base object you can retrieve the actual "distinguishedName" for the user object. Retrieving the user object using the "distinguishedName" attribute will return a DirectoryEntry object (.Net/C#/PowerShell) or a iadsUser object (VBScript) with full class data and allow you to get whatever other attribute data you need.
The issue is retrieving the initial object with the GUID (or SID). Some sources will say that you must convert the string format GUID (i.e., {28c67c50-9778-47a4-a77a-bf56f238a0c4}) into a string representation of the byte-array (i.e., "\50\7c\c6\28\78\97\a4\47\7a\a7\bf\56\f2\38\a0\c4") to pass to LDAP. According to Microsoft documentation this is not the case. A simple string representation of the GUID/SID is sufficient.
Here's a sample of how you can bind to the object via the GUID then retrieve the actual user object with full class data. Powershell actually pulls the complete object if you bind with the GUID. If you use VBScript, then you would need to do the two step process.
Also, please note that although the Microsoft docs say that multiple GUID-string formats are acceptable, the only one I have been able to successfully use is to strip the {}- characters. ALSO, please note this is NOT a correct "byte-array" string, but simply the GUID string stripped of special characters.
$strGUID = "{28c67c50-9778-47a4-a77a-bf56f238a0c4}" -replace '-|{|}',''
$guid = [ADSI]"LDAP://<GUID=$strGUID>"
$user = [ADSI]$guid.distinguishedName
The same process can be used for a SID bind. The MSDN page describing this says there are several fstring formats available, but the most common will be the S-1-5-...-...-...-... format.
#Powershell
$strSID="S-1-5-21-500000003-1000000000-1000000003-1001"
$uSid = [ADSI]"LDAP://<SID=$strSid>"
$user = [ADSI]$user.distinguishedName
*** QUERYING ***
If you are going to perform an LDAP query to find the object (e.g. by comparing 'objectGUID' to a byte-array or 'objectSID' to a byte-array), that is when you will need to do the "correct" byte-array conversion. It is important to note that the byte-array has a different order than the string representation, as it is stored as DWORD-WORD-WORD-WORD-BYTES for GUID, and DOES take endian order into consideration. Converting the byte-array for a SID has similar condierations.
There are several different ways to accomplish the conversion, Technet has a simple vbScript algorithm. You could also do something fancier with C#/VB.Net using the System.Guid, or via a simple script in PowerShell (gotta love PowerShell!):
#Powershell
# Creates a new System.GUID object from the supplied string.
# Only need for this example.
$guid = [system.guid]"{28c67c50-9778-47a4-a77a-bf56f238a0c4}"
$out=""
#Formats the array of integers as a backslash-delimited string of Hex values
$guid.ToByteArray() | %{
("\{0:x2}" -f $_) }
You should then be able to query for the object using a standard LDAP filter:
(&(objectClass=User)(objectGUID=\50\7c\c6\28\78\97\a4\47\a7\7a\bf\56\f2\38\a0\c4))
... or whatever else you may be querying for. This should work for a SID as well.
How to find user or group from SID - Software & Applications - Spiceworks Community
How do I use get-aduser "username" | select SID to get only the output, not the header, so i can use it in a variable
I always wrap the command in parenthesis and specify the property I want. It works for one or many objects, and is more simple than writing select -expand statements.
$SID = (Get-ADUser "Username").SIDMore on reddit.com
get SID for all users in AD
Get-aduser with specific SIDHistory
How do I convert a Windows SID to a username using PowerShell?
How do I find all SIDs associated with a specific user account?
Why do Windows security logs show SIDs instead of usernames?
Videos
Hello All,
My question is this, i'm using the following:
get-aduser "username" | select SID
In an effort to get the SID of a user so I can plug it in as a variable down the line...the problem is it keeps coming up as the SID with @{SID= preceding it.
Obviously...that is not helping me when I try to just plugin the ACTUAL SID number into a variable later in the script. Is there a better way to do this so I can just get the actual text of the SID as an output?
Any help is appreciated!
I always wrap the command in parenthesis and specify the property I want. It works for one or many objects, and is more simple than writing select -expand statements.
$SID = (Get-ADUser "Username").SID
Get-ADUser "username" | Select-Object -ExpandProperty SID
or
$User = Get-ADUser "username"
$Sid = $User.SID
Hello @Anne
You can extract all the SIDs in a specific domain using:
Get-ADUser -Filter * -SearchBase "dc=domain,dc=local" | select Name,SID
Hope this helps with your query,
--
--If the reply is helpful, please Upvote and Accept as answer--
The property name, I think, should be objectSID.
Also, why are you using "ADquery" instead of the PowerShell Get-ADUser?
Hi all,
I have scirpt which getting all users\groups with specific sidhistory value.
$SID = "S-1-5-21-xxxxx-xxxxx-xxxx*"
Get-ADUser -Filter * -Properties * | where{$_.sidhistory -like $SID} | Select-Object Name, @{N='Enabled';E={$_.Enabled}}, @{N='SIDHistory';E={$_.SIDHistory}}, | export-csv "x.csv"
However,
script not getting all users\groups. It's query to tens of thousands of items. Perhaps there is a problem.
Do you have better idea of this script?
You can do something like the following:
$domains = Get-ADForest | Select-Object -ExpandProperty Domains
$SID = 'some sid value'
$CN = 'user CN'
foreach ($domain in $domains) {
$DC = (Get-ADDomainController -DomainName $domain -Discover).Hostname
$User = Get-ADObject -filter "CN -eq '$CN' -and ObjectSID -eq '$SID'" -Server $DC -IncludeDeletedObjects -Credential $mycred -ErrorAction SilentlyContinue
}
Explanation:
- You can list all of your subdomains using the Get-ADForest command, and that collection is stored in
$domains. - A
foreachloop can loop through each of those domains with the current domain being$domain. - For each domain, you can query for a domain controller to store in
$DCand then perform aGet-ADObjectwith the-IncludeDeletedObjects. - To speed up your query, you can use the
-filterswitch rather than piping toWhere-Object. - You can filter on the
CNandObjectSIDattributes.
Additional Considerations:
In this script, nothing is being done with the discovered data. I am not sure where you want to go from here. You will need to add some other logic like an if statement to check the value of $User. Because we are using -filter, $user will be $null if no object is found rather than throwing an error, which you will see when using Get-ADObject -Identity. From there you can do additional processing even if that means utilizing break statements.
if ($user) {
# User was found. Process code here.
break # Exit the foreach loop because further loop processing is not needed
}
else {
# User was not found. Process code here
}
No output is generated in the solution because all queried data is stored in variables. The value of $DC and $User will be overwritten during each loop iteration. It may be best to store the discovered user data in a collection with a specific set of properties. You could retrieve DistinguishedName or CanonicalName along with SamAccountName and ObjectSID to know which domain and container has the user object.
$Users = foreach ($domain in $domains) {
$DC = (Get-ADDomainController -DomainName $domain -Discover).Hostname
Get-ADObject -filter "CN -eq '$CN' -and ObjectSID -eq '$SID'" -Server $DC -IncludeDeletedObjects -Properties CanonicalName,SamAccountName,ObjectSID -Credential $mycred -ErrorAction SilentlyContinue |
Select-Object SamAccountName,ObjectSID,CanonicalName
}
In the code snippet above, $users will now contain a collection of found users with the SamAccountName,ObjectSID,CanonicalName properties for each object.
Like Get-ADUser, Get-ADObject has a limited set of default display properties. You will need to use the -Properties parameter to display what you require. You can test what is available by starting with -Properties *.
Not much information has been provided on how AD user data is being input into the script. You may have a collection of CN values or CSV file. You will have to consider how to iterate over those values.
I might be wrong, but you can call the WMI Win32_SID class with the SID = as parameter. Works for me with two-way trusts.