Security Audit

Automating Active Directory: Export All AD Groups and Members to CSV

Posted on Updated on

Auditing Active Directory groups is a fundamental part of identity management. Whether you are performing a quarterly security review or preparing for a domain migration, knowing exactly who is in which group—and what the scope of those groups is—is essential.

This PowerShell script does more than just list group names; it iterates through every group in your domain, identifies the members (skipping disabled users to keep your data clean), and exports everything into a dated CSV file.


The PowerShell Script

Save this script as ADGroupsExport.ps1 in C:\Temp\ExportADgroups. Ensure you are running this from a machine with the RSAT (Remote Server Administration Tools) installed and logged in with a domain account that has read permissions.

PowerShell
# Get year and month for the filename
$DateTime = Get-Date -f "yyyy-MM"
# Set CSV file destination
$CSVFile = "C:\Temp\ExportADgroups\AD_Groups_"+$DateTime+".csv"
if (!(Test-Path "C:\Temp\ExportADgroups")) { New-Item -ItemType Directory -Path "C:\Temp\ExportADgroups" }
$CSVOutput = @()
# Fetch all AD groups
$ADGroups = Get-ADGroup -Filter *
$i = 0
$tot = $ADGroups.count
foreach ($ADGroup in $ADGroups) {
$i++
$status = "{0:N0}" -f ($i / $tot * 100)
Write-Progress -Activity "Exporting AD Groups" -status "Processing Group $i of $tot : $status% Completed" -PercentComplete ($i / $tot * 100)
$Members = ""
# Fetch members and filter for enabled objects
$MembersArr = Get-ADGroup $ADGroup.DistinguishedName -Properties Member | Select-Object -ExpandProperty Member
if ($MembersArr) {
foreach ($Member in $MembersArr) {
$ADObj = Get-ADObject -Filter "DistinguishedName -eq '$Member'" -Properties Enabled
# Skip disabled users to keep the report relevant
if ($ADObj.ObjectClass -eq "user" -and $ADObj.Enabled -eq $false) {
continue
}
$Members = $Members + "," + $ADObj.Name
}
if ($Members) {
$Members = $Members.Substring(1)
}
}
# Create ordered hash table for clean CSV columns
$HashTab = [ordered]@{
"Name" = $ADGroup.Name
"Category" = $ADGroup.GroupCategory
"Scope" = $ADGroup.GroupScope
"Members" = $Members
}
$CSVOutput += New-Object PSObject -Property $HashTab
}
# Sort by name and export
$CSVOutput | Sort-Object Name | Export-Csv $CSVFile -NoTypeInformation
Write-Host "Export Complete: $CSVFile" -ForegroundColor Green

Key Features of this Script

  • Progress Bar: Since large domains can take a long time to process, the Write-Progress bar gives you a real-time percentage of the completion.
  • Clean Membership Lists: The script concatenates all members into a single “Members” column, separated by commas, making it easy to read in Excel.
  • Disabled User Filtering: It intelligently checks the Enabled status of user objects. If a user is disabled, they are omitted from the report to focus on active security risks.
  • Scope & Category: Clearly identifies if a group is Security vs. Distribution and Global vs. Universal.

#ActiveDirectory #PowerShell #SysAdmin #ITAutomation #WindowsServer #IdentityManagement #LazyAdmin #TechTips #Reporting #CyberSecurity

How to Export Folder and Share Permissions to CSV via PowerShell

Posted on Updated on

Auditing file share permissions is a critical task for security and compliance. While the Windows GUI allows you to view permissions one folder at a time, it is impossible to get a “big picture” view without automation.

By using the Get-Acl (Access Control List) cmdlet in PowerShell, you can recursively scan a directory and export every user and group permission to a clean CSV file for review in Excel.


The PowerShell Script

Save the following code as ExportFolderPermissions.ps1. Before running it, ensure you update the $FolderPath and the output path for the CSV file.

PowerShell
# Define the source path (Local folder or UNC Share)
$FolderPath = dir -Directory -Path "\\ServerName\SharePath" -Recurse -Force
$Report = @()
Foreach ($Folder in $FolderPath) {
# Fetch the Access Control List for the current folder
$Acl = Get-Acl -Path $Folder.FullName
foreach ($Access in $acl.Access) {
# Create an ordered object for each permission entry
$Properties = [ordered]@{
'FolderName' = $Folder.FullName
'AD Group or User' = $Access.IdentityReference
'Permissions' = $Access.FileSystemRights
'Inherited' = $Access.IsInherited
}
$Report += New-Object -TypeName PSObject -Property $Properties
}
}
# Export the final report to CSV
$Report | Export-Csv -Path "C:\Temp\FolderPermissions.csv" -NoTypeInformation

How the Script Works

  1. dir -Recurse: This command crawls through every subfolder within your target directory. The -Directory switch ensures we only look at folders, not individual files (which would make the report massive).
  2. Get-Acl: This retrieves the security descriptor for the folder, including who has access and what specific rights they have (Read, Write, Full Control, etc.).
  3. PSObject: We bundle the folder name, user identity, and rights into a custom object so that Export-Csv can easily format them into columns.
  4. IdentityReference: This shows you the exact AD Group or User name assigned to that folder.

💡 Lazy Admin Tips

  • Run as Admin: You must run PowerShell as an Administrator and have “Read Permissions” rights on the target folders, or the script will return “Access Denied” errors.
  • Performance: Scanning thousands of subfolders over a slow network link can take time. If you have a massive file server, run the script locally on the server itself rather than over a mapped drive.
  • Filter Results: Once you open the CSV in Excel, use Filters to quickly find “Everyone” or “Anonymous” permissions, or to see which folders have inheritance disabled.

#PowerShell #SysAdmin #ActiveDirectory #SecurityAudit #WindowsServer #ITPro #Coding #LazyAdmin #CyberSecurity #TechTips

Deep Audit: Listing Nested Active Directory Group Members via VBScript | Lazy Admin Blog

Posted on Updated on

Have you ever looked at a “Domain Admins” group and thought it looked suspiciously small? The culprit is usually nesting. Standard AD queries often fail to “recurse,” meaning they show you the subgroup but not the people inside it.

This script, ListGroupMembers_IncludingNested.vbs, uses a recursive function to dive into every sub-group and extract the actual users, ensuring your security audits are 100% accurate.

The Script: How it Works

The script utilizes a Dictionary Object to keep track of groups it has already scanned. This is a critical “Lazy Admin” safety feature—it prevents the script from getting stuck in an infinite loop if two groups are members of each other.

Usage Instructions

  1. Copy the code below into Notepad.
  2. Edit the StrGroupName variable to match your target group.
  3. Save the file as ListGroupMembers.vbs.
  4. Run it from the command prompt using cscript ListGroupMembers.vbs.
VBScript
' -- Save as ListGroupMembers_IncludingNested.vbs
Option Explicit
Dim ObjRootDSE, ObjConn, ObjRS, ObjCustom
Dim StrDomainName, StrGroupName, StrSQL, StrGroupDN, StrEmptySpace
Set ObjRootDSE = GetObject("LDAP://RootDSE")
StrDomainName = Trim(ObjRootDSE.Get("DefaultNamingContext"))
' -- Edit the line below with your Group Name
StrGroupName = "YourGroupNameHere"
StrSQL = "Select ADsPath From 'LDAP://" & StrDomainName & "' Where ObjectCategory = 'Group' AND Name = '" & StrGroupName & "'"
Set ObjConn = CreateObject("ADODB.Connection")
ObjConn.Provider = "ADsDSOObject": ObjConn.Open "Active Directory Provider"
Set ObjRS = ObjConn.Execute(StrSQL)
If ObjRS.EOF Then
WScript.Echo "Group not found: " & StrGroupName
Else
StrGroupDN = Trim(ObjRS.Fields("ADsPath").Value)
Set ObjCustom = CreateObject("Scripting.Dictionary")
GetAllNestedMembers StrGroupDN, " ", ObjCustom
End If

Why VBScript in 2026?

While PowerShell is the modern standard, many legacy environments and automated scheduled tasks still rely on VBScript because it requires zero execution policy changes and runs natively on every Windows machine since Server 2000. It is the “Old Reliable” of the AD world.

Key Features of this Script

  • Recursive Discovery: It doesn’t just stop at the first layer.
  • Class Identification: Clearly marks if a member is a User, Computer, or another Group.
  • Loop Protection: Uses the Scripting.Dictionary to escape circular nesting traps.

#ActiveDirectory #WindowsServer #CyberSecurity #SysAdmin #ITAudit #VBScript #Automation #LazyAdmin #TechArchive