Поделиться через


Руководство: Настроенные отчеты в Azure Data Explorer с использованием данных из Microsoft Entra

В этом руководстве вы узнаете, как создавать настраиваемые отчеты в Azure Data Explorer (ADX) с помощью данных из службы управления идентификаторами Microsoft Entra и Microsoft Entra ID Management. В этом руководстве дополняются другие варианты создания отчетов, такие как архивный отчет & с помощью Azure Monitor и управления правами, который фокусируется на экспорте журнала аудита в Azure Monitor для хранения и анализа. По сравнению с экспортом данных идентификатора Microsoft Entra в Azure Data Explorer предоставляется гибкость для создания пользовательских отчетов для объектов Microsoft Entra, включая исторические и удаленные объекты. Кроме того, использование Azure Data Explorer позволяет агрегирование данных из дополнительных источников с массовой масштабируемостью, гибкой схемой и политиками хранения. Azure Data Explorer особенно полезно, если необходимо хранить данные доступа в течение многих лет, выполнять нерегламентированные исследования или выполнять пользовательские запросы к данным доступа пользователей.

В этой статье показано, как показать конфигурацию, пользователей и права доступа, экспортированные из Microsoft Entra вместе с данными, экспортируемыми из других источников, например приложениями с правами доступа в собственных базах данных SQL. Затем вы можете использовать язык запросов Kusto (KQL) в Azure Data Explorer для создания пользовательских отчетов на основе требований вашей организации.

Чтобы создать эти отчеты, выполните следующие действия.

  1. настройте Azure Data Explorer для подписки Azure или создайте бесплатный кластер.
  2. Извлечь данные из идентификатора Microsoft Entra с помощью сценариев PowerShell и Microsoft Graph.
  3. Создайте таблицы и импортируйте эти данные из Microsoft Entra ID вAzure Data Explorer.
  4. Извлечь данные из Microsoft Entra ID Governance.
  5. Создавать таблицы и импортировать эти данные из Microsoft Entra ID Governance в Azure Data Explorer.
  6. Создание пользовательского запроса с помощью язык запросов Kusto.

В конце этого руководства вы сможете разрабатывать настраиваемые представления прав доступа и разрешений пользователей. Эти представления охватывают различные приложения с помощью поддерживаемых корпорацией Майкрософт средств. Вы также можете передавать данные из сторонних баз данных или приложений, чтобы сообщить о них.

Необходимые компоненты

Если вы впервые знакомитесь с Azure Data Explorer и хотите освоить сценарии, приведенные в этой статье, вы можете получить бесплатный кластер Azure Data Explorer. Для использования в рабочей среде с соглашением об уровне обслуживания для Azure Data Explorer требуется подписка Azure для размещения полного кластера Azure Data Explorer.

Определите, какие данные необходимо включить в отчеты. Скрипты в этой статье содержат примеры с определенными данными пользователей, групп и приложений из Microsoft Entra. Эти примеры предназначены для иллюстрации типов отчетов, которые можно создать с помощью этого подхода, но конкретные потребности отчетов могут отличаться и требовать разные или дополнительные данные. Вы можете начать с этих объектов и с течением времени использовать другие виды объектов Microsoft Entra.

  • В этой статье показано получение данных из Microsoft Entra в качестве пользователя, вошедшего в систему. Для этого убедитесь, что у вас есть необходимые назначения ролей для получения данных из Microsoft Entra. Вам нужны роли с правильными разрешениями для экспорта типов данных Microsoft Entra, с которыми вы хотите работать.
    • Пользовательские данные: глобальный администратор, администратор привилегированных ролей, администратор пользователей
    • Группы данных: глобальный администратор, администратор привилегированных ролей, администратор группы
    • Назначения ролей приложений и приложений: глобальный администратор, администратор привилегированных ролей, администратор приложений, администратор облачных приложений
  • Для Microsoft Graph PowerShell необходимо предоставить согласие на получение объектов Microsoft Entra через Microsoft Graph. В примерах этого руководства требуются делегированные разрешения User.Read.All, Group.Read.All, Application.Read.All и Directory.Read.All. Если вы планируете получать данные с помощью автоматизации без вошедшего пользователя, то вместо этого укажите соответствующие разрешения приложения. Дополнительные сведения см . в справочнике по разрешениям Microsoft Graph. Если вы еще не дали согласие на эти разрешения для Microsoft Graph PowerShell, необходимо быть Глобальным администратором, чтобы выполнить эту операцию.
  • В этом руководстве не показаны настраиваемые атрибуты безопасности. По умолчанию глобальный администратор и другие роли администратора не включают разрешения на чтение настраиваемых атрибутов безопасности от пользователей Microsoft Entra. Если вы планируете получить настраиваемые атрибуты безопасности, может потребоваться больше ролей и разрешений.
  • На компьютере, на котором установлен Microsoft Graph PowerShell, убедитесь, что у вас есть доступ на запись в каталог файловой системы. Здесь вы устанавливаете необходимые модули Microsoft Graph PowerShell и где сохраняются экспортированные данные Microsoft Entra.
  • Убедитесь, что у вас есть разрешения на получение данных из других источников данных за пределами Microsoft Entra, если вы хотите также включить эти данные в Azure Data Explorer.

1. Настройка Azure Data Explorer

Если вы ранее не использовали Azure Data Explorer, необходимо сначала настроить этот параметр. Вы можете создать бесплатный кластер без подписки Azure или кредитной карты или полного кластера, для которого требуется подписка Azure. См . краткое руководство. Создание кластера и базы данных Azure Data Explorer для начала работы.

2. Извлечение данных идентификатора Microsoft Entra с помощью PowerShell

В этом разделе установить модули Microsoft Graph PowerShell и в PowerShell подключиться к Microsoft Graph для извлечения данных идентификатора Microsoft Entra.

При первом использовании этих модулей в организации для этого сценария необходимо иметь роль глобального администратора, чтобы разрешить Microsoft Graph PowerShell предоставить согласие на использование в клиенте. Последующие взаимодействия могут использовать роль с более низким уровнем привилегий.

  1. Откройте PowerShell.
  2. Если у вас нет всех модулей Microsoft Graph PowerShell, уже установлены, установите необходимые модули Microsoft Graph. Для этого раздела учебника требуются следующие модули: Microsoft.Graph.Authentication, Microsoft.Graph.Users, Microsoft.Graph.Groups, Microsoft.Graph.Applications, Microsoft.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
   } 
  1. Импортируйте модули в текущий сеанс PowerShell.
  $modules = @('Microsoft.Graph.Users', 'Microsoft.Graph.Groups', 'Microsoft.Graph.Applications', 'Microsoft.Graph.DirectoryObjects') 
  foreach ($module in $modules) { 
  Import-Module -Name $module 
  } 
  1. Подключение к Microsoft Graph. В этом разделе руководства показано, как читать пользователей, группы и приложения, поэтому требуется разрешения User.Read.All, Group.Read.All, Application.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. После входа вам может потребоваться согласие на необходимые разрешения, если это ваш первый раз подключение, или если требуются новые разрешения.

Запросы PowerShell для извлечения данных идентификатора Microsoft Entra, необходимых для создания пользовательских отчетов в Azure Data Explorer

Следующие запросы извлекают данные идентификатора Microsoft Entra из Microsoft Graph с помощью PowerShell и экспортируют данные в JSON-файлы, импортируемые в Azure Data Explorer в следующем разделе 3. Существует несколько сценариев создания отчетов с данными этого типа, в том числе:

  • Аудитор хотел бы просмотреть отчет, который содержит список участников группы для 10 групп, организованных отделом участников.
  • Аудитор хотел бы просмотреть отчет всех пользователей, имеющих доступ к приложению между двумя датами.

Вы также можете перенести данные в Azure Data Explorer из других источников за пределами Microsoft Entra. Это позволяет выполнять такие сценарии, как:

  • Администратор хотел бы просмотреть всех пользователей, добавленных в приложение из идентификатора Microsoft Entra ID, и их права доступа в собственном репозитории приложения, например базы данных SQL.

Эти типы отчетов не встроены в идентификатор Microsoft Entra. Однако эти отчеты можно создавать самостоятельно, извлекая данные из Entra и объединяя их с помощью пользовательских запросов в Azure Data Explorer. Вопрос будет рассмотрен далее в руководстве в разделе переноса данных из других источников .

В этом руководстве мы извлекаем данные идентификатора Microsoft Entra из нескольких областей:

  • Сведения о пользователе, такие как отображаемое имя, имя участника-пользователя и сведения о задании
  • Сведения о группах, включая их членство
  • Назначения приложений и ролей приложений

Этот набор данных позволяет выполнять широкий набор запросов вокруг того, кто получил доступ к приложению, с информацией о роли приложения и связанным временем. Обратите внимание, что это примеры запросов, и данные и конкретные требования могут отличаться от того, что показано здесь.

Примечание.

Более крупные клиенты могут столкнуться с ошибками регулирования или 429, которые обрабатываются модулем Microsoft Graph. Azure Data Explorer также может ограничить размер отправки файлов.

В этих скриптах PowerShell мы экспортируем выбранные свойства из объектов Microsoft Entra в JSON-файлы. Данные из этих экспортированных свойств используются для создания пользовательских отчетов в Azure Data Explorer. Следующие свойства были включены в эти примеры, так как мы используем эти данные для иллюстрации типов отчетов, которые можно создать в Azure Data Explorer. Ваши конкретные потребности в отчетах, вероятно, отличаются от тех, что уже представлены, поэтому следует включить в эти скрипты те свойства, которые вас интересуют для просмотра в отчетах. Однако вы можете следовать тому же шаблону, чтобы помочь вам в создании скриптов.

Выберите дату моментального снимка

Мы включили жестко закодированную дату моментального снимка , которая определяет данные в JSON-файле с определенной датой и позволяет отслеживать аналогичные наборы данных с течением времени в Azure Data Explorer. Дата моментального снимка также полезна для сравнения изменений данных между двумя датами моментального снимка.

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

Получение данных пользователя Entra

Этот скрипт экспортирует выбранные свойства из объекта пользователя 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 

Получение данных группы

Создайте JSON-файл с именами групп и идентификаторами, которые используются для создания пользовательских представлений в Azure Data Explorer. Пример включает все группы, но при необходимости можно включить дополнительную фильтрацию. Если вы фильтруете только определенные группы, может потребоваться включить логику в скрипт, чтобы проверить наличие вложенных групп.

    # Get all groups and select Id and DisplayName 
    $groups = Get-MgGroup -All | Select-Object Id,DisplayName 
    # Export the groups to a JSON file 
    $groups | ConvertTo-Json | Set-Content ".\EntraGroups.json" 

Получение данных о членстве в группах

Создайте JSON-файл с членством в группах, который используется для создания пользовательских представлений в Azure Data Explorer. Пример включает все группы, но при необходимости можно включить дополнительную фильтрацию.

    # Retrieve all groups from Microsoft Entra (Azure AD) 
    $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 "EntraGroupMembership.json" 

Получение данных приложения и субъекта-службы

Создает JSON-файл со всеми приложениями и соответствующими субъектами-службами в клиенте. Мы импортируем эти данные в Azure Data Explorer в следующем разделе этого руководства, что позволяет создавать пользовательские отчеты, связанные с приложениями на основе этих данных.

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

Получение данных AppRole

Создайте JSON-файл всех ролей приложений для корпоративных приложений в Microsoft Entra. После импорта в Azure Data Explorer эти данные используются для создания отчетов о назначении ролей приложения для пользователей.

    # Get a list of all applications, 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 using its appId 
      $spFilter = "appId eq '$($app.AppId)'" 
      $sp = Get-MgServicePrincipal -Filter $spFilter | Select-Object -First 1 
      # Process AppRoles, 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' 

Получение данных о назначении appRole

Создайте 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 needed 
        $result += [PSCustomObject]@{ 
          AppRoleId      = $_.AppRoleId 
          CreatedDateTime   = $createdDateTime 
          PrincipalDisplayName = $_.PrincipalDisplayName 
          PrincipalId     = $_.PrincipalId 
          ResourceDisplayName = $_.ResourceDisplayName 
          ResourceId      = $_.ResourceId 
          SnapshotDate     = $SnapshotDate
        } 
      } 
    } 
    $result | ConvertTo-Json -Depth 10 | Out-File "AppRoleAssignments.json" 

3. Создание таблиц и импорт JSON-файлов с данными из идентификатора Microsoft Entra в Azure Data Explorer

В этом разделе мы импортируем только что созданные JSON-файлы для служб идентификатора Microsoft Entra в виде таблиц в Azure Data Explorer для дальнейшего анализа. При первом импорте с помощью веб-интерфейса Azure Data Explorer вы создадите таблицы на основе схемы, которую веб-интерфейс предлагает из каждого JSON-файла.

После настройки базы данных в кластере Azure Data Explorer или бесплатном кластере, как описано в первом разделе этой статьи, перейдите к этой базе данных.

  1. Войдите в веб-интерфейс Azure Data Explorer.
  2. В меню слева выберите "Запрос ".

Затем выполните следующие действия для каждого экспортированного JSON-файла, чтобы получить экспортированные данные в базу данных Azure Data Explorer в качестве новой таблицы.

  1. Щелкните правой кнопкой мыши имя базы данных, в которую нужно импортировать данные. Выберите Получить данные.

    снимок экрана вкладки запроса с правым щелчком на базе данных и с открытым диалоговым окном получения параметров.

  2. Выберите источник данных из доступного списка. В этом руководстве вы загружаете данные из локального файла.

  3. Выберите + Создать таблицу и введите имя таблицы на основе имени JSON-файла, который вы импортируете. Например, если вы импортируете EntraUsers.json, назовите таблицу EntraUsers. После первого импорта таблица уже существует, и ее можно выбрать в качестве целевой таблицы для последующего импорта.

  4. Выберите Обзор файлов, выберите JSON-файл и выберите Далее.

  5. Azure Data Explorer автоматически определяет схему и предоставляет предварительный просмотр на вкладке "Обзор". Выберите "Готово", чтобы создать таблицу и импортировать данные из этого файла. После приема данных нажмите кнопку Закрыть.

  6. Повторите каждый из предыдущих шагов для каждого из json-файлов, созданных в предыдущем разделе.

В конце этих шагов в базе данных будут таблицы EntraUsers, EntraGroups, EntraGroupMembership, Applications, AppRolesи AppRoleAssignments.

4. Извлечение данных управления идентификаторами Microsoft Entra с помощью PowerShell

В этом разделе описано, как извлечь данные из служб управления идентификаторами Microsoft Entra с помощью PowerShell. Если у вас нет Microsoft Entra ID Governance, Microsoft Entra ID P2 или Microsoft Entra Suite, то продолжайте с раздела , где используется Azure Data Explorer для создания пользовательских отчетов.

Для этого может потребоваться установить модули Microsoft Graph PowerShell для извлечения данных системы управления идентификаторами Microsoft Entra. При первом использовании этих модулей в организации для этого сценария необходимо иметь роль глобального администратора, чтобы разрешить 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
   }
  1. Импортируйте модули в текущий сеанс PowerShell.
  $modules = @('Microsoft.Graph.Identity.Governance')
  foreach ($module in $modules) {
  Import-Module -Name $module
  } 
  1. Подключение к Microsoft Graph. В этом разделе руководства показано получение данных из управления правами и обзоров доступа, поэтому требуются области разрешений AccessReview.Read.All и EntitlementManagement.Read.All. Для других вариантов использования отчетов, таких как для рабочих процессов PIM или жизненного цикла, обновите параметр Scopes с необходимыми разрешениями. Дополнительные сведения о разрешениях см. в справочнике по разрешениям Microsoft Graph.
  Connect-MgGraph -Scopes "AccessReview.Read.All, EntitlementManagement.Read.All" -ContextScope Process -NoWelcome

Эта команда запрашивает вход с помощью учетных данных Microsoft Entra. После входа вам может потребоваться согласие на необходимые разрешения, если это ваш первый раз подключение, или если требуются новые разрешения.

Запросы PowerShell для извлечения данных системы управления идентификаторами Microsoft Entra, необходимых для создания пользовательских отчетов в Azure Data Explorer

Запросы можно использовать для извлечения данных системы управления идентификаторами Microsoft Entra из Microsoft Graph с помощью PowerShell и экспорта данных в JSON-файлы, которые импортируются в Azure Data Explorer в следующем разделе. Существует несколько сценариев создания отчетов с данными этого типа, в том числе:

  • отчеты об исторических проверках доступа
  • составление отчетов о назначениях через систему управления правами

Получить данные определения расписания проверки доступа

Создайте 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, можно использовать API Microsoft Graph. Этот подход гарантирует, что ваши данные организованы иерархически в соответствии с указанной структурой папок.

Прежде чем начать, обратите внимание на следующее:

  • Убедитесь, что у вас есть необходимые разрешения для доступа к данным проверки доступа в Microsoft Graph.
  • В зависимости от объема данных время выполнения скрипта может отличаться. Отслеживайте процесс и настраивайте параметры по мере необходимости.
  1. Скачайте скрипт Export_Access_Reviews.ps1 и сохраните его локально.
  2. В проводнике разблокируйте скрипт, чтобы его можно было запустить в PowerShell.
  3. Выполните следующую команду, которая выведет все данные в три папки: ReviewInstances, ReviewInstanceDecisionItems и ReviewInstanceContactedReviewers.
 .\ExportAccessReviews.ps1 -InstanceStartDate "11/15/2024" -InstanceEndDate "12/15/2024" -ExportFolder "C:\AccessReviewsExport\11_15_to_12_15" 

Получение данных пакета доступа для управления правами

Создайте JSON-файл с именами пакетов доступа и идентификаторами, которые используются для создания пользовательских представлений в Azure Data Explorer. Пример включает все пакеты доступа, но при необходимости можно включить дополнительную фильтрацию.

   $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"

Получение данных назначения пакета доступа для управления правами

Создайте JSON-файл с назначениями для доступа к пакетам, которые используются для создания пользовательских представлений в Azure Data Explorer. В этом примере включены все задания, но при необходимости можно применить дополнительные фильтры.

   $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"

5. Создание таблиц и импорт JSON-файлов с данными из системы управления идентификаторами Microsoft Entra в Azure Data Explorer

В этом разделе мы импортируем только что созданные JSON-файлы для служб управления идентификаторами Microsoft Entra в Azure Data Explorer, а также данные, уже импортированные для служб идентификаторов Microsoft Entra, для дальнейшего анализа. При первом импорте с помощью веб-интерфейса Azure Data Explorer вы создадите таблицы на основе схемы, которую веб-интерфейс предлагает из каждого JSON-файла.

В вашем кластере Azure Data Explorer или бесплатном кластере перейдите к базе данных, в которой хранятся данные вашего идентификатора Microsoft Entra.

  1. Войдите в веб-интерфейс Azure Data Explorer.
  2. В меню слева выберите "Запрос ".

Затем выполните следующие действия для каждого экспортированного JSON-файла из предыдущего раздела, чтобы получить экспортированные данные в базу данных Azure Data Explorer в качестве новой таблицы.

  1. Щелкните правой кнопкой мыши имя базы данных, в которую нужно импортировать данные. Выберите Получить данные.

    снимок экрана вкладки запроса с правым щелчком на базе данных и с открытым диалоговым окном получения параметров.

  2. Выберите источник данных из доступного списка. В этом руководстве вы загружаете данные из локального файла.

  3. Выберите + Создать таблицу и введите имя таблицы в зависимости от имени импорта JSON-файла, после первого импорта таблица уже существует, и ее можно выбрать в качестве целевой таблицы для последующего импорта.

  4. Выберите Обзор файлов, выберите JSON-файл и выберите Далее.

  5. Azure Data Explorer автоматически определяет схему и предоставляет предварительный просмотр на вкладке "Обзор". Выберите "Готово", чтобы создать таблицу и импортировать данные из этого файла. После приема данных нажмите кнопку Закрыть.

  6. Повторите каждый из предыдущих шагов для каждого из файлов JSON, созданных в предыдущем разделе, для каждой папки.

  7. Если в папке много файлов, вы можете использовать lightingest для импорта остальных файлов после создания таблицы.

В конце этих действий в базе данных будут таблицы EntraAccessReviewDefinitions, EntraAccessPackagesи EntraAccessPackageAssignments, ReviewInstances, ReviewInstanceDecisionItems, ReviewInstanceContactedReviewers в базе данных, а также таблицы, созданные в разделе 3.

6. Использование Azure Data Explorer для создания пользовательских отчетов

Теперь, когда данные доступны в Azure Data Explorer, вы готовы приступить к созданию настраиваемых отчетов на основе ваших бизнес-требований.

Azure Data Explorer — это мощный инструмент анализа данных, который является высокомасштабируемым и гибким, предоставляющим идеальную среду для создания настраиваемых отчетов о доступе пользователей. Azure Data Explorer использует язык запросов Kusto (KQL).

  1. Войдите в веб-интерфейс Azure Data Explorer.
  2. В меню слева выберите "Запрос ".

В следующих запросах приведены примеры общих отчетов, но эти отчеты можно настроить в соответствии с потребностями и создать дополнительные отчеты.

Вы также можете просматривать отчеты в Excel, выбрав вкладку Экспорт и выбрав Открыть в Excel.

Пример 1. Создание назначений ролей приложения для прямых и групповых назначений для определенной даты моментального снимка

Этот отчет предоставляет представление о том, кто имел доступ и когда к целевому приложению и может использоваться для аудита безопасности, проверки соответствия требованиям и понимания шаблонов доступа в организации.

Этот запрос предназначен для конкретного приложения в Microsoft Entra AD и анализирует назначения ролей по определенной дате. Запрос извлекает как прямые, так и групповые назначения ролей, объединяя эти данные с данными пользователя из таблицы 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 string for easier comparison 

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

// Prepare role data from 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 EntraGroupMembership on $left.PrincipalId == $right.GroupId // Join with Group Membership 
    | mvexpand Members // Expand group members 
    | extend MembersStr = tostring(Members) // Convert member ID to 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. Создание базового отчета аудитора с данными Entra, показывающими, кто имел доступ к приложению между этими двумя датами.

В этом отчете представлено представление о том, кто имел доступ к целевому приложению между двумя датами и может использоваться для аудита безопасности, проверки соответствия требованиям и понимания шаблонов доступа в организации.

Этот запрос предназначен для конкретного приложения в идентификаторе Microsoft Entra и анализирует назначения ролей между двумя датами. Запрос извлекает прямые назначения ролей из таблицы 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() 

Пример 3. Получение добавленных пользователей в приложение между двумя датами моментального снимка данных

Эти отчеты предоставляют представление о том, какие пользователи получили назначение роли приложения целевому приложению между двумя датами. Эти отчеты можно использовать для отслеживания изменений в доступе к приложению с течением времени.

Этот запрос предназначен для конкретного приложения в идентификаторе Microsoft Entra и изменения назначений ролей между датой начала и окончания.

// 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" 

Пример 4. Проверки доступа

Сведения о завершении & по временной шкале

После отправки данных используйте следующие запросы Kusto для просмотра.

  • Когда был завершен последний цикл проверки доступа? Сколько времени это займет?
ReviewInstances 
| summarize LastCompletedDate = max(ReviewInstanceEndDateTime),  
            ReviewDuration = datetime_diff('minute', max(ReviewInstanceEndDateTime), min(ReviewInstanceStartDateTime))  
  • Выполняется ли процесс проверки доступа по времени (например, ежеквартально, ежегодно)?
ReviewInstances 
| extend ExpectedFrequency = "Quarterly" // Replace with 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  

Проверка участия & Engagement

  • Кто был назначен рецензентами?
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 non-responders 
| 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 non-responders 
| 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 have 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 non-responsive 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 

     

Настройка текущих импортов

В этом руководстве иллюстрируется процесс однократного извлечения, преобразования и загрузки данных (ETL) для заполнения Azure Data Explorer единственным снимком для целей отчетности. Для текущих отчетов или сравнения изменений с течением времени можно автоматизировать процесс заполнения Azure Data Explorer из Microsoft Entra, чтобы база данных продолжала иметь текущие данные.

Вы можете использовать Azure Automation, облачную службу Azure, для размещения скриптов PowerShell, необходимых для извлечения данных из Microsoft Entra ID и Microsoft Entra ID Governance. Дополнительные сведения см. в статье Автоматизация задач управления Microsoft Entra ID с помощью Azure Automation.

Вы также можете использовать функции 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

Запрос данных в Azure Monitor

Если вы отправляете аудит, вход или другие журналы Microsoft Entra в Azure Monitor, то вы можете включить эти журналы из рабочей области Azure Monitor Log Analytics в ваши запросы. Дополнительные сведения о связи Azure Monitor и Azure Data Explorer см. в статье Запрос данных в Azure Monitor с помощью Azure Data Explorer.

  1. Войдите в Центр администрирования Microsoft Entra.

  2. Выберите параметры диагностики .

  3. Выберите рабочую область Log Analytics, в которой вы отправляете журналы.

  4. В обзоре рабочей области Log Analytics запишите идентификатор подписки, имя группы ресурсов и имя рабочей области.

  5. Войдите на портал Azure.

  6. Перейдите к веб-интерфейсу Azure Data Explorer.

  7. Убедитесь, что в списке указан кластер Azure Data Explorer.

  8. Выберите + Добавить, затем Соединение.

  9. В окне Добавление подключения введите URL-адрес рабочей области Log Analytics, сформированный из облачного имени хоста, идентификатора подписки, имени группы ресурсов и имени рабочей области Azure Monitor Log Analytics, как описано в Добавление рабочей области Log Analytics.

  10. После установки подключения рабочая область Log Analytics появится в левой области с собственным кластером Azure Data Explorer.

  11. В меню слева выберите Запроси выберите кластер Azure Data Explorer.

  12. В панели запросов вы можете ссылаться на таблицы Azure Monitor, содержащие журналы Microsoft Entra, в своих запросах Azure Data Explorer. Например:

    let CL1 = 'https://ade.loganalytics.io/subscriptions/*subscriptionid*/resourcegroups/*resourcegroupname*/providers/microsoft.operationalinsights/workspaces/*workspacename*';
    cluster(CL1).database('*workspacename*').AuditLogs | where Category == "EntitlementManagement"  and OperationName == "Fulfill access package assignment request"
    | mv-expand TargetResources | where TargetResources.type == 'AccessPackage' | project ActivityDateTime,APID = toguid(TargetResources.id)
    | join EntraAccessPackage on $left.APID == $right.Id
    | limit 100
    

Перенос данных из других источников

Вы также можете создавать дополнительные таблицы в Azure Data Explorer для приема данных из других источников. Если данные содержатся в JSON-файле, аналогично приведенным выше примерам, или в CSV-файле, вы можете создать таблицу при первом получении данных из файла. После создания таблицы вы также можете использовать LightIngest для приема данных в Azure Data Explorer из JSON или CSV-файла.

Дополнительные сведения о приеме данных см. в обзоре приема данных Azure Data Explorer.

Пример 5. Объедините назначения приложений из Entra и второго источника для создания отчета о всех пользователях, которые имели доступ к приложению между двумя датами.

В этом отчете показано, как объединить данные из двух отдельных систем для создания пользовательских отчетов в Azure Data Explorer. Он объединяет данные о пользователях, их ролях и других атрибутах из двух систем в унифицированном формате для анализа или отчетности.

В этом примере предполагается, что таблица с именем salesforceAssignments со столбцами UserName, Name, EmployeeId, Department, JobTitle, AppName, Roleи CreatedDateTime, заполненными путем привлечения данных из другого приложения.

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

let startDate = datetime("2023-06-01"); 
let endDate = datetime("2024-03-13"); 
let servicePrincipalId = "<your service principal-id>"; 

// Pre-process AppRoleAssignments with specific filters and projections 
let processedAppRoleAssignments = AppRoleAssignments 
    | where ResourceId == servicePrincipalId and todatetime(CreatedDateTime) between (startDate .. endDate) 
    | extend AppRoleId = tostring(AppRoleId) 
    | project PrincipalId, AppRoleId, CreatedDateTime, ResourceDisplayName; // Exclude DeletedDateTime and keep ResourceDisplayName 

// Pre-process AppRoles to get RoleDisplayName for each role 
let processedAppRoles = AppRoles 
    | mvexpand AppRoles 
    | project AppRoleId = tostring(AppRoles.Id), RoleDisplayName = tostring(AppRoles.DisplayName); 

// Main query: Process EntraUsers by joining with processed role assignments and roles 
EntraUsers 
    | join kind=inner processedAppRoleAssignments on $left.ObjectID == $right.PrincipalId // Join with role assignments 
    | join kind=inner processedAppRoles on $left.AppRoleId == $right.AppRoleId // Join with roles to get display names 

    // Summarize to get the latest record for each unique combination of user and role attributes 
    | summarize arg_max(AccountEnabled, *) by UserPrincipalName, DisplayName, tostring(EmployeeId), Department, JobTitle, ResourceDisplayName, RoleDisplayName, CreatedDateTime 

    // Final projection of relevant fields including source indicator and report date 
    | project UserPrincipalName, DisplayName, EmployeeId=tostring(EmployeeId), Department, JobTitle, AccountEnabled=tostring(AccountEnabled), ResourceDisplayName, RoleDisplayName, CreatedDateTime, Source="EntraUsers", ReportDate = now() 

// Union with processed salesforceAssignments to create a combined report 
| union ( 
    salesforceAssignments 

    // Project fields from salesforceAssignments to align with the EntraUsers data structure 
    | project UserPrincipalName = UserName, DisplayName = Name, EmployeeId = tostring(EmployeeId), Department, JobTitle, AccountEnabled = "N/A", ResourceDisplayName = AppName, RoleDisplayName = Role, CreatedDateTime, Source = "salesforceAssignments", ReportDate = now() 
) 

Следующие шаги