Entra ID に登録されたデバイスオブジェクトの一部の属性については、アプリケーションの権限では設定できない制限があることご存じでしたでしょうか?
詳細は以下の公開情報を参照いただければと思いますが、Windows 以外のプラットフォームのデバイスオブジェクトの場合、アプリケーションの権限で実行された PowerShell では extensionAttribute 以外の属性値を変更することができません。
でも、無人スクリプトで自動的に属性値更新を行いたい場合などありますよね?(私はありました!)
この記事では、上述のような委任権限でしか設定することができない属性を無人スクリプトで登録できるようにする実装方法について紹介します。
目次
公開情報
Update device – Microsoft Graph v1.0 | Microsoft Learn

エラーの再現
アプリケーションの権限で実行すると、以下の通りエラーが発生する。
(Update-MgDevice : Properties other than ExtendedAttribute1..15 can be modified only on windows devices.)

実装方法
注意事項
- ROPC フローはセキュリティ上の観点から推奨されていません。
- 可能な限りデバイスコードフロー、Interactive フロー、または Managed Identity などの代替認証方式をご検討ください。
- このスクリプトはサンプルです。
- 実行する前に、テナント構成、クライアントID、シークレット、権限範囲、デバイスIDなどを実環境に合わせて置き換えてください。
- 実行には、デバイスオブジェクトの更新に必要な Microsoft Graph の権限(
Device.ReadWrite.All
等)を持つアプリケーションとユーザーアカウントが必要です。
事前作業
- Windows365 管理者ロールを割り当てられた Entra ID アカウント
- アプリ登録
- シークレットの発行が必要です。
- Microsoft Graph > 委任されたアクセス許可 > openid、および profile の付与
- Microsoft Graph > 委任されたアクセス許可 > Directory.AccessAsUser.All の付与
ソースコード
# ==========================
# 事前設定部分
# ==========================
$tenantId = "<your tenant ID>" # テナントID (GUID)
$clientId = "<your client ID>" # 公開済みアプリのクライアントID
$clientSecret = "<your secret>"# アプリケーションのクライアントシークレット
$username = "<your admin username>" # Windows365 管理者ロールを持つログイン用ユーザー名(UPN)
$password = "<your admin password>" # 上記ユーザーのパスワード(安全な管理を行ってください)
$deviceId = "<device ID>" # 更新対象デバイスオブジェクトのID
# 更新したい PhysicalIds の値(例)
$newPhysicalIds = @("PhysicalId1","PhysicalId2")
# Microsoft Graph エンドポイント
$graphEndpoint = "https://graph.microsoft.com"
$graphScope = $graphEndpoint + "/.default"
$deviceUri = $graphEndpoint + "/v1.0/devices/" + $deviceId
$authEndpoint = "https://login.microsoftonline.com/" + $tenantId + "/oauth2/v2.0/token"
# ==========================
# トークン取得 (ROPC フロー)
# ==========================
$tokenBody = @{
grant_type = "password";
client_id = $clientId;
client_secret = $clientSecret;
username = $username;
password = $password;
scope = $graphScope;
}
try {
$tokenResponse = (Invoke-WebRequest -Method POST -Uri $authEndpoint -Body $tokenBody -ContentType "application/x-www-form-urlencoded") | ConvertFrom-Json
} catch {
Write-Host "トークン取得に失敗しました"
pause
exit 1
}
$accessToken = $tokenResponse.access_token
if (-not $accessToken) {
Write-Host "アクセストークンが取得できませんでした。"
pause
exit 1
}
# ==========================
# デバイス更新(PATCH)
# ==========================
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
$patchBody = @{
physicalIds = $newPhysicalIds
} | ConvertTo-Json
try {
$patchResponse = Invoke-WebRequest -Method PATCH -Uri $deviceUri -Headers $headers -Body $patchBody
Write-Host "デバイスの PhysicalIds を更新しました。"
} catch {
Write-Host "デバイス更新に失敗しました"
}
確認結果
以下の通り、アプリケーションの権限では登録できなかったモバイルデバイスのデバイスオブジェクトの PhysicalIds に属性登録できたことが確認できます。

コメント