Invoke-RestmethodでGraphAPIを叩くと2バイト文字が文字化けする

自分の知識不足ですが、ハマる人いるかもしれないのでメモ。

Office 365のGraphAPIを利用し、Office 365 の利用状況レポートをダウンロードする事が可能です。Flowでやる手順は前に記事に書きました。

GraphAPI経由でのOffice 365 レポートをFlowで取得する

これをpowershellで実行する事もできます。こんな感じです。

$url = "https://login.microsoftonline.com/[テナントID]/oauth2/token"

$body = @{
    "grant_type" = 'client_credentials'
    "resource" = "https://graph.microsoft.com"
    "client_id" = '[クライアントID]'
    "client_secret" = '[シークレットキー]'
}

$ContentType = "application/x-www-form-urlencoded"
$oauth = Invoke-RestMethod -uri $url -Method post -header $header -Body $body -ContentType $ContentType

function AccessGraph ($url, $filename) {
    $headerParams  = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
    $ContentType = "application/octet-stream"
    $res = Invoke-RestMethod -uri $url -Method Get -header $headerParams -Body $body
    $res | out-file $filename -enc utf8
}

$url = "https://graph.microsoft.com/v1.0/reports/getEmailAppUsageUserDetail(period='D7')"
$filename = "getEmailAppUsageUserDetail_period.csv"
AccessGraph $url $filename

しかしながら、このコードでは出力結果が以下のようになります。

先頭にUTF-8のBOMが表示され、中盤に表示されるはずの氏名を表す2バイト文字は文字化けています。この文字コードはUTF-8であり、スクリプト自体の文字コードや出力形式もUTF-8のはずですが…なんでや!

解決策

Invoke-RestMethodのオプションパラメーターである、-OutFileを利用すれば文字化けしない。

・修正前


    $res = Invoke-RestMethod -uri $url -Method Get -header $headerParams -Body $body
    $res | out-file $filename -enc utf8

・修正後


    Invoke-RestMethod -uri $url -Method Get -header $headerParams -Body $body -OutFile output.csv

なるほど。おそらくですが、修正前のコードだと、一度 $res という関数に格納した時点で文字コードがおかしくなってしまうようです(WindowsOSのせいかも?)

修正前のコードは、ひとまず $res 変数に突っ込んだ後、いろいろと処理ができるようにする、私が良く使うコードなのですが、コマンドレット純正のアウトプットメソッドを使う事で解決する場合もある、という事を学ぶ事ができました。

Posted by tera