Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Managing Raw DirectorySearcher Data

Posted on February 24, 2022February 24, 2022

Recently, I was chatting with my friend Gladys. As part of her work, she often creates Active Directory PowerShell-related tools for her colleagues. It is always good to be the toolmaker! Anyway, she doesn't want to rely on the Active Directory module from Remote Server Administration Tools (RSAT). There's no guarantee that the feature can be installed on a colleague's desktop, and for some of the tasks that need to be accomplished, it is overkill.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Instead, Gladys often builds PowerShell tools for managing bits and pieces of Active Directory using the [System.DirectoryServices] namespace. These .NET classes have been around a long time and are what we used before Microsoft released the Active Directory module. These classes should be found on your computer and do not rely on the Active Directory module. One of the go-to classes is the DirectorySearcher.

$Searcher = New-Object System.DirectoryServices.DirectorySearcher

Gladys' company uses managed service accounts extensively, and she was searching for them in Active Directory. In my demonstration domain, I only have one.

$searcher.filter = "(&(objectClass=msDS-GroupManagedServiceAccount))"
$gmsa = $Searcher.FindOne()

The resulting object is a little different than what you might be familiar with. The properties are stored as a ResultPropertyCollection object.

DirectoryServices ResultsPropertyCollection

Each property value is stored as a collection, so technically, you should use an index number to get the value, even if there is only a single item.

result property

The property Gladys wanted to work with was msds-groupmsamembership, but when she got the value, it was a huge collection of numbers. It turns out that the result property was an array of bytes. The bytes represented a value. Gladys can see what the value should be using the Active Directory module.

This looks like a security object. Looking at the property with Get-Member confirms it.

Remember, Gladys is trying to avoid using the Active Directory module. She needs to take the array of bytes and turn it into an ActiveDirectorySecurity object.

During Gladys' research, she came across articles discussing how to convert the byte array into something more meaningful. But all of the articles were developer-oriented and relied on COM objects. I looked at these articles, and after banging my head against my desk for a bit and trying things in PowerShell, I finally made the mental connection on how to solve this.

Looking for Constructors

I knew I needed a [System.DirectoryServices.ActiveDirectorySecurity] object. So I checked to see if there was a constructor. That is, a method to create a new instance of the object. And there was.

ActiveDirectorySecurity constructor

This looks easy. I was hoping there was a way to use the bytes which I've saved to a variable.

[byte[]]$raw = $gmsa.Properties.'msds-groupmsamembership'[0]

But maybe the new ActiveDirectorySecurityObject will provide a clue, so I'll create one.

$adsec = [System.DirectoryServices.ActiveDirectorySecurity]::new()

This is why you need to know how to use Get-Member. I piped $adsec to Get-Member, looking for something that would give me a hint on how to use the array of bytes. I found a set method.

SetSecurityDescriptorBinaryForm method.

I already knew I needed to create some form of security descriptor, and this method takes an array of bytes as a parameter.

$adsec.SetSecurityDescriptorBinaryForm($raw)

I didn't get a result which isn't surprising since Get-Member indicates this method doesn't return anything. That is what 'void' is indicating. Did anything happen?

The updated ActiveDirectorySecurity object

Success! I can pipe this to Get-Member to see what properties or methods I can use. Or pipe it to Select-Object.

all activedirectorysecurity properties.

Gladys can use this object in her PowerShell scripting.

Decoding the SID

But you know, there are a few more properties from the directory searcher result that might need to be converted. If for no other reason than to reinforce my process. The object's SID is also represented as a byte array.

[byte[]]$rawsid = $gmsa.properties.objectsid[0]

What type of object do I need to create?

object sid type

I already knew the property name. You may need to select all properties to pipe to Get-Member and narrow down your list.

What kind of constructor options are available?

SID constructors

This looks promising!

$sid = [System.Security.Principal.SecurityIdentifier]::new($rawsid,0)

Better. But not ideal. Piping $sid to Get-Member for guidance, I find the Translate() method. I know from previous experience how to use the method. If you didn't, you might have to do some research to learn how to use it.

translated sid

And this is what I expect since I already know the account name.

Object GUID

Remember, we're focusing on a process here. Let's try one more property and look at the object GUID, which is also stored as an array of bytes.

[byte[]]$rawguid = $gmsa.properties.objectguid[0]

I know this has to be a [System.Guid] object.

This looks easy.

Writing simple PowerShell functions to make these conversions wouldn't be that difficult.

Summary

I realize you may not have a need to use the DirectorySearcher, but you might find yourself in a situation with unknown data that you need to translate or convert. You might start with the process I've demonstrated here. If nothing else, I hope this has shown you the importance of knowing how to use Get-Member.

Comments and questions are welcome.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

2 thoughts on “Managing Raw DirectorySearcher Data”

  1. Pingback: Managing Raw DirectorySearcher Data - The Lonely Administrator - Syndicated Blogs - IDERA Community
  2. Paula says:
    February 24, 2022 at 4:33 pm

    Thanks, as usual, Jeff!

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d