Довольно часто приходят задачи написать скрипты для Microsoft 365, будь то репортинг или какие-то автоматизации. Как правило, сервисы входящие в пакет M365: Exchange Online, SharePoint Online или Microsoft Endpoint Manager - имеют свои отдельные модули для работы с ними из PowerShell. Однако возникают ситуации, когда функционала этих модулей недостаточно. В таких случаях остается либо ждать, когда этот функционал все же появится, либо писать скрипты под Graph API самому. Как правило это 2–3 функции основные, и множество их вариаций. В какой-то из дней при шедулинге очередного такого скрипта в голову прокралась идея, а почему бы не написать свой модуль для подобного рода запросов? Причем такой, который не ограничивался бы списком каких-то конкретных команд, и такой, чтобы если появилась какая-то новая функция, тем кто будет пользоваться этим модулем не пришлось бы ждать обновления со стороны разработчика. В итоге на свет появился Graph API Requests,  модуль, который позволяет делать практически любого вида запросы к Microsoft Graph API, доступные и описанные в официальной документации Microsoft используя PowerShell.

Установить модуль можно используя команду ниже:

Install-Module GraphApiRequests

Далее модуль необходимо импортировать:

Import-Module GraphApiRequests

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

  • Get-GraphDeviceAuthToken – служит для получения токена по авторизации устройства

  • Get-GraphToken – для получения токена через ClientSecret

  • Invoke-GraphApiRequest – для запросов к API.

Способ авторизации по ClientSecret я описывал ранее в своей предыдущей статье, где рассказывал как настроить репортинг Microsoft 365 Message Center в Telegram канал используя Azure Automation. Там же вы можете ознакомиться с процессом регистрации приложения в Azure Active Directory, что является пре-реквизитом для большинства запросов к Graph API.

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

Например удаление устройства из Azure AD по ID:

DELETE /devices/{id}

Права для DELETE /devices/{id}
Права для DELETE /devices/{id}

Тут на помощь приходит Get-GraphDeviceAuthToken, который позволяет делать вызовы к функциям, требующим Delegated Permissions.

Для получения токена посредством авторизации устройства, понадобится к предыдущим инструкциям добавить включение Redirect URIs. Чтобы перейти в меню настроек необходимо:

1. Открыть Azure Active Directory > App Registrations

2. Найти ваше зарегистрированное приложение и перейти к нему

3. Далее открыть меню Authentication > Нажать на кнопку Add a Platform и выбрать Mobile and desktop applications.

Но этого еще недостаточно. Так же нужно добавить https://localhost как дополнительный URI как показано на скриншоте ниже.

После того как произвели настройки Redirect URI и выдали необходимые права приложению, так же нужно в манифесте выставить следующий параметр с null на true:

"allowPublicClient": true

Далее можно переходить к получению токена.

NOTE: Для работы через токен полученный используя Get-GraphDeviceAuthToken необходимо выдавать Delegated права.

Для этого понадобится знать Application ID (доступно в Overview приложения) Tenant Name (в меню Overview Azure Active Directory), и как это принято для Delegated Permissions логин и пароль учетной записи с правами не ниже выданных приложению.

Получаем токен по авторизации устройства

$Token = Get-GraphDeviceAuthToken -TenantName <tenant name> -AppId c001f166-e732-4349-b138-ebb49b26e088

Далее вы увидите всплывающее окно авторизации устройства, куда нужно вставить код авторизации, который уже в вашем буфере обмена

Введя логин и пароль от учетной записи вы авторизуетесь в вашем приложении и в итоге увидите следующее окно

Данное окно необходимо закрыть и можно приступать к первому запросу к API.

Для примера вызовем все имеющиеся группы в Azure AD. Для этого приложению необходимо иметь права Delegated Groups.Read.All

Лучше заранее поместить вывод коммандлета в переменную

$Result = Invoke-GraphApiRequest -Token $Token -Resource groups

Как можно заметить, информации в выводе достаточно много. Поэтому вызовем только свойство displayName

$Result.DisplayName

Так же, можно вызвать несколько свойств одновременно

$Result.value | Select-Object displayName, mailEnabled, mailNickname

Метод вызовов к API в модуле по умолчанию GET, но изменив его так же можно и производить изменения в тенанте.

Версия API по умолчанию используется Beta, т. к. через нее как правило можно получить большее количество информации, если сравнивать с v1.0 Очень хорошо это видно на примере с managedDevices ресурсом. Однако через -ApiVersion можно выбрать и первую версию.

Список всех доступных ресурсов можно посмотреть в официальной документации. Так же есть поддержка body, для методов, поддерживаемых самим API.

Пример создания группы:

$BodyObject = [PSCustomObject]@{
    description = "Self help community for golf"
    displayName = "Golf Assist"
    groupTypes = @("Unified")
    mailEnabled = $true
    mailNickname = "golfassist"
    securityenabled = $false
}
$BodyJson = ConvertTo-Json $BodyObject
Invoke-GraphApiRequest -Token $Token -Resource groups -Method POST -Body $BodyJson

Ссылка на репозиторий: Github

Принимаются любые советы и предложения по улучшению функционала. Спасибо за внимание!

Update:

Модуль опубликован на PSGallery

Update 19.10.2021:

Добавлена информация об allowPublicClient параметре в манифесте.

Комментарии (0)