Office 365 Management API の使い方 (PowerShell 利用版)

# この記事の内容

本記事では、Office 365 Management API の中でも、特に Office 365 管理アクティビティ API を利用して、Office 365 のログを取得する方法をご紹介します。特に以下の手順では、Audit.General のサブスクリプションを作成し、そのサブスクリプションから監査ログを取得してみます。本記事ではすべて PowerShell を利用して行います。

# Office 365 Management API とは？

[Office 365 Management API](https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-apis-overview) は Office 365 の中の、サービス通信、セキュリティ、コンプライアンス、レポート作成、監査などの管理タスクに対応した、API のプラットフォームです。

特に、[Office 365 管理アクティビティ API](https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-activity-api-reference) は、Office 365 と Azure Active Directory のアクティビティ ログからの、ユーザー、管理者、システム、およびポリシー アクションとポリシー イベントについての情報を提供します。

# 基本的な手順について

基本的な手順は、[Office 365 Management API の使用を開始する](https://docs.microsoft.com/ja-jp/office/office-365-management-api/get-started-with-office-365-management-apis)を参考にしていますが、少し古い部分もあるため、下記の4つのステップとしてまとめています。

## Step 1. Azure AD でアプリケーションを登録する。
アプリケーションが Office 365 Management API にアクセスできるようにするには、アプリケーションを Azure AD に登録する必要があります。これにより、アプリケーションの ID を設定して、API へのアクセスに必要なアクセス許可レベルを指定できるようになります。

## Step 2. Office 365 API サブスクリプションを作成する。
各アクティビティAPIからデータを取得するには、サブスクリプションを作成する必要があります。
ここでは、Audit.Generalのサブスクリプションを作成しますが、ほかにも下記があります。
＊Audit.AzureActiveDirectory
＊Audit.Exchange
＊Audit.SharePoint
＊Audit.General (上記のコンテンツ タイプに含まれない、その他すべてのワーク ロードが含まれます)
＊DLP.All (すべてのワークロードの DLP イベントのみ)

なお、アクティビティAPIのサブスクリプションの種類や詳細については、[Office 365 管理アクティビティ API の操作](https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-activity-api-reference#working-with-the-office-365-management-activity-api)をご参照ください。

## Step 3. Azure AD からアクセス トークンを要求する。
Azure AD で設定されているアプリケーションの資格情報を使用すると、アプリケーションは、テナント管理者の追加の操作を必要とすることなく、継続的に同意済みのテナントの追加のアクセストークンを要求します。

##4. Office 365 Management API の呼び出し。
アプリケーションを認証して承認するため、アプリ専用アクセストークンが Office 365 Management API に渡されます。

同意とアクセストークンの要求のシーケンスは下記図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/9bdd2e7f-e7c9-1fc9-06e8-c223b9414f3e.png)

# Step 1. Azure AD でアプリケーションを登録する。

Azure AD でのアプリケーションの登録は Azure Portal の Azure AD のメニューで行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/590efe43-bdc5-13b0-ec1c-122d8bb1557d.png)

Azure AD のアプリの登録から、新規登録をクリックします。名前を記入し、あとはデフォルトの値で登録します。

その後、そのアプリケーションを選択し、APIのアクセス許可から、Office 365 Management API を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/815103fa-ec1a-738e-7e53-5c1a2fa36c3a.png)

そして、アクセス許可の要求で、「委任されたアクセス許可」と「アプリケーションの許可」でそれぞれ必要なものをすべてクリックし、許可を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/0c8342bb-141d-ca04-aa53-e8a8ea87d796.png)

そしてドメインに管理者の同意を与えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/e3b6238d-64bb-a1e2-8daf-607b3c792ae7.png)

次に、証明書とシークレットに行き、新しいクライアントシークレットをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/fc471ecd-9cf7-3fa8-72e4-87c9b56c2534.png)

期限と説明を設定して作成します。作成時にシークレットが出てくるので、メモ帳などにコピーペーストしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/a3220fee-495c-fd8d-b87d-27230f5ac74b.png)

# Step 2. Office 365 API サブスクリプションを作成する。

次に Office 365 API のサブスクリプションを作成します。
まず、下記の<>を入力して、PowerShellで実行します。$Publisherは https://guidgenerator.com/ で GUID をひとつ作って入力します。

```Powershell
$ClientID = "<GUID> from AAD App Registration"
$ClientSecret = "<clientSecret> from AAD App Registrtion"
$loginURL = "https://login.microsoftonline.com/"
$tenantdomain = "<domain>.onmicrosoft.com"
$TenantGUID = "<tenantguid> from AAD"
$resource = "https://manage.office.com"
$body = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-version=1.0 -Body $body
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"} 
$publisher = "<randomGuid>" #GUID は https://guidgenerator.com/ で作成します。
```

そして、下記コマンドで Audit.General のサブスクリプションを作ります。(&がエスケープできない場合は、適宜変更してください（""で囲むなど）。）

```Powershell
Invoke-WebRequest -Method Post -Headers $headerParams -Uri https://manage.office.com/api/v1.0/$tenantGuid/activity/feed/subscriptions/start?contentType=Audit.General&PublisherIdentifier=$Publisher
```

(参考：DLP.ALLのサブスクリプションの作成は下記のようになります。）

```Powershell
Invoke-WebRequest -Method Post -Headers $headerParams -Uri https://manage.office.com/api/v1.0/$tenantGuid/activity/feed/subscriptions/start?contentType=DLP.ALL&PublisherIdentifier=$Publisher
```

# Step 3. Azure AD からアクセストークンを要求する。

下記コマンドを PowerShell で実行します。

```PowerShell
$ClientID = "<GUID> from AAD App Registration"
$ClientSecret = "<clientSecret> from AAD App Registrtion"
$loginURL = "https://login.microsoftonline.com/"
$tenantdomain = "<domain>.onmicrosoft.com"
$TenantGUID = "<tenantguid> from AAD"
$resource = "https://manage.office.com"

# auth
$body = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-version=1.0 -Body $body
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
```
正しく進むと、下記のように Bearer Token を取得することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/6ea4c546-91f0-08b3-5fe1-d68b71cf73c2.png)

# Step 4. Office 365 Management API の呼び出し。

PowerShell から Office 365 Management API を呼び出し、ログを取得してみます。時刻は必要に合わせて変更ください（API の仕様上、startTime と endTime の間が24時間以内である必要があります）。

なお、下記の PowerShell スクリプトは、[Microsoft の Sentinel 用 GitHub Repository](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/O365%20Data/O365APItoAS-Template/TimerTrigger/run.ps1) を参考に作成しています。

下記サンプルでは、recordType=0としてすべてのレコードタイプのログを取得しています。レコードを絞りたい時は、[リファレンス](https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-activity-api-schema#auditlogrecordtype)を参照しレコードタイプを明示的に指定してください。

また、サンプルには改ページの管理のための If 文が入っています。Management API における改ページ管理については[こちら](https://docs.microsoft.com/ja-jp/office/office-365-management-api/office-365-management-activity-api-reference#pagination)をご参照ください。

```PowerShell
#取得対象ログの時間を設定
$currentUTCtime = (Get-Date).ToUniversalTime()
$endTime = $currentUTCtime.AddHours(-48) | Get-Date -Format yyyy-MM-ddThh:mm:ss
$startTime = $currentUTCtime.AddHours(-72) | Get-Date -Format yyyy-MM-ddThh:mm:ss

#Subscription の種類とレコードタイプを設定
$contentTypes = "Audit.General"
$recordTypes = 0

#ContentTypes　を複数セットした際にループを回す
$contentTypes = $contentTypes.split(",")
    foreach($contentType in $contentTypes){
        $listAvailableContentUri = "https://manage.office.com/api/v1.0/$tenantGUID/activity/feed/subscriptions/content?contentType=$contentType&PublisherIdentifier=$publisher&startTime=$startTime&endTime=$endTime"
        do {
            #取得可能な Content の表示
            $contentResult = Invoke-RestMethod -Method GET -Headers $headerParams -Uri $listAvailableContentUri

            #ひとつひとつの Content に対して Data 取得のためのループを回す
            foreach($obj in $contentResult){
                #Retrieve Content
                $data = Invoke-RestMethod -Method GET -Headers $headerParams -Uri ($obj.contentUri)             
            }
            
            #改ページの管理
            $nextPageResult = Invoke-WebRequest -Method GET -Headers $headerParams -Uri $listAvailableContentUri
            If(($nextPageResult.Headers.NextPageUrl) -ne $null){
                $nextPage = $true
                $listAvailableContentUri = $nextPageResult.Headers.NextPageUrl
            }
            Else{$nextPage = $false}
        } until ($nextPage -eq $false)
    }
```

上手くデータが取得できれば、下記のようにデータが取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/1e8d341c-4039-6a8f-3b2d-4ee6ec04823a.png)

#まとめ

簡単ではありましたが、PowerShell から Office 365 の Management API を利用して、特に 管理アクティビティ API から Audit.General のログを取得してみました。

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。