Add 12 AI-generated PowerShell scripts with documentation
⚠️ IMPORTANT: These scripts are AI-GENERATED and UNTESTED Exchange Scripts (5): - Get-MailboxPermissions.ps1: Audit delegate access permissions - Get-InactiveMailboxes.ps1: Identify stale mailboxes - Compare-MailboxDatabases.ps1: Database health comparison - Export-DistributionGroups.ps1: Distribution group inventory - Get-MailflowStats.ps1: Transport log analysis Active Directory Scripts (3): - Get-ADUserLastLogon.ps1: True LastLogon across all DCs - Export-OUStructure.ps1: OU hierarchy with GPO links - Compare-ADGroupMemberships.ps1: Compare user group memberships System Maintenance Scripts (4): - Get-ServerInventory.ps1: Hardware/software inventory report - Monitor-DiskSpace.ps1: Disk space monitoring with alerts - Backup-ExchangeCertificates.ps1: Certificate backup to PFX - Test-ExchangeHealth.ps1: Aggregated Exchange health checks Documentation: - Updated CLAUDE.md with AI-generated scripts section - Added AI-GENERATED-SCRIPTS.md with warnings and testing guide All scripts include prominent warnings and follow established patterns from existing scripts. Require thorough testing before production use. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
163
Exchange/Export-DistributionGroups.ps1
Normal file
163
Exchange/Export-DistributionGroups.ps1
Normal file
@ -0,0 +1,163 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Export complete inventory of distribution groups with members and settings
|
||||
|
||||
.DESCRIPTION
|
||||
Documents all distribution groups including members, owners, email addresses,
|
||||
and key settings. Useful for migration planning, documentation, or backup.
|
||||
|
||||
.PARAMETER OutputFolder
|
||||
Destination folder for reports. Default: .\DistributionGroups-<date>
|
||||
|
||||
.PARAMETER IncludeMembers
|
||||
Include detailed member lists (default: $true, can be slow)
|
||||
|
||||
.PARAMETER GroupFilter
|
||||
Optional filter for specific groups (default: all)
|
||||
|
||||
.NOTES
|
||||
⚠️ AI-GENERATED SCRIPT - UNTESTED
|
||||
This script was generated by Claude AI and has not been tested in production.
|
||||
Review and test thoroughly in a non-production environment before use.
|
||||
|
||||
- Run in Exchange Management Shell with appropriate RBAC permissions
|
||||
- Large environments may take significant time
|
||||
- Includes both Distribution Groups and Mail-Enabled Security Groups
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-DistributionGroups.ps1
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-DistributionGroups.ps1 -GroupFilter "Sales*" -OutputFolder "D:\Reports\Groups"
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$OutputFolder = (Join-Path -Path (Get-Location) -ChildPath ("DistributionGroups-" + (Get-Date -Format "yyyyMMdd-HHmm"))),
|
||||
[bool]$IncludeMembers = $true,
|
||||
[string]$GroupFilter = "*"
|
||||
)
|
||||
|
||||
function NowTag { (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") }
|
||||
|
||||
Write-Host "[$(NowTag)] ⚠️ AI-GENERATED SCRIPT - UNTESTED" -ForegroundColor Yellow
|
||||
Write-Host "[$(NowTag)] Starting distribution group export..." -ForegroundColor Green
|
||||
|
||||
# Create output folder
|
||||
New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null
|
||||
|
||||
# Get distribution groups
|
||||
Write-Host "[$(NowTag)] Retrieving distribution groups..."
|
||||
$groups = Get-DistributionGroup -Filter "Name -like '$GroupFilter'" -ResultSize Unlimited -ErrorAction SilentlyContinue
|
||||
|
||||
$groupCount = ($groups | Measure-Object).Count
|
||||
Write-Host "[$(NowTag)] Found $groupCount distribution groups"
|
||||
|
||||
if ($groupCount -eq 0) {
|
||||
Write-Host "[$(NowTag)] No groups found matching filter: $GroupFilter" -ForegroundColor Yellow
|
||||
exit
|
||||
}
|
||||
|
||||
# Collect group details
|
||||
$groupDetails = @()
|
||||
$groupMembers = @()
|
||||
|
||||
$current = 0
|
||||
foreach ($group in $groups) {
|
||||
$current++
|
||||
$pct = [int](($current / $groupCount) * 100)
|
||||
Write-Progress -Activity "Processing Distribution Groups" -Status "Processing $($group.Name) ($current/$groupCount)" -PercentComplete $pct
|
||||
|
||||
# Get managed by
|
||||
$managedByList = @()
|
||||
if ($group.ManagedBy) {
|
||||
foreach ($mgr in $group.ManagedBy) {
|
||||
try {
|
||||
$mgrObj = Get-Recipient $mgr -ErrorAction SilentlyContinue
|
||||
if ($mgrObj) {
|
||||
$managedByList += $mgrObj.PrimarySmtpAddress
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
# Get email addresses
|
||||
$emailAddresses = ($group.EmailAddresses | Where-Object { $_ -like "smtp:*" }) -join "; "
|
||||
|
||||
# Get member count
|
||||
$memberCount = 0
|
||||
try {
|
||||
$members = Get-DistributionGroupMember -Identity $group.Identity -ResultSize Unlimited -ErrorAction SilentlyContinue
|
||||
$memberCount = ($members | Measure-Object).Count
|
||||
|
||||
# Collect member details if requested
|
||||
if ($IncludeMembers -and $members) {
|
||||
foreach ($member in $members) {
|
||||
$groupMembers += [PSCustomObject]@{
|
||||
GroupName = $group.Name
|
||||
GroupPrimarySmtp = $group.PrimarySmtpAddress
|
||||
MemberName = $member.Name
|
||||
MemberPrimarySmtp = $member.PrimarySmtpAddress
|
||||
MemberType = $member.RecipientType
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[$(NowTag)] WARNING: Could not get members for $($group.Name)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$groupDetails += [PSCustomObject]@{
|
||||
Name = $group.Name
|
||||
DisplayName = $group.DisplayName
|
||||
Alias = $group.Alias
|
||||
PrimarySmtpAddress = $group.PrimarySmtpAddress
|
||||
EmailAddresses = $emailAddresses
|
||||
RecipientTypeDetails = $group.RecipientTypeDetails
|
||||
MemberCount = $memberCount
|
||||
ManagedBy = ($managedByList -join "; ")
|
||||
RequireSenderAuthentication = $group.RequireSenderAuthenticationEnabled
|
||||
HiddenFromAddressLists = $group.HiddenFromAddressListsEnabled
|
||||
ModerationEnabled = $group.ModerationEnabled
|
||||
SendModerationNotifications = $group.SendModerationNotifications
|
||||
AcceptMessagesOnlyFrom = (($group.AcceptMessagesOnlyFrom | ForEach-Object { $_.ToString() }) -join "; ")
|
||||
RejectMessagesFrom = (($group.RejectMessagesFrom | ForEach-Object { $_.ToString() }) -join "; ")
|
||||
BypassModerationFromSenders = (($group.BypassModerationFromSendersOrMembers | ForEach-Object { $_.ToString() }) -join "; ")
|
||||
WhenCreated = $group.WhenCreated
|
||||
WhenChanged = $group.WhenChanged
|
||||
OrganizationalUnit = $group.OrganizationalUnit
|
||||
}
|
||||
}
|
||||
|
||||
Write-Progress -Activity "Processing Distribution Groups" -Completed
|
||||
|
||||
# Export results
|
||||
Write-Host "[$(NowTag)] Exporting results..."
|
||||
|
||||
$groupsFile = Join-Path $OutputFolder "DistributionGroups.csv"
|
||||
$groupDetails | Sort-Object Name | Export-Csv -NoTypeInformation -Encoding UTF8 -Path $groupsFile
|
||||
Write-Host "[$(NowTag)] Groups exported: $groupsFile" -ForegroundColor Green
|
||||
|
||||
if ($IncludeMembers -and $groupMembers.Count -gt 0) {
|
||||
$membersFile = Join-Path $OutputFolder "DistributionGroup-Members.csv"
|
||||
$groupMembers | Sort-Object GroupName, MemberName | Export-Csv -NoTypeInformation -Encoding UTF8 -Path $membersFile
|
||||
Write-Host "[$(NowTag)] Members exported: $membersFile" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Summary
|
||||
Write-Host "`nSUMMARY:" -ForegroundColor Cyan
|
||||
Write-Host " Total Groups: $groupCount"
|
||||
Write-Host " Total Members: $($groupMembers.Count)"
|
||||
Write-Host " Hidden from Address Lists: $(($groupDetails | Where-Object HiddenFromAddressLists).Count)"
|
||||
Write-Host " Moderation Enabled: $(($groupDetails | Where-Object ModerationEnabled).Count)"
|
||||
Write-Host " Security Groups: $(($groupDetails | Where-Object { $_.RecipientTypeDetails -like '*Security*' }).Count)"
|
||||
|
||||
# Top 10 largest groups
|
||||
$top10 = $groupDetails | Sort-Object MemberCount -Descending | Select-Object -First 10
|
||||
if ($top10) {
|
||||
Write-Host "`nTop 10 Largest Groups:" -ForegroundColor Cyan
|
||||
$top10 | ForEach-Object {
|
||||
Write-Host " $($_.Name): $($_.MemberCount) members"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n[$(NowTag)] Export complete! Output folder: $OutputFolder"
|
||||
Reference in New Issue
Block a user