Subscribe to Windows IT Pro

 

Get Newsletters

  • Get the Latest News
  • Product Updates
  • Helpful Tricks
  • Productivity Tips

Subscribe Now!

August 18, 2009 12:00 AM

PowerShell Script Lists Group Hierarchies in Any LDAP Directory

The System.DirectoryServices.Protocols namespace makes it possible
Windows IT Pro
InstantDoc ID #102643
Rating: (1)
Downloads
102643.zip

Executive Summary:
You can extend PowerShell's capabilities by taking advantage of the Microsoft .NET Framework. If you work with non-Microsoft LDAP directories, one particularly useful .NET tool is the System.DirectoryServices.Protocols (S.DS.P) namespace. Here's an example of how to use the System.DirectoryServices.Protocols namespace in a PowerShell script. The PowerShell script produces a comma-delimited list of groups in a directory container, including all nested group relationships. It works with Active Directory (AD) and non-Microsoft LDAP directories.

At face value, the request was simple. A colleague asked if we could provide him with a tool that would produce a comma-delimited list of groups in a directory container, including all nested group relationships. For example, if GroupA contains GroupB as a member and GroupB contains GroupC as a member, then show the group hierarchy as

GroupA, GroupB, GroupC

Then, for GroupB, the hierarchy would be

GroupB, GroupC

To get a better idea of what he wanted, see Figure 1. To complicate matters just a bit more, he wanted to use the script with Active Directory (AD) and a non-Microsoft LDAP directory.


Figure 1: Nested group output


Because our colleague was interested in only groups (and not user account members) and wanted to include nested group relationships, the tool had to perform both filtering and recursion operations. And because he wanted to use the tool with a non-Microsoft LDAP directory, it had to use an LDAP-compliant directory services namespace.

We decided to use the System.DirectoryServices.Protocols (S.DS.P) namespace, which was introduced in Microsoft .NET Framework 2.0. S.DS.P is one of the coolest namespaces released by the Microsoft Directory Services team. It's faster and significantly more compatible with heterogeneous LDAP directories than other directory services namespaces. Its high performance and compatibility are achieved by removing Active Directory Service Interfaces (ADSI) from the picture. The ADSI layer is a suite of COM interfaces upon which all the other directory services .NET namespaces (System.DirectoryServices, System.DirectoryServices.ActiveDirectory, and System.DirectoryServices.AccountManagement) rely.

Because System.DirectoryServices.Protocols is free of ADSI, its classes make calls directly to the Win32 classes in Wldap32.dll. To see an architectural diagram of this namespace, see MSDN's "Introduction to System.DirectoryServices.Protocols (S.DS.P)" web page.

You might be wondering why anyone would use the other directory services namespaces when S.DS.P is faster and much more compatible with heterogeneous LDAP directories. Although the ADSI layer reduces performance and compatibility, it simplifies directory services code creation from managed code and provides access to COM-based scripting languages such as VBScript.

While it's true that using the classes in S.DS.P is more difficult than using the classes in the other directory services namespaces, you'll notice code patterns that emerge once you're familiar with S.DS.P. Being able to use the code with any LDAP-compliant directory more than offsets the steeper learning curve.

Although you can't use the S.DS.P namespace with VBScript, you can use it with PowerShell. So, we decided to use PowerShell rather than managed code to create our colleague's tool. GetGroupRelationships.ps1 is the result. After we show you how to use this script, we'll tell you how it works.

How to Use the Script
To obtain GetGroupRelationships.ps1, click the Download the Code Here button at the top of the page. Place the script on the machine you intend to run it from. The script accesses a domain controller (DC) in the current domain, so make sure that the machine is joined to a domain. You don't need to modify the script before you use it.

When you run the script, you need to specify two command-line parameters: the Fully Qualified Domain Name (FQDN) of the AD or LDAP server you want to connect to and the distinguished name (DN) of the organizational unit (OU) or container you want to evaluate. For example, the command might look like

GetGroupRelationships amer.corp.fabrikam.com ou=Groups,dc=amer,dc=corp,dc=fabrikam,dc=com

After the script completes, you'll receive a list of groups. Figure 1 shows an example of what the output might look.

How the Script Works
The first thing that GetGroupRelationships.ps1 does is load the S.DS.P assembly. This .NET assembly contains all the properties and methods needed to write code for LDAP. PowerShell relies on the .NET System.Reflection.Assembly class to load this and other .NET assemblies.

There are a number of ways to use the Assembly class to load a .NET assembly. The two you'll see most often in PowerShell are using the Assembly class's Load method and using the Assembly class's LoadWithPartialName method.

Even though it works, you should steer clear of the LoadWithPartialName method. We found posts as far back as 2003 (e.g., Suzanne Cook's blog post "Avoid Partial Binds") that suggest you use Load method because the LoadWithPartialName method was deprecated with the release of the .NET Framework 2.0. Using the Load method ensures the correct version of the assembly loads, preventing any backward and forward incompatibilities.

As Listing 1 shows, we follow that advice and use the Load method to load the S.DS.P assembly.


Listing 1: Code That Loads the S.DS.P Assembly


Declaring [Void] when the code calls the Load method suppresses the output associated with loading it.

Related Content:

ARTICLE TOOLS

Comments
  • Gebremeskel
    3 years ago
    Dec 23, 2009

    It is gerat script but what if I would like to add the list of uers at the end of the hierarchy, and export to excel.
    Thanks for the great work

You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement

advertisement

White Papers

Get your Windows 7 deployment off to the right start by implementing PC lockdown. A locked-down environment is easier and cheaper to support since users are less likely to make unnecessary changes to the core system configuration - read more here!

Essential Guides

Is your iSCSI "lossy"? The reality is that most off-the-shelf Ethernet hardware deployed for iSCSI can lose packets, resulting in slow performance or application downtime. Learn how to assess your current iSCSI infrastructure and engineer an advanced iSCSI SAN infrastructure.

Web Seminars

What's the best way to keep your network safe from malware? In this web seminar, security expert Greg Shields suggests an alternative method to the traditional blacklisting approach that is common with anti-virus and anti-malware solutions.

eLearning Series

We bring the experts direct to you to share their real-world perspective and expertise. During each event, three sessions stream in real time, so you can learn, ask questions, and get solutions.
Upcoming event: Getting the Most with Exchange 2010 with Paul Robichaux

Subscribe to Windows IT Pro!

Windows is a trademark of the Microsoft group of companies. Windows IT Pro is used by Penton Media Inc. under license from owner.