December 13th, 2011

Use PowerShell to Search Active Directory for GIDs

Doctor Scripto
Scripter

Summary: Learn how to use Windows PowerShell to search Active Directory for GIDs.

Today we have as our guest blogger, Chris Wu.

Chris Wu’s career at Microsoft started in 2002, first as a support engineer in Microsoft Global Technical Support Center in China to support various components of the base operating system. Now he is a premier field engineer in Canada, and he specializes in platform and development support. During the course of troubleshooting, performance tuning, and debugging, he has created many utilities to ease and facilitate the process by leveraging various programming languages, like C, C++, and C#. Now Windows PowerShell has become his new favorite.

Photo of Chris Wu

Take it away Chris…

So what is a GID? To the UNIX (and Linux) operating systems, group identifiers (GIDs) and user identifiers (UIDs) are what security identifiers (SIDs) are to the Windows operating system. Each user in the UNIX system has a UID and a primary GID to identify the primary group he belongs to. Users can also belong to multiple secondary groups to inherit security settings.

In a pure Windows world, these fields are not used, even though the uidNumber and gidNumber attributes are available for compliance to LDAP protocol. The following image shows that the gidNumber attribute is not set.

 

In a mixed Windows and UNIX environment, however, the uidNumber and gidNumber attributes provide a mechanism to map UNIX users and groups to Windows names. For example, after Services for NFS are installed, Active Directory lookup services utilize these attributes for identity management.

So how can we query groups that have GIDs assigned? As always, there are multiple ways to accomplish this in the Windows operating system. Windows PowerShell has made searching through LDAP much easier by implementing the [adsisearcher] type accelerator, which instantiates a System.DirectoryServices.DirectorySearcher .NET object from a search filter.

As a start, we can use “(objectCategory=group)” as the filter string to enumerate Active Directory groups as shown here.

$searcher=[adsisearcher]”(objectCategory=group)”

$result = $searcher.FindAll()

$result | Select-Object

This script and its associated output are shown here.

Image of command output

This simple search filter uses the “(<attribute><operator><value>)” format that is mentioned in the Services for NFS Step-by-Step Guide. Now to find all groups that have the gidNumber attribute set, we need another filter that checks this attribute, and “(gidNumber=*)” will do the trick. By combining the two filters with the “(<operator><filter1><filter2>)” format, we get the following:

“(&(objectCategory=group)(gidNumber=*))”

This script and its associated output follow. 

$searcher=[adsisearcher]”(&(objectCategory=group)(gidNumber=*))”

$result = $searcher.FindAll()

$result | Select-Object @{Name=”DN”;Expression={$_.properties.distinguishedname}},@{Name=”gid”;Expression={$_.properties.gidnumber }}

Image of command output 

The previous script would have worked just fine if objectClass was used in place of objectCategory. An interesting comparison between the two is documented in this Windows Dev Center topic.

One can easily append an Export-Csv cmdlet at the end of the previous command to save the result as a .csv file for reading or processing in the future.

With the Active Directory module that’s available for Windows 7 or Windows 2008 R2, there are multiple ways to achieve the same goal by using a single cmdlet. Two options are shown here. 

#Use LDAP search filter syntax

Get-ADObject -LDAPFilter “(&(objectCategory=group)(gidNumber=*))” -Properties gidNumber | Select @{Name=”DN”;Expression={$_.DistinguishedName}},@{Name=”gid”;Expression={$_.gidNumber}}

#Or, use AD filter syntax

Get-ADGroup -filter ‘gidNumber -like “*”‘ -Properties gidNumber | Select @{Name=”DN”;Expression={$_.DistinguishedName}},@{Name=”gid”;Expression={$_.gidNumber}}

This command output is shown here.

Image of command output

Note: The Properties parameter is needed in both commands to include the gidNumber property (which is not exported by default) in the resultant objects.

We can actually query Active Directory objects through WMI. The DS_GROUP class under the “root\directory\ldap” namespace instantiates all group objects from Active Directory. So with a WQL filter, we can retrieve a list of groups with the gidNumber attribute defined as shown here.

Get-WmiObject -namespace root\directory\ldap -class ds_group -filter ‘DS_gidNumber IS NOT NULL’ | Select-Object @{Name=”DN”;Expression={$_.DS_distinguishedName}},@{Name=”gid”;Expression={$_.DS_gidnumber }}

Image of command output

Notice how WMI uses the “DS_” prefix for both the distinguishedName and gidNumber attributes.

Now with all these options available, which route has the best performance? This question will be left to the readers to test in a real environment. As a hint, Measure-Command is the cmdlet to assess the execution time of script blocks.

Thank you CHris for sharing your time and knowledge with our readers.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.