O365ServiceCommunications.psm1

#Region '.\Classes\Connection.ps1' 0
class O365ServiceCommunications_Connection {
    hidden [string] $ClientID
    hidden [string] $ClientSecret
    [string] $TenantID
    hidden [hashtable] $AuthHeader
    [string] $ApiBase
    [DateTimeOffset] $Expires
}
#EndRegion '.\Classes\Connection.ps1' 8
#Region '.\Classes\Message.ps1' 0
class O365ServiceCommunications_MessageAdditionalDetails {
    [string] $Name
    [string] $Value
}

class O365ServiceCommunications_MessageText {
    [string] $MessageText
    [Nullable[DateTimeOffset]] $PublishedTime
}

class O365ServiceCommunications_Message {
    [string[]] $ActionType
    [O365ServiceCommunications_MessageAdditionalDetails[]] $AdditionalDetails
    [long] $AffectedTenantCount
    [long] $AffectedUserCount
    [string[]] $AffectedWorkloadDisplayNames
    [string[]] $AffectedWorkloadNames
    [string] $Classification
    [Nullable[DateTimeOffset]] $EndTime
    [string] $Feature
    [string] $FeatureDisplayName
    [string] $Id
    [string] $ImpactDescription
    [Nullable[DateTimeOffset]] $LastUpdatedTime
    [O365ServiceCommunications_MessageText[]] $Messages
    [string] $MessageType
    [string] $PostIncidentDocumentUrl
    [string] $Severity
    [datetime] $StartTime
    [string] $Status
    [string] $Title
    [string] $UserFunctionalImpact
    [string] $Workload
    [string] $WorkloadDisplayName
}

class O365ServiceCommunications_IncidentMessage : O365ServiceCommunications_Message {

}

class O365ServiceCommunications_MessageCenterMessage : O365ServiceCommunications_Message {
    hidden [string] ${@odata.type}
    [Nullable[DateTimeOffset]] $ActionRequiredByDate
    [long] $AnnouncementId
    [string] $AppliesTo
    [string] $BlogLink
    [string] $Category
    [string] $ExternalLink
    [string] $FeatureName
    [string] $FlightName
    [string] $HelpLink
    [bool] $IsDismissed
    [bool] $IsMajorChange
    [bool] $IsRead
    [string[]] $MessageTagNames
    [string] $Milestone
    [Nullable[DateTimeOffset]] $MilestoneDate
    [string] $PreviewDuration
}
#EndRegion '.\Classes\Message.ps1' 59
#Region '.\Classes\Service.ps1' 0
class O365ServiceCommunications_ServiceFeature {
    [string] $DisplayName
    [string] $Name
}

class O365ServiceCommunications_Service {
    [string] $Id
    [string] $DisplayName
    [O365ServiceCommunications_ServiceFeature[]] $Features
}
#EndRegion '.\Classes\Service.ps1' 10
#Region '.\Classes\Status.ps1' 0
class O365ServiceCommunications_FeatureStatus {
    [string] $FeatureDisplayName
    [string] $FeatureName
    [string] $FeatureServiceStatus
    [string] $FeatureServiceStatusDisplayName
}

class O365ServiceCommunications_Status {
    [O365ServiceCommunications_FeatureStatus[]] $FeatureStatus
    [string] $Id
    [string[]] $IncidentIds
    [string] $Status
    [string] $StatusDisplayName
    [Nullable[DateTimeOffset]] $StatusTime
    [string] $Workload
    [string] $WorkloadDisplayName
}
#EndRegion '.\Classes\Status.ps1' 17
#Region '.\Private\Test-SCConnection.ps1' 0
function Test-SCConnection
{
    if (!$Script:SCConnection)
    {
        return $false
    }

    if ($Script:SCConnection.Expires -lt [DateTimeOffset]::Now)
    {
        return $false
    }

    $true
}
#EndRegion '.\Private\Test-SCConnection.ps1' 14
#Region '.\Public\Connect-O365ServiceCommunications.ps1' 0
function Connect-O365ServiceCommunications
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [guid]
        $ClientID,

        [Parameter(Mandatory)]
        [string]
        $ClientSecret,

        [Parameter(Mandatory)]
        [guid]
        $TenantID
    )
    
    $Url = "https://login.microsoftonline.com/$TenantID/oauth2/token?api-version=1.0"

    $Body = @{
        grant_type = "client_credentials"
        resource = "https://manage.office.com"
        client_id = $ClientID
        client_secret = $ClientSecret
    }
    
    $Response = Invoke-RestMethod -Method Post -Uri $Url -Body $Body
    $Script:SCConnection = [O365ServiceCommunications_Connection]@{
        ClientID     = $ClientID
        ClientSecret = $ClientSecret
        TenantID    = $TenantID
        AuthHeader   = @{ 'Authorization' = "$($Response.token_type) $($Response.access_token)" }
        ApiBase      = "https://manage.office.com/api/v1.0/$TenantID/ServiceComms"
        Expires      = [datetimeoffset]::new([datetime]"1970-01-01", [timespan]::new(0)).AddSeconds($Response.expires_on)
    }
}
#EndRegion '.\Public\Connect-O365ServiceCommunications.ps1' 37
#Region '.\Public\Get-SCMessage.ps1' 0
function Get-SCMessage {
    [CmdletBinding(DefaultParameterSetName = "Filter")]
    [OutputType([O365ServiceCommunications_Message])]
    param (
        [Parameter(ParameterSetName = "Filter")]
        [string]
        $Workload,

        [Parameter(ParameterSetName = "Filter")]
        [DateTimeOffset]
        $Start,

        [Parameter(ParameterSetName = "Filter")]
        [DateTimeOffset]
        $End,

        [Parameter(ParameterSetName = "Filter")]
        [string]
        $MessageType,

        [Parameter(Mandatory, ParameterSetName = "Id")]
        [string]
        $Id
    )
    
    try {
        if (!(Test-SCConnection)) {
            Connect-O365ServiceCommunications $Script:SCConnection.ClientID $Script:SCConnection.ClientSecret $Script:SCConnection.TenantID
        }
    }
    catch {
        throw "No viable connection was found. Please run 'Connect-O365ServiceCommunications before running any other commands.'"

    }

    $Splat = @{
        Headers = $Script:SCConnection.AuthHeader
        Uri     = "$($Script:SCConnection.ApiBase)/Messages"
        Body    = @{}
    }

    switch ($PSCmdlet.ParameterSetName)
    {
        "Id" {
            $Splat["Body"]['$filter'] = "Id eq '$Id'"
        }

        "Filter" {
            $Filters = @(
                if ($PSBoundParameters.ContainsKey("Workload")) {
                    "Workload eq '$Workload'"
                }

                if ($PSBoundParameters.ContainsKey("Start")) {
                    "StartTime ge $($Start.UTCDateTime.ToString("o"))"
                }

                if ($PSBoundParameters.ContainsKey("End")) {
                    "EndTime le $($End.UTCDateTime.ToString("o"))"
                }

                if ($PSBoundParameters.ContainsKey("MessageType")) {
                    "MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'$MessageType'"
                }
            )

            if ($Filters) {
                $Splat["Body"]['$filter'] = $Filters -join " and "
            }
        }
    }

    (Invoke-RestMethod @Splat).Value | ForEach-Object {
        switch ($_) {
            { $_.MessageType -eq "Incident" } {
                [O365ServiceCommunications_IncidentMessage]$_
            }

            { $_.MessageType -eq "MessageCenter" } {
                [O365ServiceCommunications_MessageCenterMessage]$_
            }
        }
    }
}
#EndRegion '.\Public\Get-SCMessage.ps1' 84
#Region '.\Public\Get-SCService.ps1' 0
function Get-SCService {
    [CmdletBinding()]
    [OutputType([O365ServiceCommunications_Service])]
    param (

    )
    
    try {
        if (!(Test-SCConnection)) {
            Connect-O365ServiceCommunications $Script:SCConnection.ClientID $Script:SCConnection.ClientSecret $Script:SCConnection.TenantID
        }
    }
    catch {
        throw "No viable connection was found. Please run 'Connect-O365ServiceCommunications before running any other commands.'"

    }

    $Uri = "$($Script:SCConnection.ApiBase)/Services"
    [O365ServiceCommunications_Service[]](Invoke-RestMethod -Uri $Uri -Headers $Script:SCConnection.AuthHeader).Value
}
#EndRegion '.\Public\Get-SCService.ps1' 20
#Region '.\Public\Get-SCStatus.ps1' 0
function Get-SCStatus {
    [CmdletBinding(DefaultParameterSetName = "CurrentStatus")]
    [OutputType([O365ServiceCommunications_Status])]
    param (
        [Parameter(ParameterSetName = "CurrentStatus")]
        [Parameter(ParameterSetName = "HistoricalStatus")]
        [string]
        $Workload,

        [Parameter(Mandatory, ParameterSetName = "HistoricalStatus")]
        [System.DateTimeOffset]
        $From
    )
    
    try {
        if (!(Test-SCConnection)) {
            Connect-O365ServiceCommunications $Script:SCConnection.ClientID $Script:SCConnection.ClientSecret $Script:SCConnection.TenantID
        }
    }
    catch {
        throw "No viable connection was found. Please run 'Connect-O365ServiceCommunications before running any other commands.'"
    }

    $Splat = @{
        Headers = $Script:SCConnection.AuthHeader
        Uri     = "$($Script:SCConnection.ApiBase)/$($PSCmdlet.ParameterSetName)"
        Body    = @{}
    }

    if ($PSCmdlet.ParameterSetName -eq "HistoricalStatus") {
        $Splat["Body"]['$filter'] = "StatusTime eq '$From'"
    }

    if ($PSBoundParameters.ContainsKey("Workload")) {
        $Splat["Body"]['$filter'] = "Workload eq '$Workload'"
    }
    
    [O365ServiceCommunications_Status[]](Invoke-RestMethod @Splat).Value
}
#EndRegion '.\Public\Get-SCStatus.ps1' 39