Довольно часто приходят задачи написать скрипты для 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}
Тут на помощь приходит 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 параметре в манифесте.