PowerShellおよびAzureAutomationを介したTelegram上のMicrosoftメッセージセンター

そして、SaaSシステムの長所と短所は、それが私たちによって制御されていないことであり、私たちは(ほとんどの場合)主な機能の更新と新機能の追加のサイクルに影響を与えることはできません。ただし、これらの更新は有益であり、機能に大きな変更がない場合もあれば、インフラストラクチャにとって重要である場合もあります。これにより、ビジネスに追加のリスクが発生するため、ITエンジニアと同様に安心感が得られます。すべてをサポートします。この記事では、追加のアプリケーションをインストールせずに、Microsoft365の更新プログラムに関する必要なメッセージをすべて取得する方法について説明します。必要なのは、Azure Active Directory、Azure Automation、PowerShellのAPIアクセス用の登録済みアプリケーション、およびTelegramのボットです。





仕事:





, API M365, Teams Telegram.





:





  1. Microsoft 365 Roadmap





  2. Microsoft 365 Message Center





, , .. RSS feed, RSS Telegram . .





, Roadmap , , , Microsoft Message Center . , , .





, PowerShell, . . Azure Automation . , Azure Active Directory .





1.      Azure Active Directory





AADからAzureへ
AAD Azure

2.      Manage App registrations





3.      New Registration Azure Active Directory





4.      Name , .





5.      Register . , , :





  • Application ID





  • Directory ID





.





6.      , Client  Secret, . Certificates & Secrets New Client Secret. , Client Secret.





7.      Description .





8.      Value , , .





9.      Message Center. API Permissions





10.  Graph API User.Read, .





.





M365 , Delegated Permissions, , Application Permissions . , - , MFA , Application Permissions Global . User.Read , . Remove permission.





Message Center. Add Permission > Office 365 Management API





11.  Application Permissions > ServiceHealth.Read Add Permissions





12.  Global Admin, Grant admin consent, ,





13.  , Granted for <tenant name>





.





, M365 API, Get-APIToken. :





  • Application ID





  • Tenant ID (directory ID)





  • App Secret (Client Secret)





5





Rest URL :





“https://login.microsoftonline.com/” + $TenantID + “/oauth2/v2.0/token”











Function Get-ApiToken {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$True)]
        [String]
        $AppId, $AppSecret, $TenantID
    )

    $AuthUrl = "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token"
    $Scope = "https://manage.office.com/.default"

    $Body = @{
        client_id = $AppId
        client_secret = $AppSecret
        scope = $Scope
        grant_type = 'client_credentials'
    }

    $PostSplat = @{
        ContentType = 'application/x-www-form-urlencoded'
        Method = 'POST'
        Body = $Body
        Uri = $AuthUrl
    }

    try {
        Invoke-RestMethod @PostSplat -ErrorAction Stop
    }
    catch {
        Write-Warning "$(Get-Date): Exception was caught: $($_.Exception.Message)" 
    }
}
      
      



Token .





try {
    $Token = Get-ApiToken -AppId $ClientId -AppSecret $ClientSecret -TenantID $TenantId -ErrorAction Stop
    Write-Output "$(Get-Date): Token successfully issued"
}
catch {
    Write-Error "$(Get-Date): Can't get the token!"
    break
}
      
      



 





:





  , Message Center , Get-MCMessages Get-ApiRequestResult





Get-ApiRequestResult.





URL , .





header Splat.





Function Get-ApiRequestResult {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$True)]
        [String]
        $Url, $Method, $Token
    )
 
    $Header = @{
        Authorization = "$($Token.token_type) $($Token.access_token)"
    }

    $PostSplat = @{
        ContentType = 'application/json'
        Method = $Method
        Header = $Header
        Uri = $Url
    }

    try {
        Invoke-RestMethod @PostSplat -ErrorAction Stop
    }
    catch {
        $Ex = $_.Exception
        $ErrorResponse = $ex.Response.GetResponseStream()
        $Reader = New-Object System.IO.StreamReader($errorResponse)
        $Reader.BaseStream.Position = 0
        $Reader.DiscardBufferedData()
        $ResponseBody = $Reader.ReadToEnd();
        Write-Output "$(Get-Date): Response content:`n$responseBody" -f Red
        throw Write-Error "$(Get-Date): Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
    }
}
      
      



Message Center.





Get https://manage.office.com/api/ServiceComms/Messages





Function Get-MCMessages {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$True)]
        $APIUrl, $TenantId
    )

    $ApiVersion = "v1.0"
    $MS_resource = "ServiceComms/Messages?&`$filter=MessageType%20eq%20'MessageCenter'"
    $Uri = "$APIUrl/$ApiVersion/$($TenantId)/$MS_resource"
    
    $Method = "GET"

    try {
        Get-ApiRequestResult -Url $Uri -Token $Token -Method $Method -ErrorAction Stop
        Write-Output "$(Get-Date): New messages successfully collected"
    }
    catch {
        $Ex = $_.Exception
        $ErrorResponse = $ex.Response.GetResponseStream()
        $Reader = New-Object System.IO.StreamReader($errorResponse)
        $Reader.BaseStream.Position = 0
        $Reader.DiscardBufferedData()
        $ResponseBody = $Reader.ReadToEnd();
        Write-Output "$(Get-Date): Response content:`n$responseBody" -f Red
        throw Write-Error "$(Get-Date): Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
    }
}
      
      



? , API M365 , , , . , $MS_Resource $URL Get-MCMessages. Intune, Get-IntuneManagedDevices, MS_Resource "deviceManagement/managedDevices", URL https://graph.microsoft.com, .





:





, Azure Automation, . , - «» , . LastUpdatedTime, .





Runbook  Azure Automation 1 , . , : , . :





$CurrentTime = Get-Date
$ontrolTime = ($CurrentTime).AddMinutes(-60)
      
      



Get-MCMessages.





$Messages = Get-MCmessages -APIUrl $APIUrl -TenantId $TenantId
      
      



,





$NewMessages = $Messages.value | Where-Object {$(Get-date $($_.LastUpdatedTime)) -ge $controlTime}
      
      







$NewMessagesCount = $NewMessages.id.count

if ($NewMessagesCount -gt 0) {
    Write-Output "$(Get-Date): There are $NewMessagesCount new messages"
}
else {
    Write-Output "$(Get-Date): There is no new messages"
    break
}
      
      



, , . .





if ($NewMessagesCount -gt 0) {

    foreach ($NewMessage in $NewMessages){

    }

}
      
      



.





$MessagePreview = $NewMessage.Messages.MessageText
$MessageID = $NewMessage.id
$MessageTitle = $NewMessage.Title
$MessageType = $NewMessage.actiontype
$PublishedTime = Get-date $($NewMessage.Messages.publishedTime)
$UpdatedTime = Get-Date $($NewMessage.LastUpdatedTime)
      
      



MessageText html, , Telegram . , , , Telegram . Remove-HtmlTags, html , .





. :





  • - .





  • - , .





  • - - .





, , . :





Function Remove-HtmlTags {

    param (
        $Text
    )

    $SimpleTags = @(
        'p',
        'i',
        'span',
        'div',
        'ul',
        'ol',
        'h1',
        'h2',
        'h3',
        'div'
    )

    $TagsToRemove = (
        "\<\/?font[^>]*\>",
        '\<br\s?\/?\>',
        '\&rarr',
        'style=""',
        ' target\=\"_blank\"'
    )

    $TagsToReplace = @(
        @('\[','<b>'),
        @('\]','</b>'),
        @('\<A','<a'),
        @('\<\/A\>','</a>'),
        @('\<img[^>]*\>','[There was an image]'),
        @('&nbsp;',' '),
        @('\<li\>',' -'),
        @('\<\/li\>',"`n")
    )

    foreach($Tag in $SimpleTags){
        $Pattern = "\<\/?$tag\>"
        $Text = $Text -replace $Pattern
    }

    foreach($Tag in $TagsToRemove){
        $Text = $Text -replace $Tag
    }

    foreach($Tag in $TagsToReplace){
        $Text = $Text -replace $Tag

    }
    
    foreach($Tag in $SimpleTags){
        $Pattern = "\<\/?$Tag\>"
        $Text = $Text -replace $Pattern
    }

    $Text
    
}
      
      



, , , , , - . - , , , .





, . , , Microsoft , . </p>, , , html . .





$MessageTextWithHtmlString = $MessagePreview -split ('\<\/p\>')
$FormattedMesssageText = $(Remove-HtmlTags $MessageTextWithHtmlString-creplace '(?m)^\s*\r?\n',''
      
      



. Title .





$PublishingInfo = "Published: $PublishedTime `nUpdated: $UpdatedTime"
$TgmMessage = "$BoldMessageTitle `n$MessageDescription `n$PublishingInfo `n$FormattedMesssageText"
      
      



Microsoft , , . .





$MessageActionRequiredByDate = $NewMessage.ActionRequiredByDate
$MessageAdditionalInformation = $NewMessage.ExternalLink
$MessageBlogLink = $NewMessage.BlogLink

if($MessageActionRequiredByDate){

		$TgmMessage += "`nAction required by date:  $MessageActionRequiredByDate"

}
elseif ($MessageAdditionalInformation) {

		$TgmMessage += "`n$MessageAdditionalInformation'>Additional info"

}
elseif ($MessageBlogLink) {

		$TgmMessage += "`n$MessageBlogLink'>Blog"

}
      
      



. , .





ChatID, Token, ParsingType, - , .





function Send-TelegramMessage {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]
        $MessageText,$TokenTelegram,$ChatID

        [Parameter(Mandatory=$true)]
        [ValidateSet("html","markdown")]
        [string]$ParsingType
    )

    $URL_set = "https://api.telegram.org/bot$TokenTelegram/sendMessage"

    $Body = @{
        text = $MessageText
        parse_mode = $ParsingType
        chat_id = $chatID
    }

    $MessageJson = $body | ConvertTo-Json

    try {
        Invoke-RestMethod $URL_set -Method Post -ContentType 'application/json; charset=utf-8' -Body $MessageJson -ErrorAction Stop
        Write-Output "$(Get-Date): Message has been sent"
    }
    catch {
        Write-Error "$(Get-Date): Can't sent message"
        Write-Output "$(Get-Date): StatusCode:" $_.Exception.Response.StatusCode.value__ 
        Write-Output "$(Get-Date): StatusDescription:" $_.Exception.Response.StatusDescription
        throw
    }
    
}
      
      



, , :





Send-TelegramMessage -MessageText $TgmMessage -TokenTelegram $TokenTelegram -ChatID $chatID -ParsingType 'html'
      
      



:





, ID, , . Azure Automation Secure Assets. .





コード付きのリポジトリへのリンク





実行中のボットでチャネルにリンクする





PSボットを改善するための貢献者と提案に喜んでいます。








All Articles