BitTitan.Runbooks.ExchangeOnline.psm1
<#
.SYNOPSIS PowerShell module for common Exchange Online functions and resources used in BitTitan Runbooks. .NOTES Version: 0.2.1 Last updated: 23 October 2018 Copyright (c) BitTitan, Inc. All rights reserved. Licensed under the MIT License. #> # Install/import BitTitan.Runbooks.Modules to bootstrap the install/import of the other modules Install-Module BitTitan.Runbooks.Modules -Scope CurrentUser -AllowClobber Import-Module BitTitan.Runbooks.Modules -Force # Install/import the other BitTitan.Runbooks modules Import-BT_Module BitTitan.Runbooks.MSPComplete 1>$null <# .SYNOPSIS This function connects to Exchange Online using admin account credentials or a MSPComplete Endpoint. .DESCRIPTION This function connects to Exchange Online using admin account credentials or a MSPComplete Endpoint. It returns whether the connection and logon was successful. .PARAMETER username The username of the Exchange Online admin account. .PARAMETER password The password of the Exchange Online admin account. .PARAMETER endpoint The MSPComplete Endpoint for the Exchange Online admin credentials. This endpoint can be masked or unmasked. .EXAMPLE Connect-ExchangeOnlineAdminAccount -Endpoint $Endpoint .EXAMPLE $Endpoint | Connect-ExchangeOnlineAdminAccount .EXAMPLE Connect-ExchangeOnlineAdminAccount -Username $username -Password $password #> function Connect-ExchangeOnlineAdminAccount { param ( # The username of the Exchange Online admin account. [Parameter(Mandatory=$true, ParameterSetName="credential")] [string]$username, # The password of the Exchange Online admin account. [Parameter(Mandatory=$true, ParameterSetName="credential")] [SecureString]$password, # The MSPComplete Endpoint for the Exchange Online admin credentials. [Parameter(Mandatory=$true, ParameterSetName="endpoint", ValueFromPipeline=$true)] $endpoint, # The maximum number of logon attempts. Each logon attempt can take up to 60 seconds. [Parameter(Mandatory=$false)] [ValidateScript({ $_ -gt 1 })] [Int]$maximumAttempts = 5 ) # If given endpoint, retrieve username and password if ($PSCmdlet.ParameterSetName -eq "endpoint") { $exchangeCredential = $endpoint | Get-CredentialFromMSPCompleteEndpoint $username = $exchangeCredential.Username } # Create the Exchange Online credential from the given username and password else { $exchangeCredential = New-Object System.Management.Automation.PSCredential($username, $password) } # Logon to Exchange Online $attemptNum = 0 while ($true) { try { $exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange ` -ConnectionUri https://outlook.office365.com/powershell-liveid/ ` -Credential $exchangeCredential -Authentication Basic -AllowRedirection -Name "ExchangeOnline" ` -ErrorVariable errorOutput if (![String]::IsNullOrWhiteSpace($errorOutput)) { Write-Host "Error output: $($errorOutput)" } # Additional Import-Module ensures that imported cmdlets are visible globally Import-Module (Import-PSSession -Session $exchangeSession -DisableNameChecking -AllowClobber) -Global # Logon was successful Write-Information "Logon to Exchange Online successful with username '$($username)'." return $true } catch { # Check if error was due to too many runspaces if ($errorOutput -like "*Fail to create runspace because you have exceeded your budget to create runspace*") { $attemptNum += 1 if ($attemptNum -eq $maximumAttempts) { return $false } Write-Host "Encountering throttling when connecting to Exchange Online. Waiting 60 seconds, then attempting again. (attempt $($attemptNum)/$($maximumAttempts))" # Wait 60 seconds and try to connect again Start-Sleep -Seconds 60 continue } # Logon was unsuccessful due to other error Write-Error "Failed Exchange Online logon with username '$($username)'.`r`n$($_.Exception.Message)" return $false } } } <# .SYNOPSIS This function disconnects from the current Exchange Online session. .DESCRIPTION This function disconnects from the current Exchange Online session It returns whether the disconnect was successful. #> function Disconnect-ExchangeOnline { # Retrieve sessions $exchangeOnlineSession = Get-PSSession | Where-Object { $_.Name -eq "ExchangeOnline" } # There is at least one existing session if ($null -ne $exchangeOnlineSession) { # There is more than one existing session if ($null -ne $exchangeOnlineSession.length -and $exchangeOnlineSession.length -gt 1) { foreach ($session in $exchangeOnlineSession) { $session | Remove-PSSession } } # There is only one existing session else { $exchangeOnlineSession | Remove-PSSession } return $true } # There are no existing sessions else { Write-Warning "Attempting to disconnect Exchange Online session when there isn't one running." return $false } } |