This post will represent the first in a review of some of my original work assessing exchange online environments for my customers. Instead of blasting the whole script at you (like i did last time), i will be taking smaller chunks and explaining the ‘why’ and ‘how’ of each section in seperate posts.
Connecting securely to exchange online via powershell has evolved a lot over the past decade. With the latest exchange online powershell module and the demise of Basic Authentication comes REST API connections. The biggest advantage to this (in my opinion) is more exposure to the session and security layers. The biggest disadvantage is that there is a 15 minute timeout on every cmndlet, meaning that optimizing your scripts against a large set of objects can get complicated. We will get into that later as we explore assessing the user and mail ‘objects’ in another post. For now, lets get into this script.
Connect-ExchangeOnline
$O365Configs = @{}
Write-Host " "
Write-Host " "
Write-Host "Gather O365 configurations..."
$O365Configs.OrgConfig = $(Get-OrganizationConfig)
$O365Configs.OrgRelations = $(Get-OrganizationRelationship)
$O365Configs.FedID = $(Get-FederatedOrganizationIdentifier)
$O365Configs.FedTrust = $(Get-FederationTrust)
$O365Configs.IRM = $(Get-IRMConfiguration)
$O365Configs.MsgEncryptConfig = $(Get-OMEConfiguration)
$O365Configs.AcceptDom = $(Get-AcceptedDomain)
$O365Configs.InboundConn = $(Get-InboundConnector)
$O365Configs.OutboundConn = $(Get-OutboundConnector)
$O365Configs.Transport = $(Get-TransportConfig)
$O365Configs.AdministrativeUnit = $(Get-AdministrativeUnit)
$O365Configs.HybridMailFlow = $(Get-HybridMailflow)
$O365Configs.MigrationEndpoint = $(Get-MigrationEndpoint)
$O365Configs.RetentionPolicy = $(Get-RetentionPolicy)
$O365Configs.SharingPolicy = $(Get-SharingPolicy)
$O365Info.HIPAAStuff = $(Get-DataClassificationConfig)
$O365Configs.DLP = $(Get-DLPPolicy)
$O365Configs.FedInfo = $(ForEach ($Dom in $O365Configs.FedID.domains) {Get-FederationInformation $Dom})
$O365Configs | Export-Clixml .\O365ConfigReportXML-$($expoDate).xml -Encoding UTF8
Now lets break it down. The first thing we do is connect. For simplicity sake we are logging in interactively. (We will go over a way to login unattended in a later post.)
Connect-ExchangeOnline
Next we create a ‘hashtable’. Hashtables are a robust way of storing sets of objects. We will eventually store each cmdlet in thier own arrays within the hashtable to easily identify them later.
$O365Configs = @{}
The ‘write-hosts’ section skips two lines for formatting (blank spaces between the quotes) and pushes a screen output for a title.
Write-Host " "
Write-Host " "
Write-Host "Gather O365 configurations..."
The next section iterates through the majority of the available exchange online powershell cmdlets that are centered around its configuration, storing each in thier own array. We also get the basic ‘policy framework’ cmdlets here for reference but many of the sub properties need to be parsed out and deserve thier own article 🙂
$O365Configs.OrgConfig = $(Get-OrganizationConfig)
$O365Configs.OrgRelations = $(Get-OrganizationRelationship)
$O365Configs.FedID = $(Get-FederatedOrganizationIdentifier)
$O365Configs.FedTrust = $(Get-FederationTrust)
$O365Configs.IRM = $(Get-IRMConfiguration)
$O365Configs.MsgEncryptConfig = $(Get-OMEConfiguration)
$O365Configs.AcceptDom = $(Get-AcceptedDomain)
$O365Configs.InboundConn = $(Get-InboundConnector)
$O365Configs.OutboundConn = $(Get-OutboundConnector)
$O365Configs.Transport = $(Get-TransportConfig)
$O365Configs.AdministrativeUnit = $(Get-AdministrativeUnit)
$O365Configs.HybridMailFlow = $(Get-HybridMailflow)
$O365Configs.MigrationEndpoint = $(Get-MigrationEndpoint)
$O365Info.HIPAAStuff = $(Get-DataClassificationConfig)
$O365Configs.RetentionPolicy = $(Get-RetentionPolicy)
$O365Configs.SharingPolicy = $(Get-SharingPolicy)
$O365Configs.DLP = $(Get-DLPPolicy)
$O365Configs.FedInfo = $(ForEach ($Dom in $O365Configs.FedID.domains) {Get-FederationInformation $Dom})
That last line above reads from an object stored earlier to get the domain info it needs for this cmdlet. It then iterates through the items it finds using ‘ForEach’ then applies those findings to the cmdlet.
Finally we wrap it all up by creating a timestamp variable to apply to the filename and then export the configuration data in powershell’s cliXML file format
$expoDate = Get-Date -Format ddMMyyyy
$O365Configs | Export-Clixml .\O365ConfigReportXML-$($expoDate).xml -Encoding UTF8
WE export all the data into XML to be used offline, in any ‘Configuration as Code’ implementations, or for reporting purposes. Execute the above function inside a script file or directly as is in a powershell window.
To look at the data in powershell import the XML file that is generated then access the stored data like in this example
$testxml = import-clixml .\o365configreport.xml
$testxml
$testxml.transport
From here, I have created many nice HTML reports that can easily be disected by stakeholders. The HTML reports post will come next as it will apply to every future segment as we explore getting all mailbox data, user data, and AzureAD configurations. Until then i hope you all find this helpful.
Keep on scripting!