I have been working on a script to document a Microsoft Exchange environment using PowerShell and while it does the job of providing the information required, some manual input is needed and the output formatting is still work in progress. Landscape view displays the information better.

The script requires Microsoft Word to be installed, I was running this from a machine with just the Exchange Management Tools and Office installed. I am looking at other methods to not require Microsoft Word but that is still work in progress.

There are two places where you need to make manual adjustments:

  • $OutputFilePath (path where you want to file to be saved)
  • $Certificates (Modify the server name and copy the line to add additional servers)

How to run the script. I simply opened up PowerShell ISE and just ran it after making changes such as the path and servers for the certificates. The bottom window does show errors, for example, I do not have public folders.

The word document will show the heading for that section but if nothing is defined, it will simply be blank.

You may want to comment out or remove the option to get all mailboxes as you will end up with a very large document but if your environment is small, it may help you.

What is captured in the word document? The following items are exported from Microsoft Exchange:

  • Databases
  • Database Copies
  • Database Availability Groups (DAG)
  • Database Availability Group Network/s
  • Journaling rules
  • Retention Policies
  • Exchange Servers
  • Send Connectors
  • Receive Connectors
  • Accepted Domains
  • Email Address Policies
  • Mailboxes
  • Distribution Groups
  • Room Mailboxes
  • Shared Mailboxes
  • Contacts
  • Public Folders
  • Certificates
  • Virtual Directories
  • Outlook Anywhere config (if set)

Here is a sample of the word document:

Exchange 2016/2019:- display the top 10 largest mailboxes

Below is the code, feel free to modify it as you need to but don’t forget to update the fields mentioned earlier:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn

# Function to create a Word document
function Create-WordDocument {
    param (
        [string]$FilePath,
        [string]$Content
    )

    $Word = New-Object -ComObject Word.Application
    $Word.Visible = $false

    $Document = $Word.Documents.Add
    $Range = $Document.Content
    $Range.Text = $Content

    $Document.SaveAs($FilePath)
    $Document.Close()
    $Word.Quit()
}

# Output file path (Update this to where you want the document to be saved)
$OutputFilePath = "C:\Installs\ExchangeDocumentation.docx"

# Get databases
$databases = Get-MailboxDatabase | Select-Object Name, Server, Mounted, DatabaseSize, AvailableNewMailboxSpace, ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota

# Get Database Availability Groups (DAGs)
$dags = Get-DatabaseAvailabilityGroup | Select-Object Name, WitnessServer, WitnessDirectory, DatabaseAvailabilityGroupIpAddresses

# Get database copies
$databaseCopies = Get-MailboxDatabaseCopyStatus * | Select-Object DatabaseName, Status, ActivationPreference, CopyQueueLength, ReplayQueueLength

# Get DAG Networks
$dagNetworks = Get-DatabaseAvailabilityGroupNetwork | Select-Object Identity, Description, Subnets

# Get journaling configuration
$journalingConfig = Get-JournalRule | Select-Object Identity, Name, JournalEmailAddress, Enabled

# Get retention policies
$retentionPolicies = Get-RetentionPolicy | Select-Object Identity, Name, RetentionEnabled, RetentionAction, RetentionComment, RetentionHoldEnabled

# Get servers
$servers = Get-ExchangeServer | Select-Object Name, ServerRole, Edition, AdminDisplayVersion

# Get send connectors
$sendConnectors = Get-SendConnector | Select-Object Identity, AddressSpaces, SourceTransportServers, Enabled, PermissionGroups, MaxMessageSize

# Get receive connectors
$receiveConnectors = Get-ReceiveConnector | Select-Object Identity, Bindings, RemoteIPRanges, Enabled, PermissionGroups, MaxMessageSize, AuthMechanism

# Get accepted domains
$acceptedDomains = Get-AcceptedDomain | Select-Object Identity, DomainName, DomainType

# Get email address policies
$emailAddressPolicies = Get-EmailAddressPolicy | Select-Object Identity, Name, Enabled, Priority, RecipientFilterType, RecipientFilter, IncludedRecipients

# Get mailbox information
$mailboxes = Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName, Alias, UserPrincipalName, PrimarySmtpAddress, ArchiveStatus, ArchiveDatabase, ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota, Database, TotalItemSize, ItemCount

# Get distribution groups and their members
$distributionGroups = Get-DistributionGroup -ResultSize Unlimited | Select-Object DisplayName, Alias, Members

# Get resources
$resources = Get-Mailbox -ResultSize unlimited -Filter "RecipientTypeDetails -eq 'RoomMailbox'" | Select-Object DisplayName, Alias

# Get contacts
$contacts = Get-MailContact -ResultSize Unlimited | Select-Object DisplayName, Alias, ExternalEmailAddress

# Get public folders
$publicFolders = Get-PublicFolder -Recurse | Select-Object Identity, ParentPath, ItemCount

# Get shared mailboxes
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited | Select-Object DisplayName, Alias, UserPrincipalName

# Get certificates with expiration date
$certificates = Get-ExchangeCertificate -server exch1 | Select-Object Thumbprint, Subject, Issuer, NotAfter | fl

# Get virtual directory information
$virtualDirectoriesautodiscover = Get-AutodiscoverVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods
$virtualdirectoriesowa = Get-OwaVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods
$virtualdirectoriesecp = Get-EcpVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods
$virtualdirectoriesoab = Get-OabVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods
$virtualdirectoriesews = Get-WebServicesVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods
$virtualdirectoriesmapi = Get-MapiVirtualDirectory | Select-Object Server, Name, InternalUrl, ExternalUrl, InternalAuthenticationMethods, ExternalAuthenticationMethods


# Get Outlook Anywhere URLs
$outlookAnywhereUrls = Get-OutlookAnywhere | Select-Object Server, ExternalHostname, ExternalClientAuthenticationMethod, InternalHostname, InternalClientAuthenticationMethod

# Build documentation content
$documentContent = @"
Exchange Environment Documentation

Databases:
$($databases | Format-Table | Out-String)

Database Availability Groups (DAGs):
$($dags | Format-Table | Out-String)

Database Copies:
$($databaseCopies | Format-Table | Out-String)

DAG Networks:
$($dagNetworks | Format-Table | Out-String)

Journaling Configuration:
$($journalingConfig | Format-Table | Out-String)

Retention Policies:
$($retentionPolicies | Format-Table | Out-String)

Servers:
$($servers | Format-Table | Out-String)

Send Connectors:
$($sendConnectors | Format-Table | Out-String)

Receive Connectors:
$($receiveConnectors | Format-Table | Out-String)

Accepted Domains:
$($acceptedDomains | Format-Table | Out-String)

Email Address Policies:
$($emailAddressPolicies | Format-Table | Out-String)

Mailboxes:
$($mailboxes | Format-Table | Out-String)

Distribution Groups and Members:
$($distributionGroups | Format-Table | Out-String)

Resources:
$($resources | Format-Table | Out-String)

Contacts:
$($contacts | Format-Table | Out-String)

Public Folders:
$($publicFolders | Format-Table | Out-String)

Shared Mailboxes:
$($sharedMailboxes | Format-Table | Out-String)

Certificates:
$($certificates | Format-Table | Out-String)

Virtual Directories:
$($virtualDirectoriesautodiscover | Format-Table | Out-String)
$($virtualDirectoriesowa  | Format-Table | Out-String)
$($virtualDirectoriesecp  | Format-Table | Out-String)
$($virtualDirectoriesoab  | Format-Table | Out-String)
$($virtualDirectoriesews  | Format-Table | Out-String)
$($virtualDirectoriesmapi  | Format-Table | Out-String)

Outlook Anywhere URLs:
$($outlookAnywhereUrls | Format-Table | Out-String)
"@

# Create and save the Word document
Create-WordDocument -FilePath $OutputFilePath -Content $documentContent

Write-Host "Exchange environment documentation has been exported to: $OutputFilePath"

Below (in the section below the code) is the expected response once all is completed:

Exchange 2016/2019:- display the top 10 largest mailboxes

Happy documenting Exchange.

    wpChatIcon

    Discover more from Everything-PowerShell

    Subscribe now to keep reading and get access to the full archive.

    Continue reading