Public/Get-GkServiceMessage.ps1
|
function Get-GkServiceMessage { <# .SYNOPSIS Report Microsoft 365 message center posts — the change announcements that need action. .DESCRIPTION Reads GET /admin/serviceAnnouncement/messages and surfaces the message center in a form you can filter and export. The value is in -ActionRequiredOnly combined with -ByDays: the posts with a deadline are the ones that turn into an incident if nobody reads them. The message body is long HTML, so it is omitted by default; pass -IncludeBody to keep it. Requires the ServiceMessage.Read.All scope, which is the only permission Graph accepts here. .PARAMETER Service Only return messages for services whose name contains this text (case-insensitive). .PARAMETER Category Only return messages in this category. .PARAMETER ActionRequiredOnly Only return messages flagged as requiring admin action by a deadline. .PARAMETER ByDays Only return messages whose action deadline falls within this many days. .PARAMETER First Return at most this many messages. .PARAMETER IncludeBody Keep the message body. It is long HTML — useful for export, noisy on screen. .PARAMETER AsReport Add a ReportGeneratedUtc column. .EXAMPLE Get-GkServiceMessage -ActionRequiredOnly -ByDays 30 Everything with an admin deadline inside a month. .EXAMPLE Get-GkServiceMessage -Category planForChange -Service Exchange Upcoming Exchange changes. .EXAMPLE Get-GkServiceMessage -ActionRequiredOnly -AsReport | Export-Csv .\message-center.csv -NoTypeInformation .OUTPUTS PSGraphKit.ServiceMessage #> [CmdletBinding()] [OutputType('PSGraphKit.ServiceMessage')] param( [string] $Service, [ValidateSet('preventOrFixIssue', 'planForChange', 'stayInformed', 'unknownFutureValue')] [string] $Category, [switch] $ActionRequiredOnly, [int] $ByDays, [int] $First, [switch] $IncludeBody, [switch] $AsReport ) begin { Test-GkConnection -FunctionName 'Get-GkServiceMessage' -Caller $PSCmdlet | Out-Null $now = [datetime]::UtcNow } process { # category filters server-side; the rest is client-side (Graph does not support them here). $uri = '/admin/serviceAnnouncement/messages' if ($Category) { $uri += "?`$filter=category eq '$Category'" } $params = @{ Uri = $uri; CallerFunction = 'Get-GkServiceMessage' } if ($PSBoundParameters.ContainsKey('First')) { $params['MaxResult'] = $First } $messages = Invoke-GkGraphRequest @params foreach ($m in $messages) { $svc = [string](Get-GkDictValue $m 'services') if (-not $svc) { $svc = (@(Get-GkDictValue $m 'services') -join ', ') } $actionBy = ConvertTo-GkDateTime (Get-GkDictValue $m 'actionRequiredByDateTime') $isAction = ($null -ne $actionBy) if ($Service -and $svc -notlike "*$Service*") { continue } if ($ActionRequiredOnly -and -not $isAction) { continue } if ($PSBoundParameters.ContainsKey('ByDays')) { if ($null -eq $actionBy) { continue } if (($actionBy - $now).TotalDays -gt $ByDays) { continue } } $daysLeft = if ($null -ne $actionBy) { [int][math]::Floor(($actionBy - $now).TotalDays) } else { $null } $obj = [ordered]@{ PSTypeName = 'PSGraphKit.ServiceMessage' Id = [string](Get-GkDictValue $m 'id') Title = [string](Get-GkDictValue $m 'title') Services = $svc Category = [string](Get-GkDictValue $m 'category') Severity = [string](Get-GkDictValue $m 'severity') IsMajorChange = Get-GkDictValue $m 'isMajorChange' ActionRequiredBy = $actionBy DaysUntilAction = $daysLeft LastModified = ConvertTo-GkDateTime (Get-GkDictValue $m 'lastModifiedDateTime') } if ($IncludeBody) { $body = Get-GkDictValue $m 'body' $obj['Body'] = [string](Get-GkDictValue $body 'content') } if ($AsReport) { $obj['ReportGeneratedUtc'] = $now } [pscustomobject]$obj } } } |