How to Query Active Directory Objects Using GUID in PowerShell and C#


4 views

Every Active Directory object is assigned a unique Globally Unique Identifier (GUID) upon creation. This 128-bit value remains constant even if the object is renamed or moved within the directory structure. The GUID is stored in the objectGUID attribute and serves as the most reliable way to reference objects programmatically.

Using the ActiveDirectory module:

# Convert GUID string to byte array
$guid = [guid]"a1b2c3d4-e5f6-7890-abcd-ef0123456789"
$byteGuid = $guid.ToByteArray()

# Search using LDAP filter
Get-ADObject -LDAPFilter "(objectGUID=$byteGuid)"

Alternative using DirectorySearcher:

$searcher = [ADSISearcher]"(objectGUID=\\a1\\b2\\c3\\d4\\e5\\f6\\78\\90\\ab\\cd\\ef\\01\\23\\45\\67\\89)"
$searcher.FindOne()

Using System.DirectoryServices:

using System.DirectoryServices;

string guidString = "a1b2c3d4-e5f6-7890-abcd-ef0123456789";
Guid guid = new Guid(guidString);

DirectoryEntry entry = new DirectoryEntry("LDAP://dc=domain,dc=com");
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = $"(objectGUID={ConvertToLdapGuid(guid)})";

SearchResult result = searcher.FindOne();

private static string ConvertToLdapGuid(Guid guid)
{
    byte[] bytes = guid.ToByteArray();
    return $"\\{BitConverter.ToString(bytes).Replace("-", "\\")}";
}

When working with GUIDs in LDAP queries:

  • The byte order is different from standard GUID string representation
  • Escape each byte with backslashes in the LDAP filter
  • Consider using attribute-scoped queries for better performance

GUID-based lookups are particularly useful for:

  • Service accounts that might be renamed
  • Cross-domain object references
  • Audit logging where names might change
  • Automation scripts requiring stable references

Every object in Active Directory (AD) is assigned a unique Globally Unique Identifier (GUID) upon creation. This 128-bit identifier remains constant even if the object is renamed or moved within the directory. GUIDs are stored in the objectGUID attribute and are essential for reliable object references in programming scenarios.

While GUIDs are unique identifiers, querying them directly presents technical challenges because:

  • GUIDs are stored as binary data in AD
  • LDAP requires special formatting for binary data searches
  • The byte order of GUIDs differs between AD storage and .NET representation

To search for an object by GUID in Active Directory, you need to convert the GUID to a format that LDAP can understand. The correct format is a hexadecimal string representation with backslash escapes for each byte:


// C# Example using System.DirectoryServices
string guidString = "5b8a7c2e-1d3f-49b1-a13c-8d3d7f8a9b0c";
Guid guid = new Guid(guidString);
byte[] bytes = guid.ToByteArray();
string ldapGuid = "";
foreach (byte b in bytes)
{
    ldapGuid += "\\" + b.ToString("x2");
}

string ldapFilter = $"(objectGUID={ldapGuid})";

Here's a full implementation for searching AD by GUID in PowerShell:


# PowerShell function to find AD object by GUID
function Get-ADObjectByGUID {
    param(
        [Parameter(Mandatory=$true)]
        [string]$GUID
    )
    
    try {
        $guidObj = [guid]$GUID
        $searcher = [adsisearcher]""
        $searcher.Filter = "(&(objectClass=*)(objectGUID=$(ConvertTo-LDAPGUID $guidObj)))"
        $result = $searcher.FindOne()
        
        if ($result) {
            return $result.GetDirectoryEntry()
        }
        else {
            Write-Warning "No object found with GUID: $GUID"
        }
    }
    catch {
        Write-Error "Error searching for GUID $GUID : $_"
    }
}

function ConvertTo-LDAPGUID {
    param([guid]$Guid)
    $bytes = $Guid.ToByteArray()
    $hex = $bytes | ForEach-Object { '\' + $_.ToString('X2') }
    return $hex -join ''
}

Using DirectorySearcher in C#


DirectoryEntry entry = new DirectoryEntry("LDAP://dc=domain,dc=com");
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = $"(objectGUID={ConvertToLdapGuid(new Guid("5b8a7c2e-1d3f-49b1-a13c-8d3d7f8a9b0c"))})";
SearchResult result = searcher.FindOne();

Using Get-ADObject in PowerShell

If you have the ActiveDirectory module available:


Get-ADObject -Filter "objectGUID -eq '$((New-Object GUID '5b8a7c2e-1d3f-49b1-a13c-8d3d7f8a9b0c').Guid)'"

When searching across large directories:

  • Always specify the search base to limit the scope
  • Consider caching frequently accessed GUIDs
  • For batch operations, use paging with DirectorySearcher.PageSize
  • Index the objectGUID attribute if performing frequent searches

Common problems and solutions:

Issue Solution
Invalid format exception Ensure GUID string is properly formatted (8-4-4-4-12)
No results found Verify GUID exists and check for byte order issues
Performance problems Limit search scope and add proper indexing
Access denied Check authentication and permissions