ExO-EnableMailboxAuditLogging.ps1

<#PSScriptInfo
.VERSION 1.0
.GUID 911b3916-2a11-4e53-977b-3992fc89d977
.AUTHOR Soren Lindevang
.COMPANYNAME
.COPYRIGHT
.TAGS PowerShell Exchange Online Office 365 Logging Logs Audit Auditing Azure Automation
.LICENSEURI
.PROJECTURI
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
#>


<#
.SYNOPSIS
    Enabling mailbox audit log on all Exchange Online mailboxes. Designed for execution in Azure Automation
 
    No warranties. Use at your own risk.
 
.DESCRIPTION
    This script enables audit logging for all mailboxes in the connected Exchange Online tenant.
 
    The audit log level can be configured to either 'full' or 'default' for all tree logon types (Administrator, Delegate, Owner).
 
    The audit log age can be set as well.
 
    This script will only work in a Azure Automation runbook.
 
.PARAMETER AuditLogLevel
    Audit log level of all three logon types (Administrator, Delegate, Owner) to be set on all mailboxes.
 
    Only two valid inputs; 'Default' and 'Full'.
 
    'Default': The default audit log setting on mailbox creation.
 
    'Full': All possible actions are logged.
 
    List of actions to be audit logged: https://technet.microsoft.com/en-us/library/ff459237(v=exchg.160).aspx.
 
    Default value: 'Default'.
 
.PARAMETER AuditLogAgeLimit
    Determines how long audit log entries will be retained (in days) on all mailboxes
 
    Default value: 90.
 
.PARAMETER AutomationPSCredentialName
    Name of the Automation Credential used when connecting to Exchange Online.
 
    The Account should at least have "Audit Log" rights in the Exchange Online tenant.
 
.PARAMETER ForceUpdate
    If this switch is present, the script will force a 'Set' command, regardless of whether the log settings match the desired settings or not.
 
.INPUTS
    N/A
 
.OUTPUTS
    N/A
 
.NOTES
    Version: 1.0
    Author: Soren Greenfort Lindevang
    Creation Date: 30.03.2018
    Purpose/Change: Initial script development
   
.EXAMPLE
    Enable Audit Logging on all mailboxes, at default logging level and default log age limit (90 days)
    ExO-EnableMailboxAuditLogging -AutomationPSCredentialName 'ExchangeServiceAccount'
     
.EXAMPLE
    Enable Audit Logging on all mailboxes, at full logging level and custom log age limit (180 days)
    ExO-EnableMailboxAuditLogging -AuditLogAgeLimit "Full" -AuditLogLevel 180 -AutomationPSCredentialName 'ExchangeServiceAccount'
 
.EXAMPLE
    Enable Audit Logging on all mailboxes, at full logging level and custom log age limit (365 days). Will force a change to all mailboxes
    ExO-EnableMailboxAuditLogging -AuditLogAgeLimit "Full" -AuditLogLevel 365 -AutomationPSCredentialName 'ExchangeServiceAccount' -ForceUpdate
#>

[cmdletbinding()]
param (
    [Parameter(
        Mandatory=$true)]
        [ValidateSet("Default","Full")]
        [string]$AuditLogLevel = "Default",

    [Parameter(
        Mandatory=$true)]
        [int]$AuditLogAgeLimit = 90,
  
    [Parameter(
        Mandatory=$true)]
        [string]$AutomationPSCredentialName,

    [Parameter(
        Mandatory=$false)]
        [switch]$ForceUpdate    
)

#-----------------------------------------------------------[Functions]------------------------------------------------------------

# Test if script is running in Azure Automation
function Test-AzureAutomationEnvironment
    {
    if ($env:AUTOMATION_ASSET_ACCOUNTID)
        {
        Write-Verbose "This script is executed in Azure Automation"
        }
    else
        {
        $ErrorMessage = "This script is NOT executed in Azure Automation."
        throw $ErrorMessage
        }
    }

# Connect to Exchange Online
function Connect-ExchangeOnline 
    {
    param ($Creds)
    try
        {
        Write-Output "Connecting to Exchange Online"
        Get-PSSession | Remove-PSSession       
        $Session = New-PSSession â€“ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Creds `
            -Authentication Basic -AllowRedirection
        $Commands = @("Set-Mailbox","Get-Mailbox")
        Import-PSSession -Session $Session -DisableNameChecking:$true -AllowClobber:$true -CommandName $Commands | Out-Null
        }
    catch 
        {
        Write-Error -Message $_.Exception
        throw $_.Exception
        }
    Write-Verbose "Successfully connected to Exchange Online"
    }

# Disconnect to Exchange Online
function Disconnect-ExchangeOnline 
    {
    try
        {
        Write-Output "Disconnecting from Exchange Online"
        Get-PSSession | Remove-PSSession       
        }
    catch 
        {
        Write-Error -Message $_.Exception
        throw $_.Exception
        }
    Write-Verbose "Successfully disconnected from Exchange Online"
    }

#----------------------------------------------------------[Declarations]----------------------------------------------------------

if ($AuditLogLevel -eq "Default")
    {
    $AuditOwner = "UpdateFolderPermissions"
    $AuditAdmin = "Create","FolderBind","HardDelete","Move","MoveToDeletedItems","SendAs","SendOnBehalf","SoftDelete","Update","UpdateFolderPermissions"
    $AuditDelegate = "Create","HardDelete","SendAs","SoftDelete","Update","UpdateFolderPermissions"
    }
elseif ($AuditLogLevel -eq "Full")
    {
    $AuditOwner = "Create","HardDelete","MailboxLogin","Move","MoveToDeletedItems","SoftDelete","Update","UpdateFolderPermissions"
    $AuditAdmin = "Copy","Create","FolderBind","HardDelete","MessageBind","Move","MoveToDeletedItems","SendAs","SendOnBehalf","SoftDelete","Update","UpdateFolderPermissions"
    $AuditDelegate = "Create","FolderBind","HardDelete","Move","MoveToDeletedItems","SendAs","SendOnBehalf","SoftDelete","Update","UpdateFolderPermissions"
    }

#-----------------------------------------------------------[Execution]-----------------------------------------------------------

Test-AzureAutomationEnvironment

Write-Output "::: Parameters :::"
Write-Output "AuditLogAgeLimit: $AuditLogAgeLimit"
Write-Output "AuditLogLevel: $AuditLogLevel"
Write-Output "ForceUpdate: $ForceUpdate"
Write-Output "AutomationPSCredentialName: $AutomationPSCredentialName"
Write-Output ""

# Get AutomationPSCredential
Write-Output "::: Connection :::"
try
    {
    Write-Output "Importing Automation Credential"
    $Credentials = Get-AutomationPSCredential -Name $AutomationPSCredentialName -ErrorAction Stop
    }
catch 
    {
    Write-Error -Message $_.Exception
    throw $_.Exception
    }
Write-Verbose "Successfully imported credentials"

# Connect to Exchange Online
Connect-ExchangeOnline -Creds $Credentials
Write-Output ""

# Check if all Cmdlets are available


# Get All Mailboxes (UserMailbox, SharedMailbox, EquipmentMailbox, RoomMailbox)
try
    {
    Write-Verbose "Importing list of mailboxes"
    $Mailboxes = Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox,EquipmentMailbox,RoomMailbox,DiscoveryMailbox -ErrorAction Stop
    }
catch 
    {
    Write-Error -Message $_.Exception
    throw $_.Exception
    }
Write-Verbose "Successfully imported list of mailboxes"

if (!$Mailboxes)
    {
    $ErrorMessage = "No mailboxes found!"
    throw $ErrorMessage
    }

# Filter mailboxes in scope for processing
$LogAgeTimeSpan = New-TimeSpan -Days $AuditLogAgeLimit
if ($ForceUpdate)
    {
    $MailboxesToProcess = $Mailboxes
    }
else
    {
    try
        {
        Write-Verbose "Filtering mailboxes in scope for processing"
        $MailboxesToProcess = $Mailboxes | Where-Object {($_.AuditLogAgeLimit -ne $LogAgeTimeSpan) -or (Compare-Object $_.AuditOwner $AuditOwner) -or `
            (Compare-Object $_.AuditAdmin $AuditAdmin) -or (Compare-Object $_.AuditDelegate $AuditDelegate)}
        }
    catch 
        {
        Write-Error -Message $_.Exception
        throw $_.Exception
        }
    Write-Verbose "Successfully filtered mailboxes"
    }

#Process Mailboxes
Write-Output "::: Process Mailboxes :::"
Write-Output "Mailboxes to process: $($MailboxesToProcess.count)"
$count = $null
Foreach ($Mailbox in $MailboxesToProcess)
    {
    try
        {
        $count++
        Write-Verbose "Mailbox: $count/$($MailboxesToProcess.count) - $($Mailbox.UserPrincipalName)"
        $Mailbox | Set-Mailbox -AuditEnabled $true -AuditOwner $AuditOwner -AuditAdmin $AuditAdmin -AuditDelegate $AuditDelegate `
            -AuditLogAgeLimit $AuditLogAgeLimit -Force
        }
    catch 
        {
        Write-Error -Message $_.Exception
        }
    }
Write-Verbose "Processing completed"
Write-Output ""

# Close Session
Disconnect-ExchangeOnline

Write-Output "Script completed"