Microsoft Windows Server are very great products to work with. And,... server administrators and operators do not like to do stupid work or repeating tasks. That's why I have made this category, to share my most favorite general scripts that I often use. This is not a scripting site, there are many more and better sites available for that. These scripts and tips are just handy for common, migrations and daily (scheduled) use. So, the initially set up was for my own references, but now I share it with you. Enjoy it !! Due to the fact that a big percentage of visitors of this page are internationally based, this article is in the english language.

Now, you probably recognize the problem. You are working with Active Directory, everything is nice, and works great. You have your OU structure perfectly in place, and users are members of rolegroups, and every function and application has its own publi or local domain security group. And then,.. once a year, you are having an (internal)audit from your accountant or controller, and you have to provide them with all kinds of stuff, that no-one really care about, as long as everything is functionally correctly. One of these things is the groupmembership of certain Active Directory Security Groups. This is not only important for (Microsoft)licensing issues, but normally your users will only complain if they are not having enough access rights, they will never complain when they have to much access rights. And thats why security groups in my opinion, needs more attention from you as an administrator, as well from the upper management. (not only on audits). There are a lot of vbs scripts available to extract this information in older environments, but larger organizations are to big for that, and then you'll need powershell if you don't want a hugh paper administration.

The solution is here underneath for you, explaining roughly how it works. If you Google for this functionallity in powershell, you will notice that it is very hard to find, but I can only hope this article will provide me with a better ranking in Google. So, have fun reading, feel free to copy it for your own use, but if you do, it would be nice to mention my name, and this url, as a reference. (also online)

First of all, you start up Notepad++ or your own editor, and your Active Directory Users and Computers msc. We are going to create 2 files: One source/reference file, and a powershell (ps1) script file. It is possible to export the groupmember users in a single powershell file, but often I don't find that handy, as security groupnames don't change that much, only the members often do. Create a blank page and copy/paste everything between the red lines in to it.

This script will list the Groupmembership from Active Directory
(c) Ben Oostdam - the Netherlands
$GrpFile = New-Item -type file -force "E:\Scripts\GroupMembersShip\GroupMembers-Export.csv"
Import-CSV "E:\Scripts\GroupMembersShip\GroupMembers-OU.csv" | ForEach-Object {
$GrpName = $_.GroupName
$group = [ADSI] "LDAP://$GrpName"
$ | Out-File $GrpFile -encoding ASCII -append
 foreach ($member in $group.member)
   $Uname = new-object directoryservices.directoryentry("LDAP://$member")
   $ | Out-File $GrpFile -encoding ASCII -append

This will be the script we are going to run, Save it as "Export-AD-Sec-Group-Users.ps1" or something like that. I'll explain in further on in this article. Now create another blank page in order to create another file. The text is, again, below the red lines...



These are the parameters that the script is going to use, so save it as
"E:\Scripts\GroupMembersShip\GroupMembers-OU.csv" or as the same name you are going to use 6th line of the first script. As you can see, you can specify multiple security groups at the same time, and across multiple OU groups as well, I tried to put some different syntaxis in here, I'll guess you are able to figure the rest out yourself! You can use a single group, or dozens of it, that doesn't matter. Keep Tip1 at the bottom of this article in mind when you are expecting a large output. I called the output file in the 5th line of the first script
"E:\Scripts\GroupMembersShip\GroupMembers-Export.csv" ; you can call it anything you want, but do not forget to specify the correct directory structure. If you name it wrong, a new directory or filename will be created. keep that in mind!

A rough explanation of the script. Line 5 creates the output file, as that needs to be open, to enable the script to append some lines later. Line 6 calls/opens your second file that contains the the actual security group lines from left to right, corresponding your Active Directory structure and starts the first loop in the script. Line 7 loads the security groupname. Line 8 stores the full structure to a variable and line 9 converts that to the CommonName. Than the second loop starts en every Distinguished Name of a member of that securitygroup is looked-up and appended to the export file. Using the Uname variable, actually prevents the script from stopping on strange SID's, or unresolvable, nested, other (local) security groups and that works great! Depending on your naming convention for your security groups, it should be easy to recognize other, nested, security groups. It might be a little different if you are using friendly names for user roles, but hey,... in that case,... it wasn't me who designed that.  
Now lets start up Powershell with administrative privileges from the Start button. Browse to the directory,
that your "Export-AD-Sec-Group-Users.ps1" script is in and just run it! The result will be displayed on the screen and stored in the previous named export-file as well. Import it in Excel, split it, and customize the security group with color or a bold, underlined font and your controller/accountant will be pleased with you. You can delegate these tasks to your junior administrator or helpdesk as well offcourse. You canb Google and found this page! Let the others do the rest! 

Tip 1: Use the -ResultSize Unlimited parameter if you are expecting an output above a thousand lines.
Tip 2: You can run this script remotely, but make sure that all the parameters and OU's are correct. (remember the signing)
Tip 3: If you want to export only the active users, add the follow statement in the second loop:
           'Where userAccountControl = 512' (see also the article on )  
Tip 4: If you want the GroupNames in another color, modify the 10th line of the first script in something like: 
           Out-File $GrpFile -Color Red -encoding ASCII -append
Tip 5: If you want all the (names) of the GroupMembers to show up in the export, add some lines in the
           script fafter line 13 with a cumulative build up of parameters to a new string that exported. Something like:
                                  $Uname = new-object directoryservices.directoryentry("LDAP://$member")
                                  $SummLine = "`""
                                  $SummLine +=$Uname.sAMAccountName
                                  $SummLine += "`",`""
                                  $SummLine += $Uname.displayName
                                  $SummLine += "`",`""
                                  $SummLine += $Uname.userPrincipalName
                                  $SummLine += "`""
                                  $SummLine | Out-File $GrpFile -encoding ASCII -append
           You will be surprised be the result I guess. Just import the result in an excelsheet!

Tip 6: Schedule this script on a monthly bases to prove the differences in license related security groups.
           Use the %date% parameter in the export-file to recognize the running date and preventing overrides.

Have fun, using Microsoft Powershell !



Ben OostdamBen Oostdam has been working with Windows systems since 1993. Worked for several companies as a system administrator, and is currently a Senior Support Engineer for a large company in the Netherlands.

Disclaimer: The information contained in this website/article is for general information purposes only. The information is provided as is, by Ben Oostdam and while we endeavour to keep the information up to date and correct, we make no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the website or the information, products, services, or related graphics contained on the website for any purpose. Any reliance you place on such information is therefore strictly at your own risk. In no event will we be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this website. Through this website you are sometimes able to link to other websites which are not under my control. I have no control over the nature, content and availability of those sites. The inclusion of any links does not necessarily imply a recommendation or endorse the views expressed within them. Every effort is made to keep the website up and running smoothly. However, I take no responsibility for, and will not be liable for, the website being temporarily unavailable due to technical issues beyond our control. All entries in these articles, are my individual opinion, or from co-writers and they don't necessary reflect the opinion of my employer.


Friday the 7th, May 2021. All rights reserved.. // Oostdam WebDesign