Azure AD Join を切断した時のデバイス所有者を Log Analytics と組み合わせて特定する方法。

#はじめに

Azure AD Join した Windows 10 コンピューターには所有者として「職場または学校にアクセス」からサインインした UPN を確認することができます。
つまり、そのコンピューターを誰が所有しているかを UPN で確認することができます。

しかし、「職場または学校にアクセス」から「切断」したときには、そのコンピューターが誰が所有していたのかを Azure AD の監査ログから追うことができません。
(「デバイス ID」と「表示名」が記録されますが「所有者 (RegisteredOwnerUpn)」までは出力されません。)

切断されたデバイスに対して、後追いでこのコンピューターを使っていたのは誰だったのか？という調査をするためには、監査ログだけでは探せなくはないですが、30 日以前のログは後追いできないなど制約があります。

そこで、デバイスが「切断」された時点でデバイス管理者に通知を行い、PowerShell で事前に出力させていたリストと突き合わせることで、効率良く「所有者」を特定する方法をまとめましたので、以下にその手順を書きたいと思います。

#前提条件、構成
まず、Azure Monitor Log Analytics を利用するためには、Azure AD の Premium ライセンスとは別に Azure の***サブスクリプション***が必要になります。
なぜなら Log Analytics は Azure AD の機能ではなく、サブスクリプションを利用した「従量課金制」の Azure サービスだからです。

Azure AD Premium P1 以上のライセンスを持つことで、「***サインイン ログ***」と今回利用する「***監査ログ***」を最大 30 日間 Azure AD 側にデータが保存できます。

また、Azure AD 上のログを Azure Monitor Log Analytics に転送することで、ログを長期間 (30 日以上) 保存することができます。
Azure Monitor Log Analytics は予め 100 GB 単位でワークスペースを確保する「容量予約」とワークスペースにデータが取り込まれた GB 単位で課金する「従量課金制」の 2 つのタイプを選択することができます。

料金の詳細については下記 Microsoft の公開情報を確認してください。

-参考情報
Azure Monitor の価格
URL:https://azure.microsoft.com/ja-jp/pricing/details/monitor/

さて、今回これから構成しようとするイメージは下記イメージです。
PowerShell のスクリプトで取得したデバイス情報と、Log Analytics でデバイスが「切断」された際に出力された「デバイス ID」を突き合わせて削除された Windows 10 コンピューターの「所有者」を特定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/c0e0cd0e-62ee-78a5-1dcf-805f6cf3a58c.png)

さらに、「切断」されたタイミングで指定した電子メール アドレス宛にメールで通知する仕組みを構成します。

#やってみる
作業の概要としては以下となります。

1. PowerShell のスクリプト準備、デバイス情報一覧取得
2. Log Analytics の構成
3. デバイス削除時にメールで通知する仕組みを構成

#####1. PowerShell のスクリプト準備、デバイス情報一覧取得

Azure AD に登録されたデバイス情報は「Get-MsolDevice」コマンドレットで確認することができます。
対象の Azure AD テナント上のデバイス一覧を取得し、Excel ファイルにエクスポートする手順は下記の Microsoft の公開情報に記載されているので、そちらを参照してください。
※下記公開情報の「スクリプトを実行してデバイスの詳細情報を取得する」の項目が該当箇所になります。

-参考情報
Office 365 のモバイル デバイス管理 (MDM) によって管理されているデバイスの詳細情報を取得する
URL:https://support.office.com/ja-jp/article/Office-365-%e3%81%ae%e3%83%a2%e3%83%90%e3%82%a4%e3%83%ab-%e3%83%87%e3%83%90%e3%82%a4%e3%82%b9%e7%ae%a1%e7%90%86-MDM-%e3%81%ab%e3%82%88%e3%81%a3%e3%81%a6%e7%ae%a1%e7%90%86%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%82%8b%e3%83%87%e3%83%90%e3%82%a4%e3%82%b9%e3%81%ae%e8%a9%b3%e7%b4%b0%e6%83%85%e5%a0%b1%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b-5602963c-a1f2-4c21-afb9-f66cd7dca1f0

※上記のスクリプトの中で「DeviceTrustType」だけを追加で出力させたかったので、下記のようにスクリプトの内容を変更しています。

```powershell

param (
    [PSObject[]]$users = @(),
    [Switch]$export,
    [String]$exportFileName = "UserDeviceComplianceStatus_" + (Get-Date -Format "yyMMdd_HHMMss") + ".csv",
    [String]$exportPath = [Environment]::GetFolderPath("Desktop")
 )

[System.Collections.IDictionary]$script:schema = @{
    
    DeviceId = ''
    DeviceOSType = ''
    DeviceOSVersion = ''
    DeviceTrustLevel = ''
    DeviceTrustType = ''
    DisplayName = ''
    IsCompliant = ''
    IsManaged = ''
    ApproximateLastLogonTimestamp = ''
    DeviceObjectId = ''    
    RegisteredOwnerUpn = ''
    RegisteredOwnerObjectId = ''
    RegisteredOwnerDisplayName = ''
}

function createResultObject
{

    [PSObject]$resultObject = New-Object -TypeName PSObject -Property $script:schema

    return $resultObject
}

If ($users.Count -eq 0)
{
    $users = Get-MsolUser
}

[PSObject[]]$result = foreach ($u in $users)
{
    
    [PSObject]$devices = get-msoldevice -RegisteredOwnerUpn $u.UserPrincipalName
    foreach ($d in $devices)
    {
        [PSObject]$deviceResult = createResultObject
        $deviceResult.DeviceId = $d.DeviceId 
        $deviceResult.DeviceOSType = $d.DeviceOSType 
        $deviceResult.DeviceOSVersion = $d.DeviceOSVersion 
        $deviceResult.DeviceTrustLevel = $d.DeviceTrustLevel
	$deviceResult.DeviceTrustType = $d.DeviceTrustType
        $deviceResult.DisplayName = $d.DisplayName
        $deviceResult.IsCompliant = $d.GraphDeviceObject.IsCompliant
        $deviceResult.IsManaged = $d.GraphDeviceObject.IsManaged
        $deviceResult.DeviceObjectId = $d.ObjectId
        $deviceResult.RegisteredOwnerUpn = $u.UserPrincipalName
        $deviceResult.RegisteredOwnerObjectId = $u.ObjectId
        $deviceResult.RegisteredOwnerDisplayName = $u.DisplayName
        $deviceResult.ApproximateLastLogonTimestamp = $d.ApproximateLastLogonTimestamp

        $deviceResult
    }

}

If ($export)
{
    $result | Export-Csv -path ($exportPath + "\" + $exportFileName) -NoTypeInformation
}
Else
{
    $result
}
```

PowerShell ファイル名「Get-MsolUserDeviceComplianceStatus.ps1」を実行すると以下のように「RegisteredOwnerUpn 」を含めた形でデバイス一覧が取得できます。

```powershell

PS C:\test> .\Get-MsolUserDeviceComplianceStatus.ps1


RegisteredOwnerUpn            : test003@shyamag025.onmicrosoft.com
DeviceObjectId                : 91c09821-84d3-4d79-8044-077d9f166cb9
DeviceOSType                  : Windows
IsCompliant                   :
DisplayName                   : Windows10-003
DeviceOSVersion               : 10.0.17763.0
RegisteredOwnerDisplayName    : test003@shyamag025.onmicrosoft.com
RegisteredOwnerObjectId       : 11c2c3da-2927-4de9-9ea7-ac706ba8a6ba
DeviceTrustType               : Azure AD Joined
IsManaged                     :
DeviceId                      : d921e2fd-6147-47b8-983a-0e707a956fc0
ApproximateLastLogonTimestamp : 2020/03/15 6:40:09
DeviceTrustLevel              : Authenticated

RegisteredOwnerUpn            : test002@shyamag025.onmicrosoft.com
DeviceObjectId                : d7bd6382-15e9-46e2-ba4f-f8198177ebd9
DeviceOSType                  : Windows
IsCompliant                   :
DisplayName                   : Windows10-002
DeviceOSVersion               : 10.0.17763.0
RegisteredOwnerDisplayName    : test002@shyamag025.onmicrosoft.com
RegisteredOwnerObjectId       : 97c64c60-135a-4663-8fdd-17bf6019dd10
DeviceTrustType               : Azure AD Joined
IsManaged                     :
DeviceId                      : 807f69e6-aa07-4a8b-bd65-c5be8d687117
ApproximateLastLogonTimestamp : 2020/03/15 6:12:22
DeviceTrustLevel              : Authenticated

RegisteredOwnerUpn            : test001@shyamag025.onmicrosoft.com
DeviceObjectId                : 2116a0ab-c53a-4d8d-b2df-45774c8beded
DeviceOSType                  : Windows
IsCompliant                   :
DisplayName                   : Windows10-001
DeviceOSVersion               : 10.0.17763.0
RegisteredOwnerDisplayName    : test001@shyamag025.onmicrosoft.com
RegisteredOwnerObjectId       : 9aeb6672-cf14-43a2-bc36-8dae82e971de
DeviceTrustType               : Azure AD Joined
IsManaged                     :
DeviceId                      : f141bd19-c231-4097-871f-4431934f2d1b
ApproximateLastLogonTimestamp : 2020/03/15 6:06:44
DeviceTrustLevel              : Authenticated
```

これを「.\Get-MsolUserDeviceComplianceStatus.ps1 -Export」として引数に「-Export」を指定すると規定ではデスクトップ上に Excel ファイルが出力されます。
下記画面ショットのようにファイルができますので、Azure AD に登録されているデバイスを棚卸するためにも使えると思います。
この記事で押さえておくべき項目(列)は「***RegisteredOwnerUpn***」「***DeviceObjectId***」「***DisplayName***」の3つになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/4619c16e-e754-ceb4-e40b-8dad6da59a84.png)

#####2. Log Analytics の構成

Azure AD の監査ログを Log Analytics で分析するために、Log Analytics の構成を行います。
前提として、冒頭に触れましたとおり、サブスクリプションを用意する必要があります。
今回は 30 日間無料で使える無料サブスクリプションを使って構成してみます。

Azure サービス一覧から「Log Analytics ワークスペース」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/9838d06f-a303-75c8-8642-506afde49c0e.png)

画面左上の「追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/70ec17d5-435e-4cf5-35e8-beea704ad5a7.png)

Log Analytics ワークスペース画面で必要事項を入力、選択し、画面下の「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/3af9a329-4ce9-7ab0-27ab-bdcb351ee786.png)

Log Analytics ワークスペース一覧に作成したワークスペースが表示されることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/e4dd3466-c1ee-2cf7-f5f0-da7c224c45e7.png)

次に、Azure AD 概要画面の左ペインより、「診断設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/c4845619-997e-c76f-7a2f-d766e4f5a9ec.png)

診断設定の画面より、「＋診断設定を追加する」のリンクをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/044f9998-2979-149f-c981-b5a87700c378.png)

下記画面ショットのように、「診断設定の名前」を入力し、Log の種類として「AuditLogs (監査ログ)」と「SinInLogs (サインインログ)」にチェックをいれ、宛先の詳細に「Log Analytics への送信」にチェックを入れた状態で画面左上の「保存」をクリックします。
(今回は AuditLogs 内のログを検索対象にするので、SinInLogs のチェックは必須ではありません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/7ecabe15-98a0-68b5-bb4e-56939cc81787.png)

上記設定をすることで、Azure AD の監査ログとサインイン ログが Log Analytics のワークスペース「AzureADLog0315」に取り込まれるようになりました。
この状態で一度 Azure AD Join をしている Windows 10 コンピューターの 1 台を「職場または学校にアクセス」から「切断」してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/67088346-9cb2-7b71-8879-0d3996f957ac.png)

「切断」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/64d12865-6039-6695-fb7d-847a99488a24.png)

ローカル管理者アカウントの資格情報を入力して「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/df65a9a7-ba8e-52b0-1506-8ee875d0ff74.png)

「今すぐ再起動する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/29e5485e-3212-9c1e-e610-3cd029e2250e.png)

Azure AD のすべてのデバイスからは対象のデバイス (Windows10-001) が削除されていることが確認できます。
監査ログへの出力は数分かかるので待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/e617513f-c77f-2627-c4d6-d14bed5ae260.png)

数分待った後に、Log Analytics ワークスペース (AzureADLog0315) に移動し、左ペインのログをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/e87c3bca-6f09-fa6e-6318-3251d2b1383f.png)

真ん中上の空白の部分が Kusto クエリという、取り込んだログを検索するためのクエリを実行するスペースになります。
このスペースに以下クエリを入力し、「実行」をクリックします。

| 項目       |      Azure AD 監査ログ |    Log Analytics    |
|:-----------------|:------------------|:------------------|
| 検索元|        監査ログ      |        AuditLogs|
|検索範囲 (Where) |     アクティビティ       |  OperationName     |
| アクティビティの種類|              Delete device|        Delete device|

```sql
AuditLogs
| where OperationName == "Delete device" 
```

ちなみにですが、アクティビティの種類は「大文字」「小文字」の判定をするので、「Delete Device」と指定すると検索条件に合致しないので注意が必要です。(実際に試してみると分かると思いますので試してみてください)

結果として下記画面ショットのように 1 件のレコードがヒットしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/122ec8e4-f5b7-c6f3-cf0d-927afdd7fd39.png)

出力結果の中で、「TargetResources」の項目に注目します、「displayName」と「Device ID」に注目します。

```bash
powershell
TargetResources
[{"displayName":"Windows10-001","modifiedProperties":[],"type":"Device","id":"2116a0ab-c53a-4d8d-b2df-45774c8beded"}]
0
{"displayName":"Windows10-001","modifiedProperties":[],"type":"Device","id":"2116a0ab-c53a-4d8d-b2df-45774c8beded"}

displayName Windows10-001
Id 2116a0ab-c53a-4d8d-b2df-45774c8beded
modifiedProperties []
Type Device
```

つまり、削除されたデバイスの「Device ID」と PowerShell で取得した「DeviceObjectId」を比較して合致する ID の「RegisteredOwnerUpn」が削除されたデバイスの所有者 (UPN) であることが確認できます。

| 項目       |      DeviceObjectId|    Device Id|   DisplayName    | RegisteredOwnerUpn   |
|:-----------------|:------------------|:------------------|:------------------|:------------------|
| PowerShell |    2116a0ab-c53a-4d8d-b2df-45774c8beded    |  |      Windows10-001| ***test001@shyamag025.onmicrosoft.com*** |
|Log Analytics|       | 2116a0ab-c53a-4d8d-b2df-45774c8beded |      Windows10-001|  |

上記のように照らし合わせることで、削除されたデバイスの所有者が「 ***test001@shyamag025.onmicrosoft.com***」であることが分かりました。
これで、Log Analytics のログから後追いで削除されたデバイスの所有者を特定できる方法が確立できましたが、デバイス自体が「いつ」削除されるのかはデバイス管理者が把握することは難しいと思います。

そこで、最後のステップで、デバイスが削除 (Delete device) されたタイミングで管理者にメールで通知する仕組みを構成し、管理者がデバイス削除に気づけるようにしたいと思います。

#####3. デバイス削除時にメールで通知する仕組みを構成

デバイスの削除をトリガーにして、メール アドレスに通知する機能は、Azure Monitor の機能に備わっています。具体的な構成手順を見ていきます。
前段の Log Analytics の「ログ」の項目でクエリを実行したかと思いますが、そのクエリの画面の上に「＋新しいアラート ルール」という項目があるのでクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/40130164-076e-67a9-cbdb-1fa020d14627.png)


ルールの作成の画面に遷移します。この画面でルールを定義していきます。
「条件」の項目でロジックを定義するのでリンクをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/e042c679-7bf0-ccff-d081-bc27996a4f13.png)

以下は例ですが、検索結果として「Delete device」の条件に合致した数が「1」つでもあった場合、且つ評価基準を「過去 1440 分 (24時間)」と指定しています。「完了」をクリックします。
(過去 1 日 の *Custom log search* ログ クエリ内の 結果の数 が 次の値より大きい 1 の場合。5 分 ごとに評価されます。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/34402b58-7a00-8428-61d4-b2023dfdb74d.png)

次に「アクション グループ」の「作成」をクリックします。
ここで「条件」に合致する結果が出力された場合に具体的に「どうするか」を決めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/bfa2fe08-9dd0-c995-f4d1-e3cac9ebe282.png)

アクション グループの追加の画面で必要事項を入力、選択していき、「アクション」の欄で「アクションの種類」として「電子メール/SMS/プッシュ通知/音声」をプルダウンメニューから選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/4491358c-8be1-9822-5906-7e0424ec5fe4.png)

下記画面が表示されるので、「電子メール」のチェック ボックスにチェックを入れ、通知先の電子メールを入力し、画面下の「OK」をクリックします。
画面上に表示されているとおり、メールだけではなく、SMS や 音声による通知も可能なようです。
(ただ、音声は国コードが「1 (アメリカ)」しか選択できないので、「日本 (+81)」はまだ未対応なようです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/fc081901-0955-c3d0-afcb-22a141c7f4eb.png)

アクション グループが追加されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/9c323fb0-b658-c2c6-c762-799a4b06cadd.png)

次に、アクションをカスタマイズするの項目で「メールの件名」のチェックボックスにチェックを入れます。
また、下記画面ショットのように「メールの件名」や「重要度」などを入力、選択し、画面下の「アラート ルールの作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/b240afb7-1f28-4eaa-d754-bc25b5222b42.png)

アラート ルールが正常に作成されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/77994467-1d52-89eb-d34e-a3f597b4e75f.png)

作成されたアラート ルールを確認するためには、「すべてのサービス」→「モニター」→「アラート」の順で表示される、下記画面ショットの「アラート ルールの管理」をクリックすることで確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/f1ae9b03-bc15-c07d-9780-1e88fd51220f.png)

下記画面ショットのように定義したアラート ルールが表示されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/d1a6543a-8d74-8500-7730-dfd72b08a853.png)

定義したとおり、「5分毎」に過去「24時間」の Log Analytics ワークスペース内のログを対象に指定したクエリが定期実行され、「1」つ以上合致した場合には、指定したアドレス宛に「メール」が「自動的に通知」通知される仕組みができました。
実際には、下記のような形でメールが飛んできます。

※この通知を出す前に追加で「Windows10-002」も「切断」したので、カウントが「2」となっています。 
「View2 result(s)」のボタンをクリックすると、Azure AD の認証エンドポイントにリダイレクトされ、管理者でサインインすると Log Analytics のワークスペースのクエリ実行画面に自動で遷移するので非常に便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/135506f5-7e25-ca07-2940-08b282753005.png)

ちなみにスマートフォンへの SMS 通知は以下のような感じで通知されます。
PC がなくてもスマートフォンを持ち歩いていれば、Azure Monitor で設定した通知が飛んでくるので常に PC に張り付いている必要もなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/801edcff-7561-bf56-a8d8-d7332e39b19f.png)

#おわりに
今回は Azure AD の監査ログと Azure Monitor Log Analytics を組み合わせて PowerShell で取得したデバイス情報と「Device ID」を突き合わせることで、削除されたデバイスの所有者 (UPN) を特定する方法を動作確認してみました。

このまま運用として使えるレベルにまで落とし込んだつもりです。
もちろん Azure Monitor は今回のような使い方だけでなく、サーバーやアプリケーション監視にも使える非常に柔軟なツールでので、是非活用してみてください。
今回の記事が少しでも参考になれば幸いです。