PSWinDocumentation.O365HealthService.psm1

function Convert-TimeToDays { 
    [CmdletBinding()]
    param ($StartTime,
        $EndTime,
        [string] $Ignore = '*1601*')
    if ($null -ne $StartTime -and $null -ne $EndTime) { try { if ($StartTime -notlike $Ignore -and $EndTime -notlike $Ignore) { $Days = (New-TimeSpan -Start $StartTime -End $EndTime).Days } } catch { } } elseif ($null -ne $EndTime) { if ($StartTime -notlike $Ignore -and $EndTime -notlike $Ignore) { $Days = (New-TimeSpan -Start (Get-Date) -End ($EndTime)).Days } } elseif ($null -ne $StartTime) { if ($StartTime -notlike $Ignore -and $EndTime -notlike $Ignore) { $Days = (New-TimeSpan -Start $StartTime -End (Get-Date)).Days } }
    return $Days
}
function Find-TypesNeeded { 
    [CmdletBinding()]
    param ($TypesRequired,
        $TypesNeeded)
    [bool] $Found = $False
    foreach ($Type in $TypesNeeded) {
        if ($TypesRequired -contains $Type) {
            $Found = $true
            break
        }
    }
    return $Found
}
function Get-Types { 
    [CmdletBinding()]
    param ([Object] $Types)
    $TypesRequired = foreach ($Type in $Types) { $Type.GetEnumValues() }
    return $TypesRequired
}
function Start-TimeLog { 
    [CmdletBinding()]
    param()
    [System.Diagnostics.Stopwatch]::StartNew()
}
function Stop-TimeLog { 
    [CmdletBinding()]
    param ([Parameter(ValueFromPipeline = $true)][System.Diagnostics.Stopwatch] $Time,
        [ValidateSet('OneLiner', 'Array')][string] $Option = 'OneLiner',
        [switch] $Continue)
    Begin { }
    Process { if ($Option -eq 'Array') { $TimeToExecute = "$($Time.Elapsed.Days) days", "$($Time.Elapsed.Hours) hours", "$($Time.Elapsed.Minutes) minutes", "$($Time.Elapsed.Seconds) seconds", "$($Time.Elapsed.Milliseconds) milliseconds" } else { $TimeToExecute = "$($Time.Elapsed.Days) days, $($Time.Elapsed.Hours) hours, $($Time.Elapsed.Minutes) minutes, $($Time.Elapsed.Seconds) seconds, $($Time.Elapsed.Milliseconds) milliseconds" } }
    End {
        if (-not $Continue) { $Time.Stop() }
        return $TimeToExecute
    }
}
Add-Type -TypeDefinition @"
    using System;
 
    namespace PSWinDocumentation
    {
        [Flags]
        public enum Office365Health {
            All,
            Services,
            ServicesExtended,
            CurrentStatus,
            CurrentStatusExtended,
            HistoricalStatus,
            HistoricalStatusExtended,
            MessageCenterInformation,
            MessageCenterInformationExtended,
            Incidents,
            IncidentsExtended,
            PlannedMaintenance,
            PlannedMaintenanceExtended,
            Messages
        }
    }
"@

function Connect-O365ServiceHealth {
    [CmdLetbinding()]
    param(
        [string][alias('ClientID')] $ApplicationID,
        [string][alias('ClientSecret')] $ApplicationKey,
        [string] $TenantDomain,
        [switch] $TlsDefault
    )
    $Body = @{
        grant_type    = "client_credentials"
        resource      = "https://manage.office.com"
        client_id     = $ApplicationID
        client_secret = $ApplicationKey
    }
    try {
        if (-not $TlsDefault) {
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        }
        $Authorization = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$($TenantDomain)/oauth2/token?api-version=1.0" -Body $body -ErrorAction Stop
    } catch {
        $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
        Write-Warning -Message "Connect-O365ServiceHealth - Error: $ErrorMessage"
    }
    if ($Authorization) {
        @{'Authorization' = "$($Authorization.token_type) $($Authorization.access_token)" }
    } else {
        $null
    }
}
function ConvertFrom-UTCTime {
    [CmdLetbinding()]
    param(
        [Object] $Time,
        [switch] $ToLocalTime
    )
    if ($null -eq $Script:TimeZoneBias) {
        $TimeZoneBias = (Get-CimInstance -ClassName Win32_TimeZone).Bias
    } else {
        $TimeZoneBias = $Script:TimeZoneBias
    }
    if ($Time -is [DateTime]) {
        $ConvertedTime = $Time
    } else {
        if ($null -eq $Time -or $Time -eq '') {
            return
        } else {
            $NewTime = $Time -replace ', at', '' -replace 'UTC', '' -replace 'at' -replace '(^.+?,)'
            try {
                [DateTime] $ConvertedTime = [DateTime]::Parse($NewTime)
            } catch {
                Write-Warning "ConvertFrom-UTCTime - couldn't convert time. Please report on GitHub - $Time. Skipping conversion..."
                return $Time
            }
        }
    }
    if ($ToLocal) {
        $ConvertedTime.AddMinutes($TimeZoneBias)
    } else {
        $ConvertedTime
    }
}
function Get-Office365ServiceHealthCurrentStatus {
    [CmdLetbinding()]
    param(
        [System.Collections.IDictionary] $Authorization,
        [string] $TenantDomain,
        [switch] $ToLocalTime
    )
    try {
        $CurrentStatus = (Invoke-RestMethod -Uri "https://manage.office.com/api/v1.0/$($TenantDomain)/ServiceComms/CurrentStatus" -Headers $Authorization -Method Get)
    } catch {
        $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
        Write-Warning -Message "Get-Office365ServiceHealthCurrentStatus - Error: $ErrorMessage"
        return
    }
    $Output = @{ }
    $Output.Simple = foreach ($Status in $CurrentStatus.Value) {
        [PSCustomObject][ordered] @{
            #ID = $Status.ID
            Service       = $Status.WorkloadDisplayName
            #Status = $Status.Status
            ServiceStatus = $Status.StatusDisplayName
            StatusTime    = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Status.StatusTime
            IncidentIds   = $Status.IncidentIds -join ', '
            #Workload = $Status.Workload
        }
    }

    $Output.Extended = foreach ($Status in $CurrentStatus.Value) {
        foreach ($Feature in  $Status.FeatureStatus) {
            [PSCustomObject][ordered] @{
                #ID = $Status.ID
                Service       = $Status.WorkloadDisplayName
                ServiceStatus = $Status.StatusDisplayName
                Feature       = $Feature.FeatureDisplayName
                FeatureStatus = $Feature.FeatureServiceStatusDisplayName
                IncidentIds   = $Status.IncidentIds -join ', '
                #Status = $Status.Status
                StatusTime    = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Status.StatusTime
                #Workload = $Status.Workload
                #FeatureName = $Feature.FeatureName
                #FeatureServiceStatus = $Feature.FeatureServiceStatus

            }
        }
    }
    return $Output
}
function Get-Office365ServiceHealthHistoricalStatus {
    [CmdLetbinding()]
    param(
        [System.Collections.IDictionary] $Authorization,
        [string] $TenantDomain,
        [switch] $ToLocalTime
    )
    try {
        $HistoricalStatus = (Invoke-RestMethod -Uri "https://manage.office.com/api/v1.0/$($TenantDomain)/ServiceComms/HistoricalStatus" -Headers $Authorization -Method Get)
    } catch {
        $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
        Write-Warning -Message "Get-Office365ServiceHealthHistoricalStatus - Error: $ErrorMessage"
        return
    }

    $Output = @{ }
    $Output.Simple = foreach ($Status in $HistoricalStatus.Value) {
        $StatusTime = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Status.StatusTime
        [PSCustomObject][ordered] @{
            #ID = $Status.ID
            Service       = $Status.WorkloadDisplayName
            ServiceStatus = $Status.StatusDisplayName
            IncidentIds   = $Status.IncidentIds -join ', '
            #Status = $Status.Status

            StatusTime    = $StatusTime
            StatusDaysAgo = Convert-TimeToDays -StartTime $StatusTime -EndTime $Script:Today
            #Workload = $Status.Workload

        }
    }
    $Output.Extended = foreach ($Status in $HistoricalStatus.Value) {
        foreach ($Feature in  $Status.FeatureStatus) {
            $StatusTime = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Status.StatusTime
            [PSCustomObject][ordered] @{
                #ID = $Status.ID
                Service       = $Status.WorkloadDisplayName
                ServiceStatus = $Status.StatusDisplayName
                Feature       = $Feature.FeatureDisplayName
                FeatureStatus = $Feature.FeatureServiceStatusDisplayName
                IncidentIds   = $Status.IncidentIds -join ', '
                #Status = $Status.Status
                StatusTime    = $StatusTime
                StatusDaysAgo = Convert-TimeToDays -StartTime $StatusTime -EndTime $Script:Today
                #Workload = $Status.Workload
                #FeatureName = $Feature.FeatureName
                #FeatureServiceStatus = $Feature.FeatureServiceStatus

            }
        }
    }
    return $Output
}
function Get-Office365ServiceHealthMessages {
    [CmdLetbinding()]
    param(
        [System.Collections.IDictionary] $Authorization,
        [string] $TenantDomain,
        [switch] $ToLocalTime
    )
    try {
        $AllMessages = (Invoke-RestMethod -Uri "https://manage.office.com/api/v1.0/$($TenantDomain)/ServiceComms/Messages" -Headers $Authorization -Method Get)
    } catch {
        $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
        Write-Warning -Message "Get-Office365ServiceHealthMessages - Error: $ErrorMessage"
        return
    }
    $Output = @{ }
    $Simple = foreach ($Message in $AllMessages.Value) {
        $LastUpdatedTime = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Message.LastUpdatedTime
        [PSCustomObject][ordered] @{
            Id                      = $Message.Id
            Title                   = $Message.Title
            ImpactDescription       = $Message.ImpactDescription
            LastUpdatedTime         = $LastUpdatedTime
            LastUpdatedDaysAgo      = Convert-TimeToDays -StartTime $LastUpdatedTime -EndTime $Script:Today
            MessageType             = $Message.MessageType
            Status                  = $Message.Status
            Severity                = $Message.Severity
            StartTime               = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Message.StartTime

            #Workload = $Message.Workload
            Workload                = $Message.WorkloadDisplayName
            ActionType              = $Message.ActionType
            Classification          = $Message.Classification
            EndTime                 = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Message.EndTime
            #Feature = $Message.Feature
            Feature                 = $Message.FeatureDisplayName
            UserFunctionalImpact    = $Message.UserFunctionalImpact
            PostIncidentDocumentUrl = $Message.PostIncidentDocumentUrl
            AffectedTenantCount     = $Message.AffectedTenantCount
            AffectedUserCount       = $Message.AffectedUserCount
            AffectedWorkload        = $Message.AffectedWorkloadDisplayNames -join ','
            #AffectedWorkloadNames = $Message.AffectedWorkloadNames -join ','
        }
    }

    $Extended = foreach ($Message in $AllMessages.Value) {
        $Messages = $Message.Messages
        foreach ($M in $Messages) {
            $LastUpdatedTime = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Message.LastUpdatedTime
            $PublishedTime = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $M.PublishedTime
            [PSCustomObject][ordered] @{
                Id                      = $Message.Id
                Title                   = $Message.Title
                ImpactDescription       = $Message.ImpactDescription
                LastUpdatedTime         = $LastUpdatedTime
                LastUpdatedDaysAgo      = Convert-TimeToDays -StartTime $LastUpdatedTime -EndTime $Script:Today
                MessageType             = $Message.MessageType
                Status                  = $Message.Status
                Severity                = $Message.Severity
                StartTime               = ConvertFrom-UTCTime -Time $Message.StartTime -ToLocalTime:$ToLocalTime
                Message                 = $M.MessageText
                PublishedTime           = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $M.PublishedTime
                PublishedDaysAgo        = Convert-TimeToDays -StartTime $PublishedTime -EndTime $Script:Today
                #Workload = $Message.Workload
                Workload                = $Message.WorkloadDisplayName
                ActionType              = $Message.ActionType
                Classification          = $Message.Classification
                EndTime                 = ConvertFrom-UTCTime -ToLocalTime:$ToLocalTime -Time $Message.EndTime
                #Feature = $Message.Feature
                Feature                 = $Message.FeatureDisplayName
                UserFunctionalImpact    = $Message.UserFunctionalImpact
                PostIncidentDocumentUrl = $Message.PostIncidentDocumentUrl
                AffectedTenantCount     = $Message.AffectedTenantCount
                AffectedUserCount       = $Message.AffectedUserCount
                AffectedWorkload        = $Message.AffectedWorkloadDisplayNames -join ','
                #AffectedWorkloadNames = $Message.AffectedWorkloadNames -join ','
            }
        }
    }

    # Below this point ConvertFrom-UTCTime is not needed as rest of data is built on code above


    # Simplified Message Center
    $MessageCenterInformationSimple = foreach ($_ in $Simple) {
        if ($_.MessageType -eq 'MessageCenter') { $_ }
    }
    $Output.MessageCenterInformationSimple = foreach ($_ in $MessageCenterInformationSimple) {
        [PSCustomObject][ordered] @{
            ID                 = $_.ID
            Title              = $_.Title
            LastUpdatedTime    = $_.LastUpdatedTime
            LastUpdatedDaysAgo = $_.LastUpdatedDaysAgo
            Severity           = $_.Severity
            StartTime          = $_.StartTime
            EndTime            = $_.EndTime
            ActionType         = $_.ActionType
            Classification     = $_.Classification
            AffectedService    = $_.AffectedWorkload
            MessageType        = $_.MessageType
        }
    }
    # More information Message Center
    $MessageCenterInformation = foreach ($_ in $Extended) {
        if ($_.MessageType -eq 'MessageCenter') { $_ }
    }
    $Output.MessageCenterInformation = foreach ($_ in $MessageCenterInformation) {
        [PSCustomObject][Ordered] @{
            ID                 = $_.ID
            PublishedTime      = $_.PublishedTime
            PublishedDaysAgo   = $_.PublishedDaysAgo
            Title              = $_.Title
            Message            = $_.Message
            LastUpdatedTime    = $_.LastUpdatedTime
            LastUpdatedDaysAgo = $_.LastUpdatedDaysAgo
            Severity           = $_.Severity
            StartTime          = $_.StartTime
            EndTime            = $_.EndTime
            ActionType         = $_.ActionType
            Classification     = $_.Classification
            AffectedService    = $_.AffectedWorkload
            MessageType        = $_.MessageType
        }
    }

    # Simplified Message Center
    $IncidentsSimple = foreach ($_ in $Simple) {
        if ($_.MessageType -eq 'Incident') { $_ }
    }
    $Output.IncidentsSimple = foreach ($_ in $IncidentsSimple) {
        [PSCustomObject][ordered] @{
            Service                 = $_.Workload
            Feature                 = $_.Feature
            ID                      = $_.ID
            Title                   = $_.Title
            ImpactDescription       = $_.ImpactDescription
            LastUpdatedTime         = $_.LastUpdatedTime
            LastUpdatedDaysAgo      = $_.LastUpdatedDaysAgo
            UserFunctionalImpact    = $_.UserFunctionalImpact
            PostIncidentDocumentUrl = $_.PostIncidentDocumentUrl
            Severity                = $_.Severity
            StartTime               = $_.StartTime
            EndTime                 = $_.EndTime
            #ActionType = $_.ActionType
            Classification          = $_.Classification
            #AffectedService = $_.AffectedWorkload
            AffectedTenantCount     = $_.AffectedTenantCount
            AffectedUserCount       = $_.AffectedUserCount
            MessageType             = $_.MessageType
        }
    }
    # More information Message Center
    $Incidents = foreach ($_ in $Extended) {
        if ($_.MessageType -eq 'Incident') { $_ }
    }
    $Output.Incidents = foreach ($_ in $Incidents) {
        [PSCustomObject][Ordered] @{
            Service                 = $_.Workload
            Feature                 = $_.Feature
            ID                      = $_.ID
            Title                   = $_.Title
            ImpactDescription       = $_.ImpactDescription
            PublishedTime           = $_.PublishedTime
            PublishedDaysAgo        = $_.PublishedDaysAgo
            Message                 = $_.Message
            LastUpdatedTime         = $_.LastUpdatedTime
            LastUpdatedDaysAgo      = $_.LastUpdatedDaysAgo
            UserFunctionalImpact    = $_.UserFunctionalImpact
            PostIncidentDocumentUrl = $_.PostIncidentDocumentUrl
            Severity                = $_.Severity
            StartTime               = $_.StartTime
            EndTime                 = $_.EndTime
            #ActionType = $_.ActionType
            Classification          = $_.Classification
            #AffectedService = $_.AffectedWorkload
            AffectedTenantCount     = $_.AffectedTenantCount
            AffectedUserCount       = $_.AffectedUserCount
            MessageType             = $_.MessageType
        }
    }

    $Output.Messages = foreach ($Entry in $Extended) {
        $LimitedEntry = foreach ($_ in $Entry) { if ($_.MessageType -eq 'Incident') { $_ } } # Faster Where-Object
        foreach ($_ in $LimitedEntry) {
            $Object = [PsCustomObject][Ordered] @{
                Service              = $_.Workload
                Status               = $_.Status
                PublishedTime        = $_.PublishedTime
                PublishedDaysAgo     = $_.PublishedDaysAgo
                Title                = ''
                UserImpact           = ''
                MoreInfo             = ''
                CurrentStatus        = ''
                ScopeOfImpact        = ''
                StartTime            = ''
                PreliminaryRootCause = ''
                NextUpdateBy         = ''
                FinalStatus          = ''
                Other                = ''
            }
            foreach ($SubMessage in $_.Message.Split([Environment]::NewLine)) {
                # | Where-Object { ($_).Trim() -ne '' }) {
                if ($SubMessage -like 'Title: *') {
                    $Object.Title = $SubMessage -replace 'Title: ', ''
                } elseif ($SubMessage -like 'User Impact: *') {
                    $Object.UserImpact = $SubMessage -replace 'User Impact: ', ''
                } elseif ($SubMessage -like 'More info: *') {
                    $Object.MoreInfo = $SubMessage -replace 'More info: ', ''
                } elseif ($SubMessage -like 'Current status: *') {
                    $Object.CurrentStatus = $SubMessage -replace 'Current status: ', ''
                } elseif ($SubMessage -like 'Scope of impact: *') {
                    $Object.ScopeOfImpact = $SubMessage -replace 'Scope of impact: ', ''
                } elseif ($SubMessage -like 'Start time: *') {
                    $Time = $SubMessage -replace 'Start time: ', ''
                    $Object.StartTime = ConvertFrom-UTCTime -Time $Time -ToLocalTime:$ToLocalTime
                } elseif ($SubMessage -like 'Preliminary root cause: *') {
                    $Object.PreliminaryRootCause = $SubMessage -replace 'Preliminary root cause: ', ''
                } elseif ($SubMessage -like 'Next update by: *') {
                    $Time = ($SubMessage -replace 'Next update by: ', '').Trim()
                    $Object.NextUpdateBy = ConvertFrom-UTCTime -Time $Time -ToLocalTime:$ToLocalTime
                } elseif ($SubMessage -like 'Final status: *') {
                    $Object.FinalStatus = ($SubMessage -replace 'Final status: ', '').Trim()
                } else {
                    $Object.Other = $SubMessage.Trim()
                }
            }
            $Object
        }
    }
    #$Output.IncidentsSimple = foreach ($_ in $Simple) { if ($_.MessageType -eq 'Incident') { $_ }}
    #$Output.Incidents = foreach ($_ in $Extended) { if ($_.MessageType -eq 'Incident') { $_ }}

    $Output.PlannedMaintenanceSimple = foreach ($_ in $Simple) { if ($_.MessageType -eq 'PlannedMaintenance') { $_ } }
    $Output.PlannedMaintenance = foreach ($_ in $Extended) { if ($_.MessageType -eq 'PlannedMaintenance') { $_ } }
    return $Output
}
function Get-Office365ServiceHealthServices {
    [CmdLetbinding()]
    param(
        [System.Collections.IDictionary] $Authorization,
        [string] $TenantDomain
    )
    try {
        $Services = (Invoke-RestMethod -Uri "https://manage.office.com/api/v1.0/$($TenantDomain)/ServiceComms/Services" -Headers $Authorization -Method Get)
    } catch {
        $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
        Write-Warning -Message "Get-Office365ServiceHealthServices - Error: $ErrorMessage"
        return
    }
    $Output = @{ }
    $Output.Simple = foreach ($Service in $Services.Value) {
        [PSCustomObject][ordered] @{
            #ID = $Service.ID
            Service = $Service.DisplayName
        }
    }

    $Output.Extended = foreach ($Service in $Services.Value) {
        foreach ($Feature in  $Service.Features) {
            [PSCustomObject][ordered] @{
                #ID = $Service.ID
                Service = $Service.DisplayName
                Feature = $Feature.DisplayName
                #FeatureName = $Feature.Name
            }
        }
    }
    return $Output
}

function Get-Office365Health {
    [CmdLetbinding()]
    param(
        [string][alias('ClientID')] $ApplicationID,
        [string][alias('ClientSecret')] $ApplicationKey,
        [string] $TenantDomain,
        [PSWinDocumentation.Office365Health[]] $TypesRequired = [PSWinDocumentation.Office365Health]::All,
        [switch] $ToLocalTime,
        [switch] $TlsDefault
    )
    $StartTime = Start-TimeLog
    $Script:TimeZoneBias = (Get-CimInstance -ClassName Win32_TimeZone).Bias
    $Script:Today = Get-Date
    if ($null -eq $TypesRequired -or $TypesRequired -contains [PSWinDocumentation.Office365Health]::All) {
        $TypesRequired = Get-Types -Types ([PSWinDocumentation.Office365Health])
    }
    $Authorization = Connect-O365ServiceHealth -ApplicationID $ApplicationID -ApplicationKey $ApplicationKey -TenantDomain $TenantDomain -TlsDefault:$TlsDefault
    if ($null -ne $Authorization) {
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @(
                [PSWinDocumentation.Office365Health]::Services,
                [PSWinDocumentation.Office365Health]::ServicesExtended)) {
            $Services = Get-Office365ServiceHealthServices -Authorization $Authorization -TenantDomain $TenantDomain
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @(
                [PSWinDocumentation.Office365Health]::CurrentStatus,
                [PSWinDocumentation.Office365Health]::CurrentStatusExtended
            )) {
            $CurrentStatus = Get-Office365ServiceHealthCurrentStatus -Authorization $Authorization -TenantDomain $TenantDomain -ToLocalTime:$ToLocalTime
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @(
                [PSWinDocumentation.Office365Health]::HistoricalStatus,
                [PSWinDocumentation.Office365Health]::HistoricalStatusExtended
            )) {
            $HistoricalStatus = Get-Office365ServiceHealthHistoricalStatus -Authorization $Authorization -TenantDomain $TenantDomain -ToLocalTime:$ToLocalTime
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @(
                [PSWinDocumentation.Office365Health]::Incidents,
                [PSWinDocumentation.Office365Health]::IncidentsExtended,
                [PSWinDocumentation.Office365Health]::MessageCenterInformation,
                [PSWinDocumentation.Office365Health]::MessageCenterInformationExtended,
                [PSWinDocumentation.Office365Health]::PlannedMaintenance,
                [PSWinDocumentation.Office365Health]::PlannedMaintenanceExtended,
                [PSWinDocumentation.Office365Health]::Messages
            )) {
            $Messages = Get-Office365ServiceHealthMessages -Authorization $Authorization -TenantDomain $TenantDomain -ToLocalTime:$ToLocalTime
        }
        $Output = [ordered] @{ }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::Services)) {
            $Output.Services = $Services.Simple
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::ServicesExtended)) {
            $Output.ServicesExtended = $Services.Extended
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::CurrentStatus)) {
            $Output.CurrentStatus = $CurrentStatus.Simple
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::CurrentStatusExtended)) {
            $Output.CurrentStatusExtended = $CurrentStatus.Extended
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::HistoricalStatus)) {
            $Output.HistoricalStatus = $HistoricalStatus.Simple
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::HistoricalStatusExtended)) {
            $Output.HistoricalStatusExtended = $HistoricalStatus.Extended
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::MessageCenterInformation)) {
            $Output.MessageCenterInformation = $Messages.MessageCenterInformationSimple | Sort-Object -Property LastUpdatedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::MessageCenterInformationExtended)) {
            $Output.MessageCenterInformationExtended = $Messages.MessageCenterInformation | Sort-Object -Property LastUpdatedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::Incidents)) {
            $Output.Incidents = $Messages.IncidentsSimple | Sort-Object -Property LastUpdatedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::Messages)) {
            $Output.IncidentsMessages = $Messages.Messages | Sort-Object -Property PublishedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::IncidentsExtended)) {
            $Output.IncidentsExtended = $Messages.Incidents | Sort-Object -Property LastUpdatedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::PlannedMaintenance)) {
            $Output.PlannedMaintenance = $Messages.PlannedMaintenanceSimple | Sort-Object -Property LastUpdatedTime -Descending
        }
        if (Find-TypesNeeded -TypesRequired $TypesRequired -TypesNeeded @([PSWinDocumentation.Office365Health]::PlannedMaintenanceExtended)) {
            $Output.PlannedMaintenanceExtended = $Messages.PlannedMaintenance | Sort-Object -Property LastUpdatedTime -Descending
        }
        $EndTime = Stop-TimeLog -Time $StartTime -Option OneLiner
        Write-Verbose "Get-Office365Health - Time to process: $EndTime"
        return $Output

    } else {
        return
    }
}



Export-ModuleMember -Function @('Get-Office365Health') -Alias @()