ルドルフもわたるふもいろいろあってな

Microsoft 365、Power Platform、PowerShellについて調べたことや検証したことなどを投稿します。技術の話は面白い。

AzureADアプリを登録せずにPowerShell からMicrosft Graph API を使う

最初に

この話は下記の投稿内容を前提としています。
wataruf.hatenablog.com

上記の投稿ではTeams 内の"いいね"を取得するためにMicrosoft Graph API を使用しています。
Graph API を使用するためにAzure Active Directory にアプリを登録しています。

今回の趣旨

前回の投稿と同じく、PowerShell を使ってMicrosoft Teams のいいね一覧をCSV形式で出力します。
ただし、前回と違って、AzureADアプリの登録は行いません。

どうやってアプリ登録無しを実現するのか

SharePoint PnP Cmdlets の機能を使います。

接続コマンドである「Connect-PnPOnline」には下記の2種類の使い方があります。
1. Connect-PnPOnline -Url "https://(SPOサイトのURL)"
2. Connect-PnPOnline -Scopes @((Graph API で使うアクセス許可))

2 のScopes パラメータで指定したアクセス許可はこの接続コマンドのセッション終了までのあいだ使用することができます。つまり、AzureADアプリでのアクセス許可付与と同じ効果が得られます。

アプリの登録が省略できると何が嬉しいか

PowerShell を実行するための準備をソースコード内で完結できます。
つまり、必要な権限を付与されている実行ユーザーさえ準備できていればこのPowerShell を対象のテナントに対してすぐ実行きるということです。

ソースコード

指定したチャネルのいいね一覧をPowerShellで取得する(AzureADアプリ不要版)

#使用するアクセス許可を指定
$scopes = @("Group.Read.All")

#Microsoft Graph API に接続
#注意:認証情報の入力が求められます
Connect-PnPOnline -Scopes $scopes

#取得対象チームのID
$teamID = "3b17fd48-3b03-4e9b-b1d9-d0acb61b2f1d"
$channelID = "19:fd47b47bcfd44d1a9b74dbb5c724cecf@thread.skype"

$token = Get-PnPAccessToken
$headerParams = @{Authorization ="Bearer $token"}

#チャネル内のスレッドをすべて取得
$url = "https://graph.microsoft.com/beta/teams/{0}/channels/{1}/messages/" -f $teamID,$channelID
$responseFromAPI = Invoke-RestMethod -uri $url -Method Get -Headers $headerParams

$messagesWithOutReply = @()
$messagesWithOutReply += $responseFromAPI.value

$messagesWithReply = @()
$messagesWithReply += $responseFromAPI.value

#返信をすべて取得
foreach($m in $messagesWithOutReply)
{
    $url = "https://graph.microsoft.com/beta/teams/{0}/channels/{1}/messages/{2}/replies" -f $teamID,$channelID,$m.ID
    $responseFromAPI = Invoke-RestMethod -uri $url -Method Get -Headers $headerParams

    $messagesWithReply += $responseFromAPI.value
}

#いいねをCSVに出力
foreach($message in $messagesWithReply)
{
    if($message.reactions.Count -eq 0)
    {
        continue
    }

    $reactions = @()
    $reactions += $message.reactions

    foreach($reaction in $reactions)
    {
        $obj = New-Object PSObject | Select "ReactionType","CreatedDateTime","From","To","Content","ID","ReplyToID"

        #リアクションの種類
        $obj.ReactionType =  $reaction.reactionType

        #リアクションをした日時
        $obj.CreatedDateTime = $reaction.createdDateTime

        #誰がリアクションをしたか
        $obj.From =  $reaction.user.user.id

        #誰に対してリアクションをしたか
        $obj.To =  $message.from.user.id

        #リアクション対象の投稿内容
        $obj.Content = $message.body.content

        #投稿ID
        ##スレッドでも返信でも投稿IDを持っている
        $obj.ID = $message.id

        #返信先のID
        ##この値が空白値の場合は返信ではなくスレッド
        $obj.ReplyToId = $message.replyToId

        $obj |  Export-Csv -Path ".\output.csv" -Encoding UTF8 -NoTypeInformation -Append
    }#foreach($reaction in $reactions)
}#foreach($message in $messagesWithReply)

実行結果のイメージ

f:id:wataruf01:20220321232243p:plain

ひとつだけ残念な点あり

アプリの登録なしでGraph API の操作が実行できるのは便利です。
ですが、この方法は1点残念な点があります。

Microsoft Graph API に対する接続コマンドを実行したとき(= Scopes パラメータを使用したとき)に、必ず認証情報の入力を求めるポップアップが表示されます。

Credentials パラメータをつけても、なぜか認証情報のポップアップが表示されます。
回避方法は判明していないです。ご存知のかたはコメント欄等で教えて頂けると助かります。

Connect-PnPOnline -Scopes $scopes