次の方法で共有


チュートリアル: Microsoft Entra のデータを使用して Azure Data Explorer でカスタマイズされたレポートを作成する

このチュートリアルでは、Microsoft Entra ID および Microsoft Entra ID ガバナンス サービスのデータを使用して 、Azure Data Explorer でカスタマイズされたレポートを作成する方法について説明します。

このチュートリアルでは、 Azure Monitor を使用したアーカイブやレポート作成、エンタイトルメント管理などのレポート オプションを補完します。このオプションでは、保持と分析のために監査ログを Azure Monitor にエクスポートすることに重点を置いています。 これに対して、Microsoft Entra ID と Microsoft Entra ID ガバナンス データを Azure Data Explorer にエクスポートすると、履歴オブジェクトや削除されたオブジェクトなど、Microsoft Entra オブジェクトに対してカスタム レポートを柔軟に作成できます。

Azure Data Explorer を使用した Microsoft Entra ID ガバナンス データに関するレポートの概要を簡単に説明するビデオを次に示します。

Azure Data Explorer を使用すると、大規模なスケーラビリティ、柔軟なスキーマ、保持ポリシーを使用して、追加のソースからのデータ集計も可能になります。 Azure Data Explorer は、ユーザー アクセス データを何年も保持したり、アドホック調査を実行したり、アクセス データに対してカスタム クエリを実行したりする必要がある場合に特に役立ちます。

データ抽出とクエリを示す概念図。

このチュートリアルでは、Microsoft Entra からエクスポートされた構成、ユーザー、アクセス権を、他のソース (独自の SQL データベースのアクセス権を持つアプリケーションなど) からエクスポートされたデータと共に表示する方法について説明します。 次に、Azure Data Explorer で Kusto 照会言語 (KQL) を使用して、組織の要件に基づくカスタムレポートを構築します。

このチュートリアルでは、次の操作を行います。

  • Azure サブスクリプションで Azure Data Explorer を設定するか、無料のクラスターを作成します。
  • PowerShell スクリプトと Microsoft Graph を使用して Microsoft Entra ID からデータを抽出します。
  • テーブルを作成し、Microsoft Entra ID から Azure Data Explorer にデータをインポートします。
  • Microsoft Entra ID ガバナンスからデータを抽出します。
  • Microsoft Entra ID Governance から Azure Data Explorer にテーブルを作成し、データをインポートします。
  • KQL を使用してカスタム クエリを作成します。
  • Azure Monitor でデータのクエリを実行します。

このチュートリアルを終了する頃には、ユーザーのアクセス権とアクセス許可に関するカスタマイズされたビューを作成できるようになります。 これらのビューは、Microsoft でサポートされているツールを使用して複数のアプリケーションにまたがっています。 また、Microsoft 以外のデータベースまたはアプリケーションからデータを取り込んで、それらのアクセス権とアクセス許可について報告することもできます。

前提条件

Azure Data Explorer を初めて使用する場合に、このチュートリアルで示されているシナリオを学習したい場合は、 無料の Azure Data Explorer クラスターを入手できます。 Azure Data Explorer のサービス レベル アグリーメントで運用環境でサポートされている使用を行うには、完全な Azure Data Explorer クラスターをホストするための Azure サブスクリプションが必要です。

レポートに含めるデータを決定します。 このチュートリアルのスクリプトは、Microsoft Entra のユーザー、グループ、アプリケーションからの特定のデータを含むサンプルを提供します。 これらのサンプルは、この方法で生成できるレポートの種類を示していますが、特定のレポートのニーズが異なり、異なるデータや追加のデータが必要になる場合があります。 これらのオブジェクトから始めて、徐々に Microsoft Entra のオブジェクトの種類を増やしていくことができます。

  • このチュートリアルでは、サインインしているユーザーとして Microsoft Entra からデータを取得する方法について説明します。 そのためには、必要なロールの割り当てがあることを確認します。 使用する Microsoft Entra データの種類をエクスポートするには、適切なアクセス許可を持つロールが必要です。

    • ユーザー データ: グローバル管理者、特権ロール管理者、ユーザー管理者
    • グループ データ: グローバル管理者、特権ロール管理者、グループ管理者
    • アプリケーションとアプリ ロールの割り当て: グローバル管理者、特権ロール管理者、アプリケーション管理者、クラウド アプリケーション管理者
  • Microsoft Graph PowerShell では、Microsoft Graph 経由で Microsoft Entra オブジェクトを取得するための同意が必要です。 このチュートリアルの例では、委任された User.Read.AllGroup.Read.AllApplication.Read.All、および Directory.Read.All アクセス許可が必要です。 サインインしているユーザーなしでオートメーションを使用してデータを取得する予定がある場合は、代わりに対応するアプリケーションのアクセス許可に同意してください。 詳細については、「Microsoft Graph のアクセス許可リファレンス」を参照してください。

    これらのアクセス許可に対する Microsoft Graph PowerShell の同意をまだ付与していない場合は、この同意操作を実行する全体管理者である必要があります。

  • このチュートリアルでは、カスタム セキュリティ属性については説明しません。 既定では、グローバル管理者およびその他の管理者のロールには、Microsoft Entra ユーザーからカスタム セキュリティ属性を読み取るためのアクセス許可は含まれていません。 カスタム セキュリティ属性の取得を計画している場合は、さらに多くのロールとアクセス許可が必要になる場合があります。

  • Microsoft Graph PowerShell がインストールされているコンピューターで、ファイル システム ディレクトリへの書き込みアクセス権があることを確認します。 このディレクトリでは、必要な Microsoft Graph PowerShell モジュールをインストールし、エクスポートした Microsoft Entra データを保存します。

  • そのデータを Azure Data Explorer に組み込む場合は、Microsoft Entra 以外の他のデータ ソースからデータを取得するアクセス許可があることを確認します。

Azure Data Explorer を設定する

Azure Data Explorer をまだ使用していない場合は、最初に設定する必要があります。 無料のクラスターは、 Azure サブスクリプションまたはクレジット カードなしで作成できます。 または、Azure サブスクリプションが必要な完全なクラスターを作成することもできます。 開始するには、「 クイック スタート: Azure Data Explorer クラスターとデータベースを作成する」を参照してください。

PowerShell を使用して Microsoft Entra ID データを抽出する

このセクションでは、 Microsoft Graph PowerShell モジュールをインストールします。 PowerShell では、 Microsoft Graph に接続して Microsoft Entra ID データを抽出します。

組織でこのシナリオにこれらのモジュールを初めて使用するときは、Microsoft Graph PowerShell がテナントで使用するための同意を付与できるように、グローバル管理者ロールが必要です。 後続のインタラクションでは、低権限のロールを使用できます。

  1. PowerShell を開きます。

  2. インストールされていない Microsoft Graph PowerShell モジュールがある場合は、必要な Microsoft Graph モジュールをインストールします。 チュートリアルのこのセクションでは、 Microsoft.Graph.AuthenticationMicrosoft.Graph.UsersMicrosoft.Graph.GroupsMicrosoft.Graph.ApplicationsMicrosoft.Graph.DirectoryObjectsの各モジュールが必要です。 これらのモジュールが既にインストールされている場合は、この手順をスキップします。

       $modules = @('Microsoft.Graph.Users', 'Microsoft.Graph.Groups', 'Microsoft.Graph.Applications', 'Microsoft.Graph.DirectoryObjects') 
       foreach ($module in $modules) { 
       Install-Module -Name $module -Scope CurrentUser -AllowClobber -Force
       } 
    
  3. モジュールを現在の PowerShell セッションにインポートします。

      $modules = @('Microsoft.Graph.Users', 'Microsoft.Graph.Groups', 'Microsoft.Graph.Applications', 'Microsoft.Graph.DirectoryObjects') 
      foreach ($module in $modules) { 
      Import-Module -Name $module 
      } 
    
  4. Microsoft Graph に接続します。 このセクションでは、ユーザー、グループ、アプリケーションの読み取りについて説明します。そのため、 User.Read.AllGroup.Read.AllApplication.Read.All、および Directory.Read.All アクセス許可スコープが必要です。 アクセス許可の詳細については、Microsoft Graph のアクセス許可リファレンスをご覧ください。

      Connect-MgGraph -Scopes "User.Read.All", "Group.Read.All", "Application.Read.All", "Directory.Read.All" -ContextScope Process -NoWelcome
    

    このコマンドを実行すると、Microsoft Entra の資格情報でサインインするよう求められます。 サインイン後、初めて接続する場合、または新しいアクセス許可が必要な場合は、必要なアクセス許可に同意する必要があります。

カスタム レポートの Microsoft Entra ID データを抽出するための PowerShell クエリ

次のクエリでは、PowerShell を使用して Microsoft Graph から Microsoft Entra ID データを抽出し、そのデータを JSON ファイルにエクスポートします。 これらのファイルは、 このチュートリアルの後のセクションで Azure Data Explorer にインポートします。

この種類のデータを使用してレポートを生成するシナリオは次のとおりです。

  • 監査担当者は、10 グループのグループ メンバーをメンバーの部署別に一覧表示するレポートを表示したいと考えています。
  • 監査担当者は、2 つの日付の間にアプリケーションにアクセスしたすべてのユーザーのレポートを表示したいと考えています。

Microsoft Entra 以外のソースから Azure Data Explorer にデータを取り込むこともできます。 この機能のシナリオは次のとおりです。

  • 管理者は、Microsoft Entra ID からアプリケーションに追加されたすべてのユーザーと、アプリケーションの独自のリポジトリ (SQL データベースなど) でのアクセス権を表示したいと考えています。

これらの種類のレポートは、Microsoft Entra ID には組み込まれません。 ただし、これらのレポートを自分で作成するには、Microsoft Entra ID からデータを抽出し、Azure Data Explorer でカスタム クエリを使用してデータを結合します。 このチュートリアルでは、後の 「他のソースからのデータの取り込み」の記事で 、このプロセスについて説明します。

このチュートリアルでは、次の領域から Microsoft Entra ID データを抽出します。

  • 表示名、UPN、ジョブの詳細などのユーザー情報
  • メンバーシップを含むグループ情報
  • アプリケーションとアプリケーションロールへの割り当てについて

このデータ セットを使用すると、アプリケーションロール情報と関連する期間を使用して、アプリケーションへのアクセスを受け取ったユーザーに関する広範なクエリセットを実行できます。 これらはサンプル クエリであり、データと特定の要件は、ここに示されているものとは異なる場合があることに注意してください。

大規模なテナントでは、Microsoft Graph モジュールが処理するスロットリングと 429 エラーが発生する可能性があります。 Azure Data Explorer では、ファイルのアップロード サイズが制限される場合もあります。

これらの PowerShell スクリプトでは、選択したプロパティを Microsoft Entra オブジェクトから JSON ファイルにエクスポートします。 これらのエクスポートされたプロパティのデータは、Azure Data Explorer でカスタム レポートを生成するために使用されます。

このデータを使用して、Azure Data Explorer で作成できるレポートの種類を示しているため、以下の特定のプロパティがこれらの例に含まれています。 特定のレポートのニーズは、このチュートリアルで示されているものとは異なる可能性があるため、レポートで表示する必要があるこれらのスクリプトに特定のプロパティを含める必要があります。 ただし、スクリプトのビルドに役立つのと同じパターンに従うことができます。

スナップショットの日付を選択する

ハードコーディングされた スナップショット日付 は、特定の日付で JSON ファイル内のデータを識別します。 これを使用して、Azure Data Explorer で同様のデータ セットを時間の経過と同時に追跡できます。 スナップショット日付は、2 つのスナップショット日付間のデータの変更を比較する場合にも役立ちます。

$SnapshotDate = Get-Date -AsUTC -Format "yyyy-MM-dd"

Microsoft Entra ユーザー データを取得する

このスクリプトは、選択したプロパティを Microsoft Entra ユーザー オブジェクトから JSON ファイルにエクスポートします。 このファイルと他の JSON ファイルの追加データは、 このチュートリアルの後のセクションで Azure Data Explorer にインポートします。

  function Export-EntraUsersToJson { 

  # Define a hash table for property mappings 
   $propertyMappings = @{ 
    "Id" = "ObjectID" 
    "DisplayName" = "DisplayName" 
    "UserPrincipalName" = "UserPrincipalName" 
    "EmployeeId" = "EmployeeId" 
    "UserType" = "UserType" 
    "CreatedDateTime" = "CreatedDateTime" 
    "JobTitle" = "JobTitle" 
    "Department" = "Department" 
    "AccountEnabled" = "AccountEnabled" 

   # Add custom properties as needed 
    "custom_extension" = "CustomExtension" 
   } 
  # Retrieve users with specified properties and create custom objects directly 
   $users = Get-MgUser -Select ($propertyMappings.Keys) -All | ForEach-Object { 
      $userObject = @{} 
      foreach ($key in $propertyMappings.Keys) { 
        if ($key -eq "CreatedDateTime") { 
          # Convert date string directly to DateTime and format it 
          $date = [datetime]::Parse($_.$key) 
          $userObject[$propertyMappings[$key]] = $date.ToString("yyyy-MM-dd") 
        } else { 
          $userObject[$propertyMappings[$key]] = $_.$key 
        } 
      } 
      # Additional properties or transformations 
      $userObject["SnapshotDate"] = $SnapshotDate
      [pscustomobject]$userObject 
    } 
    # Convert the user data to JSON and save it to a file 
    $users | ConvertTo-Json -Depth 2 | Set-Content ".\EntraUsers.json" 
  } 
  # Execute the function 
  Export-EntraUsersToJson 

グループ データを取得する

Azure Data Explorer でカスタム ビューを作成するために使用する、グループ名と ID を含む JSON ファイルを生成します。 このサンプルにはすべてのグループが含まれていますが、必要に応じて追加のフィルター処理を含めることができます。 特定のグループのみを含むようにフィルター処理する場合は、入れ子になったグループを確認するロジックをスクリプトに含めることができます。

    # Get all groups and select Id and DisplayName 
    $groups = Get-MgGroup -All | Foreach-Object {
       $groupObject = @{} 
       $groupObject["Id"] = $_.Id
       $groupObject["DisplayName"] = $_.DisplayName
       $groupObject["SecurityEnabled"] = $_.SecurityEnabled
       $groupObject["MailEnabled"] = $_.MailEnabled
       $groupObject["MailNickname"] = $_.MailNickname
       $groupObject["SecurityIdentifier"] = $_.SecurityIdentifier
       $date = [datetime]::Parse($_.CreatedDateTime) 
       $groupObject["CreatedDateTime"] = $date.ToString("yyyy-MM-dd") 
       $groupObject["SnapshotDate"] = $SnapshotDate
      [pscustomobject]$groupObject 
    }
    # Export the groups to a JSON file 
    $groups | ConvertTo-Json | Set-Content ".\EntraGroups.json" 

グループ メンバーシップ データを取得する

グループ メンバーシップを持つ JSON ファイルを生成します。これは、Azure Data Explorer でカスタム ビューを作成するために使用されます。 このサンプルにはすべてのグループが含まれていますが、必要に応じて追加のフィルター処理を含めることができます。

    # Retrieve all groups from Microsoft Entra ID 
    $groups = Get-MgGroup -All 
    # Initialize an array to store results 
    $results = @() 
    # Iterate over each group 
    foreach ($group in $groups) { 
      # Extract the group ID 
      $groupId = $group.Id 
      # Get members of the current group and select their IDs 
      $members = Get-MgGroupMember -GroupId $groupId | Select-Object -ExpandProperty Id 
      # Add a custom object with group ID and member IDs to the results array 
      $results += [PSCustomObject]@{ 
        GroupId = $groupId 
        Members = $members 
        SnapshotDate = $SnapshotDate
      } 
      # Pause for a short time to avoid rate limits 
      Start-Sleep -Milliseconds 200 
    } 
    # Convert the results array to JSON format and save it to a file 
    $results | ConvertTo-Json | Set-Content "EntraGroupMemberships.json" 

アプリケーションとサービス プリンシパルのデータを取得する

テナント内のすべてのアプリケーションと対応するサービス プリンシパルを含む JSON ファイルを生成します。 このデータは、このデータに基づいてアプリケーションに関連するカスタム レポートを生成できるように、 このチュートリアルの後のセクションで Azure Data Explorer にインポートします。

    # Fetch applications and their corresponding service principals, and then export to JSON 
    Get-MgApplication -All | ForEach-Object { 
      $app = $_ 
      $sp = Get-MgServicePrincipal -Filter "appId eq '$($app.AppId)'" 
      $date = [datetime]::Parse($app.CreatedDateTime)
      [pscustomobject]@{ 
        DisplayName     = $app.DisplayName
        ApplicationId   = $app.AppId 
        ServicePrincipalId = $sp.Id 
        SnapshotDate = $SnapshotDate
        CreatedDateTime = $date.ToString("yyyy-MM-dd")
      } 
    } | ConvertTo-Json -Depth 10 | Set-Content "Applications.json" 

アプリの役割データを取得します

Microsoft Entra でエンタープライズ アプリのすべてのアプリ ロールの JSON ファイルを生成します。 このデータを Azure Data Explorer にインポートした後、それを使用して、ユーザーのアプリ ロールの割り当てを含むレポートを生成します。

    # Get a list of all applications, and handle pagination manually if necessary 
    $apps = Get-MgApplication -All 
    # Loop through each application to gather the desired information 
    $results = foreach ($app in $apps) { 
      # Get the service principal for the application by using its app ID 
      $spFilter = "appId eq '$($app.AppId)'" 
      $sp = Get-MgServicePrincipal -Filter $spFilter | Select-Object -First 1 
      # Process app roles, if any, for the application 
      $appRoles = if ($app.AppRoles) { 
        $app.AppRoles | Where-Object { $_.AllowedMemberTypes -contains "User" } | 
        Select-Object Id, Value, DisplayName 
      } 
      # Construct a custom object with application and service principal details 
      [PSCustomObject]@{ 
        ApplicationId    = $app.AppId 
        DisplayName     = $app.DisplayName 
        ServicePrincipalId = $sp.Id 
        AppRoles      = $appRoles 
        SnapshotDate = $SnapshotDate
      } 
    } 
    # Export the results to a JSON file 
    $results | ConvertTo-Json -Depth 4 | Out-File 'AppRoles.json' 

アプリ ロールの割り当てデータを取得する

テナント内のユーザーのすべてのアプリ ロール割り当ての JSON ファイルを生成します。

    $users = Get-MgUser -All 
    $result = @() 
    foreach ($user in $users) { 
      Get-MgUserAppRoleAssignment -UserId $user.Id | ForEach-Object { 
        # Use the same date formatting approach 
        $createdDateTime = $_.CreatedDateTime -replace "\\/Date\((\d+)\)\\/", '$1' 
        # Convert the milliseconds timestamp to a readable date format if necessary 
        $result += [PSCustomObject]@{ 
          Id = $_.Id
          AppRoleId      = $_.AppRoleId
          CreatedDateTime   = $createdDateTime
          PrincipalDisplayName = $user.DisplayName
          PrincipalId     = $user.Id
          AssignmentPrincipalType = $_.PrincipalType
          AssignmentPrincipalDisplayName = $_.PrincipalDisplayName
          AssignmentPrincipalId     = $_.PrincipalId
          ResourceDisplayName = $_.ResourceDisplayName
          ResourceId      = $_.ResourceId
          SnapshotDate     = $SnapshotDate
        } 
      } 
    } 
    $result | ConvertTo-Json -Depth 10 | Out-File "AppRoleAssignments.json" 

Microsoft Entra ID から Azure Data Explorer にテーブルを作成し、データを含む JSON ファイルをインポートする

このセクションでは、Microsoft Entra ID サービス用に新しく作成した JSON ファイルを Azure Data Explorer のテーブルとしてインポートし、さらに分析します。 Azure Data Explorer Web UI を使用した最初のインポートでは、Web UI が各 JSON ファイルから提案するスキーマに基づいてテーブルを作成します。

  1. Azure Data Explorer の Web UI にサインインします。

  2. このチュートリアルの前半で、Azure Data Explorer クラスターまたは無料クラスターで設定したデータベースに移動します。

  3. 左側のメニューで、[クエリ] を選択 します

  4. エクスポートされた各 JSON ファイルに対して次の手順に従って、エクスポートしたデータを新しいテーブルとしてその Azure Data Explorer データベースに取得します。

    1. データを取り込むデータベースの名前を右クリックします。 次に、[ データの取得] を選択します。

      データベースのショートカット メニューとデータを取得するためのコマンドが強調表示されているクエリ タブのスクリーンショット。

    2. 使用可能なリストからデータ ソースを選択します。 このチュートリアルでは、ローカル ファイルからデータを取り込んでいるので、[ ローカル ファイル] を選択します。

    3. [ + 新しいテーブル ] を選択し、インポートする JSON ファイルの名前に基づいてテーブル名を入力します。 たとえば、 EntraUsers.jsonインポートする場合は、テーブル に EntraUsers という名前を付けます。 最初のインポート後、テーブルは既に存在しているので、その後のインポートのターゲット テーブルとして選択できます。

    4. [ ファイルの参照] を選択し、JSON ファイルを選択して、[ 次へ] を選択します。

    5. Azure Data Explorer によってスキーマが自動的に検出され、[ 検査 ] タブにプレビューが表示されます。[ 完了] を 選択してテーブルを作成し、そのファイルからデータをインポートします。 データが取り込まれたら、[ 閉じる] を選択します。

    6. 前のセクションで生成した JSON ファイルごとに、前の手順を繰り返します。

これらの手順の最後には、データベースにテーブル EntraUsersEntraGroupsEntraGroupMembershipsApplicationsAppRoles、および AppRoleAssignments があります。

PowerShell を使用して Microsoft Entra ID ガバナンス データを抽出する

このセクションでは、PowerShell を使用して Microsoft Entra ID ガバナンス サービスからデータを抽出します。 Microsoft Entra ID Governance、Microsoft Entra ID P2、または Microsoft Entra Suite がない場合は、「 Azure Data Explorer を使用してカスタム レポートを作成する」セクションに進んでください。

次の手順では、Microsoft Entra ID ガバナンス データを抽出するために、 Microsoft Graph PowerShell モジュールのインストール が必要になる場合があります。 組織でこのシナリオにこれらのモジュールを初めて使用するときは、Microsoft Graph PowerShell がテナントで使用するための同意を付与できるように、グローバル管理者ロールが必要です。 後続のインタラクションでは、低権限のロールを使用できます。

  1. PowerShell を開きます。

  2. インストールされていない Microsoft Graph PowerShell モジュールがある場合は、必要な Microsoft Graph モジュールをインストールします。 チュートリアルのこのセクションでは、次のモジュールが必要です: Microsoft.Graph.Identity.Governance。 モジュールが既にインストールされている場合は、次の手順に進みます。

       $modules = @('Microsoft.Graph.Identity.Governance')
       foreach ($module in $modules) {
       Install-Module -Name $module -Scope CurrentUser -AllowClobber -Force
       }
    
  3. モジュールを現在の PowerShell セッションにインポートします。

      $modules = @('Microsoft.Graph.Identity.Governance')
      foreach ($module in $modules) {
      Import-Module -Name $module
      } 
    
  4. Microsoft Graph に接続します。 このセクションでは、エンタイトルメント管理とアクセス レビューからデータを取得する方法について説明します。そのため、 AccessReview.Read.AllEntitlementManagement.Read.All アクセス許可スコープが必要です。 Privileged Identity Management (PIM) やライフサイクル ワークフローなど、他のレポートユース ケースの場合は、必要なアクセス許可で Scopes パラメーターを更新します。 アクセス許可の詳細については、Microsoft Graph のアクセス許可リファレンスをご覧ください。

      Connect-MgGraph -Scopes "AccessReview.Read.All, EntitlementManagement.Read.All" -ContextScope Process -NoWelcome
    

    このコマンドを実行すると、Microsoft Entra の資格情報でサインインするよう求められます。 サインイン後、初めて接続する場合、または新しいアクセス許可が必要な場合は、必要なアクセス許可に同意する必要があります。

カスタム レポートの Microsoft Entra ID ガバナンス データを抽出するための PowerShell クエリ

次のクエリでは、PowerShell を使用して Microsoft Graph から Microsoft Entra ID ガバナンス データを抽出し、そのデータを JSON ファイルにエクスポートします。 これらのファイルは、 このチュートリアルの後のセクションで Azure Data Explorer にインポートします。

この種類のデータを使用してレポートを生成するシナリオは次のとおりです。

  • アクセス履歴レビューに関するレポート。
  • 権限管理による割り当てに関する報告。

アクセスレビューのスケジュール定義データを取得する

アクセス レビュー定義名と ID を含む JSON ファイルを生成します。これは、Azure Data Explorer でカスタム ビューを作成する際に使用します。 このサンプルにはすべてのアクセス レビューが含まれていますが、必要に応じて追加のフィルター処理を含めることができます。 詳細については、「 フィルター クエリ パラメーターの使用」を参照してください。

   $allsched = Get-MgIdentityGovernanceAccessReviewDefinition -All
   $definitions = @()
   # Iterate over each definition
   foreach ($definition in $allsched) {
      $definitions += [PSCustomObject]@{
         Id = $definition.Id
         DisplayName = $definition.DisplayName
         SnapshotDate = $SnapshotDate
      }
   }
   $definitions | ConvertTo-Json -Depth 10 | Set-Content "EntraAccessReviewDefinitions.json"

アクセス レビューのインスタンス データを取得する

PowerShell を使用して、すべてのアクセス レビュー定義、インスタンス、および決定を構造化フォルダー形式にエクスポートするには、Microsoft Graph API を使用できます。 この方法により、データが階層的に編成され、指定されたフォルダー構造に合わせて調整されます。

開始する前に、次の点に注意してください。

  • Microsoft Graph のレビュー データにアクセスするために必要なアクセス許可があることを確認します。
  • データの量によっては、スクリプトの実行時間が異なる場合があります。 プロセスを監視し、必要に応じてパラメーターを調整します。

インスタンス データを取得するには:

  1. Export_Access_Reviews.ps1 スクリプトをダウンロードし、ローカルに保存します。

  2. エクスプローラーでスクリプトのブロックを解除して、PowerShell で実行できるようにします。

  3. 次のコマンドを実行します。 出力では、すべてのデータが 3 つのサブフォルダー ( ReviewInstancesReviewInstanceDecisionItemsReviewInstanceContactedReviewers) に配置されます。

     .\ExportAccessReviews.ps1 -InstanceStartDate "11/15/2024" -InstanceEndDate "12/15/2024" -ExportFolder "C:\AccessReviewsExport\11_15_to_12_15" 
    

エンタイトルメント管理用のアクセス パッケージ データを取得する

Azure Data Explorer でカスタム ビューを作成するために使用する、アクセス パッケージ名と ID を含む JSON ファイルを生成します。 このサンプルにはすべてのアクセス パッケージが含まれていますが、必要に応じて追加のフィルター処理を含めることができます。

   $accesspackages1 = Get-MgEntitlementManagementAccessPackage -All
   $accesspackages2 = @()
   # Iterate over each access package
   foreach ($accesspackage in $accesspackages1) {
      $accesspackages2 += [PSCustomObject]@{
         Id = $accesspackage.Id
         DisplayName = $accesspackage.DisplayName
         SnapshotDate = $SnapshotDate
      }
   }
   $accesspackages2 | ConvertTo-Json -Depth 10 | Set-Content "EntraAccessPackages.json"

エンタイトルメント管理用のアクセス パッケージの割り当てデータを取得する

Azure Data Explorer でカスタム ビューを作成するために使用する、パッケージへのアクセス権を含む JSON ファイルを生成します。 このサンプルには、配信されるすべての割り当てが含まれていますが、必要に応じて追加のフィルター処理を含めることができます。

   $apassignments1 = Get-MgEntitlementManagementAssignment -ExpandProperty target,accessPackage -filter "state eq 'Delivered'" -all
   $apassignments2 = @()
   # Iterate over each access package assignment
   foreach ($assignment in $apassignments1) {
      $apassignments2 += [PSCustomObject]@{
         Id = $assignment.Id
         ScheduleStartDateTime = $assignment.Schedule.StartDateTime -replace "\\/Date\((\d+)\)\\/", '$1' 
         AccessPackageId = $assignment.AccessPackage.Id
         AccessPackageDisplayName = $assignment.AccessPackage.DisplayName
         TargetId = $assignment.Target.Id
         TargetDisplayName = $assignment.Target.DisplayName
         TargetEmail = $assignment.Target.Email
         TargetObjectId = $assignment.Target.ObjectId
         TargetPrincipalName = $assignment.Target.PrincipalName
         TargetSubjectType = $assignment.Target.SubjectType
         SnapshotDate = $SnapshotDate
      }
   }
   $apassignments2 | ConvertTo-Json -Depth 10 | Set-Content "EntraAccessPackageAssignments.json"

Microsoft Entra ID Governance から Azure Data Explorer にテーブルを作成し、データを含む JSON ファイルをインポートする

このセクションでは、Microsoft Entra ID ガバナンス サービス用に新しく作成された JSON ファイルを Azure Data Explorer にインポートして、さらに分析します。 これらのファイルは、Microsoft Entra ID サービス用に既にインポートしたデータを結合します。 Azure Data Explorer Web UI を使用した最初のインポートでは、Web UI が各 JSON ファイルから提案するスキーマに基づいてテーブルを作成します。

  1. Azure Data Explorer の Web UI にサインインします。

  2. Azure Data Explorer クラスターまたは無料クラスターで、Microsoft Entra ID データを保持しているデータベースに移動します。

  3. 左側のメニューで、[クエリ] を選択 します

  4. エクスポートされた各 JSON ファイルに対して次の手順に従って、エクスポートしたデータを新しいテーブルとしてその Azure Data Explorer データベースに取得します。

    1. データを取り込むデータベースのデータベース名を右クリックします。 次に、[ データの取得] を選択します。

      データベースのショートカット メニューとデータを取得するためのコマンドが強調表示されているクエリ タブのスクリーンショット。

    2. 使用可能なリストからデータ ソースを選択します。 このチュートリアルでは、ローカル ファイルからデータを取り込んでいるので、[ ローカル ファイル] を選択します。

    3. [ + 新しいテーブル ] を選択し、インポートする JSON ファイルの名前に基づいてテーブル名を入力します。 最初のインポート後、テーブルは既に存在しているので、その後のインポートのターゲット テーブルとして選択できます。

    4. [ ファイルの参照] を選択し、JSON ファイルを選択して、[ 次へ] を選択します。

    5. Azure Data Explorer によってスキーマが自動的に検出され、[ 検査 ] タブにプレビューが表示されます。[ 完了] を 選択してテーブルを作成し、そのファイルからデータをインポートします。 データが取り込まれたら、[ 閉じる] を選択します。

    6. 各フォルダーについて、前のセクションで生成した JSON ファイルごとに、上記の手順を繰り返します。

    7. フォルダーに多数のファイルがある場合は、 lightingest を使用して、テーブルの作成後に残りのファイルをインポートできます。

これらの手順の最後には、前に作成したテーブルに加えて、データベースにテーブル EntraAccessReviewDefinitionsEntraAccessPackagesEntraAccessPackageAssignmentsReviewInstancesReviewInstanceDecisionItems、および ReviewInstanceContactedReviewers があります。

Azure Data Explorer を使用してカスタム レポートを作成する

Azure Data Explorer でデータを使用できるようになったので、ビジネス要件に基づいてカスタマイズされたレポートの作成を開始する準備が整いました。

  1. Azure Data Explorer の Web UI にサインインします。

  2. 左側のメニューで、[クエリ] を選択 します

次のクエリでは、一般的なレポートの例を示しますが、ニーズに合わせてこれらのレポートをカスタマイズし、追加のレポートを作成できます。

[エクスポート] タブを選択し、[Excel で開く] を選択することで、Excel でレポートを表示することもできます。

例: 特定のスナップショット日付のために、直接割り当てとグループ割り当てに対するアプリのロールを生成する

このレポートでは、ターゲット アプリへのアクセス権を持つユーザーと、いつアクセスしたかが表示されます。 これは、セキュリティ監査、コンプライアンス検証、組織内のアクセス パターンの理解に使用できます。

次のクエリは、Microsoft Entra ID 内の特定のアプリケーションを対象とし、特定の日付の時点でのロールの割り当てを分析します。 このクエリでは、直接およびグループベースのロールの割り当ての両方が取得されます。 このデータは、 EntraUsers テーブルのユーザーの詳細と、 AppRoles テーブルのロール情報とマージされます。 クエリで、 targetSnapshotDate データの読み込み時に使用した snapshotDate 値に設定します。

/// Define constants 
let targetServicePrincipalId = "<your service principal-id>"; // Target service principal ID 
let targetSnapshotDate = datetime("2024-01-13"); // Target snapshot date for the data 

// Extract role assignments for the target service principal and snapshot date 
let roleAssignments = AppRoleAssignments 
    | where ResourceId == targetServicePrincipalId and startofday(SnapshotDate) == targetSnapshotDate 
    | extend AppRoleIdStr = tostring(AppRoleId); // Convert AppRoleId to a string for easier comparison 

// Prepare user data from the EntraUsers table 
let users = EntraUsers 
    | project ObjectID, UserPrincipalName, DisplayName, ObjectIDStr = tostring(ObjectID); // Include ObjectID as string for joining 

// Prepare role data from the AppRoles table 
let roles = AppRoles 
    | mvexpand AppRoles // Expand AppRoles to handle multiple roles 
    | extend RoleName = AppRoles.DisplayName, RoleId = tostring(AppRoles.Id) // Extract role name and ID 
    | project RoleId, RoleName; 
// Process direct assignments 
let directAssignments = roleAssignments 
    | join kind=inner users on $left.PrincipalId == $right.ObjectID // Join with EntraUsers on PrincipalId 
    | join kind=inner roles on $left.AppRoleIdStr == $right.RoleId // Join with roles to get role names 
    | project UserPrincipalName, DisplayName, CreatedDateTime, RoleName, AssignmentType = "Direct", SnapshotDate; 

// Process group-based assignments 

let groupAssignments = roleAssignments 
    | join kind=inner EntraGroupMemberships on $left.PrincipalId == $right.GroupId // Join with group membership 
    | mvexpand Members // Expand group members 
    | extend MembersStr = tostring(Members) // Convert the member ID to a string 
    | distinct MembersStr, CreatedDateTime, AppRoleIdStr, SnapshotDate // Get distinct values 
    | join kind=inner users on $left.MembersStr == $right.ObjectIDStr // Join with EntraUsers for user details 
    | join kind=inner roles on $left.AppRoleIdStr == $right.RoleId // Join with roles for role names 
    | project UserPrincipalName, DisplayName, CreatedDateTime, RoleName, AssignmentType = "Group", SnapshotDate; 

// Combine results from direct and group-based assignments 
directAssignments 
| union groupAssignments 

例: 2 つの日付の間にアプリにアクセスしたユーザーを示す Microsoft Entra データを使用して、基本的な監査担当者レポートを作成する

このレポートには、2 つの日付の間にターゲット アプリにアクセスしたユーザーが表示されます。 これは、セキュリティ監査、コンプライアンス検証、組織内のアクセス パターンの理解に使用できます。

次のクエリは、Microsoft Entra ID 内の特定のアプリケーションを対象とし、2 つの日付の間のロールの割り当てを分析します。 このクエリは、AppRoleAssignments テーブルから直接ロール割り当てを取得し、このデータを EntraUsers テーブルのユーザー詳細と AppRoles テーブルの役割情報とマージします。

// Set the date range and service principal ID for the query 
let startDate = datetime('2024-01-01'); 
let endDate = datetime('2024-03-14'); 
let servicePrincipalId = "<your service principal-id>"; 

// Query AppRoleAssignments for the specified service principal within the date range 
AppRoleAssignments 
| where ResourceId == servicePrincipalId and 
    todatetime(CreatedDateTime) between (startDate .. endDate) 

// Extend AppRoleId to a string for joining 
| extend AppRoleIdStr = tostring(AppRoleId) 

// Project the necessary fields for the join with EntraUsers and AppRoles 
| project PrincipalId, AppRoleIdStr, CreatedDateTime 

// Join with EntraUsers to get user details 
| join kind=inner (EntraUsers | project UserPrincipalName, DisplayName, ObjectID) on $left.PrincipalId == $right.ObjectID 

// Join with AppRoles to get the role display names 
| join kind=inner ( 
  AppRoles | mvexpand AppRoles | project RoleIdStr = tostring(AppRoles.Id), RoleDisplayName = tostring(AppRoles.DisplayName) 
) on $left.AppRoleIdStr == $right.RoleIdStr 

// Final projection of the report with the current date and time 
| project UserPrincipalName, DisplayName, RoleDisplayName, CreatedDateTime, ReportDate = now() 

例: 2 つのデータ スナップショットの日付の間にアプリに追加されたユーザーを表示する

これらのレポートには、2 つの日付の間にターゲット アプリケーションへのアプリ ロールの割り当てを受け取ったユーザーのビューが表示されます。 これらのレポートを使用して、時間の経過に伴うアプリ アクセスの変更を追跡できます。

このクエリは、Microsoft Entra ID 内の特定のアプリケーションを対象とし、開始日と終了日の間のロールの割り当ての変更を対象とします。

// Define the date range and service principal ID for the query 

let startDate = datetime("2024-03-01"); 
let endDate = datetime("2024-03-14"); 
let servicePrincipalId = "<your service principal-id>"; 
let earlierDate = startDate; // Update this to your specific earlier date 

AppRoleAssignments 
| where SnapshotDate < endDate and ResourceId == servicePrincipalId
| project PrincipalId, AppRoleId2 = tostring(AppRoleId), CreatedDateTime 
| join kind=anti ( 
    AppRoleAssignments 
    | where SnapshotDate < earlierDate and ResourceId == servicePrincipalId 
    | project PrincipalId, AppRoleId1 = tostring(AppRoleId) 
) on PrincipalId 
| join kind=inner (EntraUsers) on $left.PrincipalId == $right.ObjectID 
| join kind=inner (AppRoles 
                   | mvexpand AppRoles 
                   | project AppRoleId=tostring(AppRoles.Id), RoleDisplayName=tostring(AppRoles.DisplayName) 
                  ) on $left.AppRoleId2 == $right.AppRoleId 
| project UserPrincipalName, DisplayName, RoleDisplayName, CreatedDateTime, PrincipalId, Change = "Added" 

例: アクセス レビューを使用するさまざまなクエリ

アクセス レビューの完了とタイムライン情報を表示する

データがアップロードされたら、次の Kusto クエリを使用して確認します。

  • 最後のアクセス レビュー サイクルが完了したのはいつですか? 所要時間はどのくらいでしたか?

    ReviewInstances
    | summarize LastCompletedDate = max(ReviewInstanceEndDateTime),  
                ReviewDuration = datetime_diff('minute', max(ReviewInstanceEndDateTime), min(ReviewInstanceStartDateTime))  
    
  • アクセスレビューのプロセスは、定期的に(例えば、四半期ごとに)実施されていますか?

    ReviewInstances 
    | extend ExpectedFrequency = "Quarterly" // Replace with the organization's frequency
    | summarize ReviewsCompleted = count(), LastReviewEndDate = max(ReviewInstanceEndDateTime)
    | extend CurrentDate = now(),  
             TimeSinceLastReview = datetime_diff('day', now(), LastReviewEndDate)
    | extend IsOnSchedule = iff(TimeSinceLastReview <= 90, "Yes", "No") // Assuming quarterly = 90 days
    

アクセスレビューへの参加および関与を確認する

  • 割り当てられた校閲者は誰ですか?

    ReviewInstanceContactedReviewers
    | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerName = DisplayName, ReviewerUserPrincipalName = UserPrincipalName, CreatedDateTime
    
  • どの校閲者が積極的に参加し、回答を提供しましたか?

    ReviewInstanceDecisionItems
    | where ReviewedBy_DisplayName != "AAD Access Reviews"
    | where Decision in ("Approve", "Deny")
    | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerName = ReviewedBy_DisplayName,
    ReviewerUserPrincipalName = ReviewedBy_UserPrincipalName, Decision, ReviewedDateTime
    | distinct AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerName, ReviewerUserPrincipalName, Decision
    
  • アクセス レビュー要求に応答したレビュー担当者の割合は何パーセントですか?

    let TotalReviewers = ReviewInstanceContactedReviewers 
        | summarize Total = dcount(Id) by AccessReviewDefinitionId, AccessReviewInstanceId;  
    
    let RespondedReviewers = ReviewInstanceDecisionItems 
        | where ReviewedBy_DisplayName != "AAD Access Reviews"
        | where ReviewedBy_Id != "00000000-0000-0000-0000-000000000000"
        | where Decision in ("Approve", "Deny")
        | summarize Responded = dcount(ReviewedBy_Id) by AccessReviewDefinitionId, AccessReviewInstanceId;  
    
    TotalReviewers
    | join kind=leftouter RespondedReviewers on AccessReviewDefinitionId, AccessReviewInstanceId
    | extend Responded = coalesce(Responded, 0)  // Replace null with 0 for Responded
    | extend NotResponded = Total - Responded   // Calculate the number of nonresponders
    | extend ResponsePercentage = (Responded * 100.0) / Total  // Percentage of those who responded
    | extend NonResponsePercentage = (NotResponded * 100.0) / Total  // Percentage of those who didn't respond
    | project AccessReviewDefinitionId, AccessReviewInstanceId, Total, Responded, ResponsePercentage, NotResponded, NonResponsePercentage  
    
  • 各校閲者がタスクを完了したのはいつですか?

    ReviewInstanceDecisionItems 
    | where Decision in ("Approve", "Deny") 
    | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerName = ReviewedBy_DisplayName, ReviewerUserPrincipalName = ReviewedBy_UserPrincipalName, ReviewedDateTime  
    
  • どの校閲者が決定を下さなかったのですか?

    let AllReviewers = ReviewInstanceContactedReviewers 
        | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerId = Id, ReviewerUserPrincipalName = UserPrincipalName, ReviewerName = DisplayName;
    
    let ActiveReviewers = ReviewInstanceDecisionItems
        | where Decision in ("Approve", "Deny")
        | where ReviewedBy_DisplayName != "AAD Access Reviews"
        | where ReviewedBy_Id != "00000000-0000-0000-0000-000000000000"
        | summarize ActiveReviewers = make_set(ReviewedBy_Id) by AccessReviewDefinitionId, AccessReviewInstanceId;
    
    AllReviewers
    | extend ReviewerId = tostring(ReviewerId)  // Ensure ReviewerId is a string
    | join kind=leftanti (
        ActiveReviewers
        | mv-expand ActiveReviewers
        | extend ActiveReviewers = tostring(ActiveReviewers)  // Cast ActiveReviewers to a string
    ) on $left.ReviewerId == $right.ActiveReviewers
    | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerUserPrincipalName, ReviewerName
    
  • レビュー担当者が対話しなかった割合は何% ですか?

    let TotalReviewers = ReviewInstanceContactedReviewers 
        | summarize Total = dcount(Id) by AccessReviewDefinitionId, AccessReviewInstanceId;
    
    let RespondedReviewers = ReviewInstanceDecisionItems
        | where ReviewedBy_DisplayName != "AAD Access Reviews"
        | where ReviewedBy_Id != "00000000-0000-0000-0000-000000000000"
        | where Decision in ("Approve", "Deny")
        | summarize Responded = dcount(ReviewedBy_Id) by AccessReviewDefinitionId, AccessReviewInstanceId;
    
    TotalReviewers
    | join kind=leftouter RespondedReviewers on AccessReviewDefinitionId, AccessReviewInstanceId
    | extend Responded = coalesce(Responded, 0)  // Replace null with 0 for Responded
    | extend NotResponded = Total - Responded   // Calculate the number of nonresponders
    | extend ResponsePercentage = (Responded * 100.0) / Total  // Percentage of those who responded
    | extend NonResponsePercentage = (NotResponded * 100.0) / Total  // Percentage of those who didn't respond
    | project AccessReviewDefinitionId, AccessReviewInstanceId, Total, Responded, ResponsePercentage, NotResponded, NonResponsePercentage  
    
  • 無責任なレビュー担当者または保留中の決定に対してリマインダーがトリガーされましたか?

    // Step 1: Get the list of all reviewers
    let TotalReviewers = ReviewInstanceContactedReviewers 
        | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerId = Id, ReviewerUserPrincipalName = UserPrincipalName, ReviewerName = DisplayName;
    
    // Step 2: Get the list of reviewers who responded 
    let RespondedReviewers = ReviewInstanceDecisionItems
        | where ReviewedBy_DisplayName != "AAD Access Reviews"
        | where ReviewedBy_Id != "00000000-0000-0000-0000-000000000000"
        | where Decision in ("Approve", "Deny")
        | project AccessReviewDefinitionId, AccessReviewInstanceId, RespondedReviewerId = ReviewedBy_Id;
    
    // Step 3: Get the list of review instances
    let ReviewInstancesWithDetails = ReviewInstances
        | project AccessReviewDefinitionId = ReviewDefinitionId,  
                  AccessReviewInstanceId = ReviewInstanceId,  
                  RemindersSent = ReviewDefinitionSettings_ReminderNotificationsEnabled,  
                  StartDate = todatetime(ReviewInstanceStartDateTime),  
                  EndDate = todatetime(ReviewInstanceEndDateTime)
        | extend
                  ReminderSentDate = iif(RemindersSent, StartDate + (EndDate - StartDate) / 2, datetime(null));
    
    // Step 4: Identify nonresponsive reviewers and join with review instance details
    TotalReviewers
    | join kind=leftouter (ReviewInstancesWithDetails) on AccessReviewDefinitionId, AccessReviewInstanceId
    | join kind=leftanti RespondedReviewers on $left.ReviewerId == $right.RespondedReviewerId
    | project AccessReviewDefinitionId, AccessReviewInstanceId, ReviewerUserPrincipalName, ReviewerName, RemindersSent, ReminderSentDate
    

アクセス レビューに起因するユーザーとアクセスの変更を表示する

  • アクセス レビュー中に特定のリソースへのアクセスを失ったユーザー

    ReviewInstanceDecisionItems 
    | where Decision == "Deny" 
    | project User = Principal_DisplayName, Resource = Resource_DisplayName, Decision, Justification 
    
  • ユーザーに非アクティブが原因でフラグが設定されましたか?

    ReviewInstanceDecisionItems
    | where Insights contains "inactive"
    | project User = Principal_DisplayName, Resource = Resource_DisplayName, Insights, Decision
    
  • アクセスの削除日とアクセスを失う理由は何でしたか?

    ReviewInstanceDecisionItems
    | where Decision == "Deny"
    | project User = Principal_DisplayName, Resource=Resource_DisplayName, AccessRemovalDate = AppliedDateTime, Reason = Justification  
    
  • どのユーザーが何も決定しなかったか。

    ReviewInstanceDecisionItems
    | where Decision == "NotReviewed"
    | project User = Principal_DisplayName, Resource=Resource_DisplayName
    
  • レビュー担当者がいなかったレビューはどれですか?

    ReviewInstances
    | join kind=leftanti (
        ReviewInstanceContactedReviewers
        | summarize by AccessReviewInstanceId
    ) on $left.ReviewInstanceId == $right.AccessReviewInstanceId  
    
  • ユーザーがいなかったレビューはどれですか?

    ReviewInstances 
    | join kind=leftanti (
        ReviewInstanceDecisionItems
        | summarize by AccessReviewInstanceId
    ) on $left.ReviewInstanceId == $right.AccessReviewInstanceId
    

アクセス レビューの決定を要約する

  • ユーザーが行った決定 (承認、拒否、変更なし)

    ReviewInstanceDecisionItems
    | summarize count() by Decision
    
  • アクセスが承認または拒否されたユーザーの数は何ですか?

    ReviewInstanceDecisionItems
    | summarize ApprovedCount = countif(Decision == "Approve"), DeniedCount = countif(Decision == "Deny")
    
  • 承認の理由は文書化されましたか?

    ReviewInstanceDecisionItems
    | where Decision == "Approve" and isnotempty(Justification)
    | summarize count() by ReviewedBy_DisplayName
    

アクセスレビューの品質を確認し、完全性を検査する

  • 休止中のユーザーのアクセス失効は考慮されましたか?

    ReviewInstanceDecisionItems
    | where Insights contains "inactive" and Decision == "Deny"
    | project User = Principal_DisplayName, Decision
    
  • アクセス権が正しく削除されませんでしたか?

    ReviewInstanceDecisionItems
    | where ApplyResult != "New" and ApplyResult != "AppliedSuccessfully"
    
  • 校閲者は自分の決定を文書化しましたか?

    ReviewInstanceDecisionItems
    | where isnotempty(Justification)
    | summarize count() by ReviewedBy_DisplayName
    
  • 各ユーザーのコメントはキャプチャされましたか?

    ReviewInstanceDecisionItems
    | where isnotempty(Justification)
    | project User = Principal_DisplayName, Resource = Resource_DisplayName, Comments = Justification
    

進行中のインポートを設定する

このチュートリアルでは、レポート用に Azure Data Explorer に単一のスナップショットを追加する、1 回限りのデータ抽出、変換、読み込み (ETL) プロセスを説明します。 継続的なレポート作成や、時間の経過に伴う変更の比較を行う場合は、Microsoft Entra から Azure Data Explorer にデータを追加するプロセスを自動化し、データベースに常に最新のデータが保持されるようにすることができます。

Azure クラウド サービスである Azure Automation を使用して、Microsoft Entra ID と Microsoft Entra ID ガバナンスからデータを抽出するために必要な PowerShell スクリプトをホストできます。 詳細については、「 Azure Automation と Microsoft Graph を使用して Microsoft Entra ID ガバナンス タスクを自動化する」を参照してください。

また、Azure の機能や lightingest などのコマンドライン ツールを使用して、データを取り込み、既存のテーブルを設定することもできます。 詳細については、「 LightIngest を使用して Azure Data Explorer にデータを取り込む」を参照してください。

たとえば、現在ログインしているユーザーとして現在のディレクトリの EntraAccessPackages.json ファイルを EntraAccessPackages テーブルに読み込むには、次のコマンドを使用します。

az login
LightIngest.exe "https://ingest-CLUSTERHOSTNAME;Fed=True" -database:"DATABASE" -table:EntraAccessPackages -sourcepath:"." -pattern:"EntraAccessPackages.json" -format:multijson -azcli:true

より多くのソースからのデータに関するレポート

Microsoft Entra 以外のソースから Azure Data Explorer にデータを取り込むこともできます。 この機能のシナリオは次のとおりです。

  • 管理者は、監査レコード自体の一部ではないユーザー、アクセス パッケージ、またはその他のオブジェクトに関する詳細を含むイベントを監査ログに表示したいと考えています。
  • 管理者は、Microsoft Entra ID からアプリケーションに追加されたすべてのユーザーと、アプリケーションの独自のリポジトリ (SQL データベースなど) でのアクセス権を表示したいと考えています。

詳細については、「他の ソースからのデータを使用して Azure Data Explorer でカスタマイズされたレポートを作成する」を参照してください。