Cleaning Up Those Pesky Distribution Lists

In the past I wrote a script that would cleanup Distribution Lists in Exchange 2010. My original post can be found HERE. In the newest version I’ve changed the ‘Get-TransportServer’ and replaced it with ‘Get-TransportService’ as Microsoft has deprecated ‘Get-TransportServer’ in Exchange 2013/2016. I’ve also cleaned up the code, put more comments in and added a variable table to make modifying this script a bit easier. Other than that it operates like the Exchange Server 2010 version of the script.

NOTES

There will be an Office 365 version coming soon that will scan Office 365 as well as your Hybrid server for mail traffic to distribution lists. This script will also run the same sort of process of marking the CustomAttribute10 to keep track of active/inactive groups. Look for it this week.

Second, and more importantly, I have not added support for Dynamic Distribution groups. Only groups that can be found via ‘Get-DistributionGroup’ are included at this time. The plan is to add that feature, but is on the backburner until I get the Office 365 version of the script completed.

Source Code
I’ve posted the code here and on the TechNet Gallery for you to download and use.–> Download Link

<#  
.SYNOPSIS  
	Distribution Group Cleanup Script - for Exchange 2013 and 2016
 
.DESCRIPTION  
	This script will cleanup all distribution lists that have not been used within a certain timeframe.
 
.NOTES  
    Version					: 1.1
    Date Created			: 05/02/2016
    Change Log			 	: 1.1 - Change 'GetTransportServer' to 'Get-TransportService' and added a variable list for $To, $From and $SMTPServer
				 			: 1.0 - Script first set up
    Wish list				: HTML Report to IT?
    Rights Required			: Local admin on server
    Sched Task Req'd		: No
    Exchange Version		: 2013 / 2016
    Author					: Damian Scoles
    Dedicated Blog			: https://justaucguy.wordpress.com/
    Disclaimer				: You are on your own.  This was not written by, support by, or endorsed by Microsoft.
    Code stolen from		: None 

.EXAMPLE
        .\Run-DistributionGroupCleanup.ps1
		To be run once per month as a recurring task
 
.INPUTS
		None. You cannot pipe objects to this script.
#>

# Global variable section

# Testing Dates - use this for finding older results
# $onemonth = ((get-date).addmonths(-13))
# $current = ((get-date).addmonths(-12))

# Production Dates
$current = get-date
$onemonth = ((get-date).addmonths(-1))

# Arrays
$activegroups2 = @()
$activegroups = @()
$inactivegroups = @()
$allgroups = @()
$smtp = @()

# Other Variables - below are samples, make sure to change for your environment
$from = "Notifications@16-lg.local"
$SMTPServer = "192.168.0.190"
$to = "damian@16-lg.local"
$AdminAddress = "damian@16-lg.local"

# Load AD Module for PowerShell
import-module activedirectory

function mail-managerhidden ($groupsmtpaddress) {
	$manager = ((get-distributiongroup $groupsmtpaddress).managedby)
	$manager | foreach {
		$mgr = $_.name
		$smtp4 = (get-mailbox $mgr).emailaddresses
		$smtp4 | foreach {
			$smtp3 = $_.smtpaddress
			$smtp3
		}
		$smtp += @($smtp3)
	}
	$DLName =  (get-distributiongroup $groupsmtpaddress).displayname
	[string] $body = "<strong>NOTIFICATION</strong><BR><BR>As a part of regular maintanence, IT has decided to monitor the usage of Distribution # Lists.<BR><BR>This email is a notification that an Email Distribution Group that you manage has been inactive for 6 months. Because of this level of inactivity, the group has been hidden from the Global Address List. Please check this list to see if it is still valid or not.<BR><BR>Please send an email to $AdminAddress if the list is no longer needed.   Thanks for you assistance with this matter."
	foreach ($line in $smtp) {
   	     $messageParameters = @{
		Subject = "Distribution Group Manager Alert - Inactive Distribution Group - $DLName"
		Body = $body
		From = "$from"
		To = $line
		SmtpServer = "$SMTPServer"
             }
                Send-MailMessage @messageParameters –BodyAsHtml
	}
}

function mail-managerdisabled ($groupsmtpaddress) {
	$manager = ((get-distributiongroup $groupsmtpaddress).managedby)
	$manager | foreach {
		$mgr = $_.name
		$smtp2 = (get-mailbox $mgr).emailaddresses
		$smtp2 | foreach {
			$smtp3 = $_.smtpaddress
		}
		$smtp += @($smtp3)
	}
	$DLName =  (get-distributiongroup $groupsmtpaddress).displayname
	[string] $body = "<strong>NOTIFICATION</strong><BR><BR>As a part of regular maintanence, IT has decided to monitor the usage of Distribution # Lists.<BR><BR>This email is a notification that an Email Distribution Group that you manage has been inactive for over 12 months. This Distribiution group has been deleted.<BR><BR>Please send an email to $AdminAddress if you have any questions.   Thanks for you assistance with this matter."
	foreach ($line in $smtp) {
 	     $messageParameters = @{
  		Subject = "Distribution Group Manager Alert - Removed Distribution Group - $DLName"
		Body = $body
		From = "$from"
		To = $line
		SmtpServer = "$SMTPServer"
                }
                Send-MailMessage @messageParameters –BodyAsHtml
	     }
}

function emailIT-Groupremoval ($groupsmtpaddress) {
	$DLName =  (get-distributiongroup $groupsmtpaddress).displayname
	[string] $body = "<strong>NOTIFICATION</strong><BR><BR>As a part of regular maintanence this group was disabled.  The group has been inactive for 12 months per the DL Cleanup Script. Confirm that this list can be deleted and remove it from AD."
	$messageParameters = @{
		Subject = "Distribution Group - IT Alert - Removed Distribution Group - $DLName"
		Body = $body
		From = "$from"
		to = "$to"
		SmtpServer = "$SMTPServer"
                }
	Send-MailMessage @messageParameters –BodyAsHtml
}
	
# Get a list of the active groups
$servers = get-transportservice
foreach ($name in $servers) {
     $activegroups2 += (Get-MessageTrackingLog -Server $name.name -EventId Expand -ResultSize Unlimited -start $onemonth -end $current | Sort-Object RelatedRecipientAddress | Group-Object RelatedRecipientAddress | Sort-Object Name | select-object name)
}

$activegroups2 = $activegroups2 | sort-object name | group-object name
foreach ($line in $activegroups2) {
	$activegroups += $line.name
}

# Get a list of all groups
$allgroups2 = get-distributiongroup -resultsize unlimited | Select-Object -Property @{Label="Name";Expression={$_.PrimarySmtpAddress}}
foreach ($line in $allgroups2) {
	$allgroups += $line.name
}

# Find inactive groups by comparing active groups to all groups
$InactiveGroups2 = Compare-Object $activegroups $allgroups
foreach ($line in $inactivegroups2) {
	$smtp2=$line.inputobject
	$address=$smtp2.local+"@"+$smtp2.domain
	$inactivegroups += $address
}

# Set custom attribute 10 for active groups to 0
foreach ($line in $ActiveGroups){
 	set-distributiongroup -identity $line -CustomAttribute10 0 -warningaction silentlycontinue
}

# Set custom attribute 10 for inactive groups - increase by 1
# Hide or disable group
foreach ($line in $InactiveGroups){
		[string]$email = $line
		[int]$number = (get-distributiongroup -identity $email).CustomAttribute10
		$number += 1
		set-distributiongroup -identity $email -CustomAttribute10 $number 
		if ($number -eq 6) {
			$notes = "$current - Hidden from address list due to inactive use."
			Set-Group -identity $email -notes $notes
			Set-DistributionGroup -identity $email -HiddenFromAddressListsEnabled $true

			# Email manager - group hidden
			mail-managerhidden $email
		}
		if ($number -eq 12) {
			# Email manager and IT of group removal
			mail-managerdisabled $email
			emailIT-Groupremoval $email

			# Disable the group
			$notes = "$current - No longer Mail Enabled due to inactive use."
			Set-Group -identity $email -notes $notes
			Disable-DistributionGroup -identity $email -Confirm:$false
		}
}
Advertisements

2 thoughts on “Cleaning Up Those Pesky Distribution Lists

  1. Hey, the description in the beginning of the script is wrong. It says ” This script will cleanup all SCRIPTS that have not been used within a certain timeframe.”
    Also, in the synopsis it says “Exchange 203” 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s