AzureAD B2Cユーザアカウントの操作方法(PowerShell)

PowerShellでAzure AD B2Cのユーザアカウントを操作する方法を説明します。

概要

  • AzureAD B2CのユーザアカウントをPowerShellで操作する方法を説明します。
  • 拡張属性・カスタム属性を操作する方法も併せて説明します。
    なお、拡張属性とカスタム属性については、こちらに纏めてみました。
  • PowerShellからAzureADを操作するためのモジュールはいくつかありますが、
    ここではAzure AD for Graph (Azure AD v2)を使用します。
  • TwitterやFacebook等の外部アカウント連携は想定しておらず、ローカルアカウントの使用を想定した例になっています。拡張属性・カスタム属性以外の操作はAzureADでも同様に使用できると思います。
  • Windows 10環境で確認した結果を記載しています。
  • 環境に依存する内容は変数として定義しているので、実行時に適宜変更してください。
    $TenantId = "mytenant.onmicrosoft.com"
    $ObjectId = "5122ad78-1a91-4927-a521-12e59696fa6e" # オブジェクトIDまたはUserPrincipalName

サンプル実行のための事前準備

AzureADモジュールがインストールされていない場合、「Azure ADモジュールのインストール方法」を行ってください。また、サンプルを実行する前に「Azureへの接続方法」を行ってください。

Azure ADモジュールのインストール方法

管理者用PowerShellを起動し、”Install-Module -Name AzureAD”を実行します。
(ローカルコンピュータの構成変更が必要になるので、管理者権限のPowerShellが必要です。)

Install-Module -Name AzureAD

続行するには NuGet プロバイダーが必要です
PowerShellGet で NuGet ベースのリポジトリを操作するには、'2.8.5.201' 以降のバージョンの ...
...
'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force' を実行して ...
今すぐ PowerShellGet で NuGetプロバイダーをインストールしてインポートしますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y

信頼されていないリポジトリ
信頼されていないリポジトリからモジュールをインストールしようとしています。
このリポジトリを信頼する場合は、Set-PSRepository コマンドレットを実行して、リポジトリの ...
'PSGallery'からモジュールをインストールしますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Azureへの接続方法

通常のPowerShellを起動し、Connect-AzureADを実行します。
Azureのサインイン画面が表示されるので、ユーザ名やパスワード等の認証情報を入力します。

Connect-AzureAD -TenantId $TenantId

Account     Environment TenantId                  TenantDomain             AccountType
-------     ----------- --------                  ------------             -----------
youraccount AzureCloud  xxxxxxxx-...-xxxxxxxxxxxx mytenant.onmicrosoft.com User

ユーザアカウントの一覧・検索

Get-AzureADUserで使用できるオプションはコマンドリファレンスを参照のこと。

# 単純な一覧取得
Get-AzureADUser
Get-AzureADUser -Top 10
Get-AzureADUser -All $true # ユーザ数が多い場合(全件取得)

# ソート(昇順・降順)
Get-AzureADUser | Sort DisplayName,ObjectId
Get-AzureADUser | Sort DisplayName,ObjectId -Descending

# 表示名やUPNで検索
# ※DisplayNameとUserPrincipalNameの前方一致で検索
Get-AzureADUser -SearchString "試験"

# 任意条件で検索(フィルタ指定)
# ※endsWith()等の一部フィルタ機能は未実装のようです。
Get-AzureADUser -Filter "userPrincipalName eq 'test1@example.com'"
Get-AzureADUser -Filter "Surname eq '試験' and GivenName eq '一郎'"
Get-AzureADUser -Filter "startswith(displayName,'試験')"

# 任意条件で検索(ワイルドカード)
Get-AzureADUser | Where-Object {$_.DisplayName -Like "*郎"}

# オブジェクトIDで検索
$ObjectId="7a72f111-3492-4f7a-8ff9-e88ff24b57ad"
Get-AzureADUser -ObjectId $ObjectId

# すべての属性情報を出力
Get-AzureADUser | Select *
Get-AzureADUser | Format-List

# 抽出項目の選択例
Get-AzureADUser | Select ObjectId, DisplayName

# 抽出項目の選択例(拡張プロパティSignInNames)
$ObjectId="79cfb0bf-8b18-43a5-a476-fbf9bf196aad"
Get-AzureADUser -ObjectId $ObjectId | Select -ExpandProperty SignInNames
  • -Filterで指定できる条件はこちらを参考のこと。なお、そこに記載している全てのコマンドを使用できるわけではないようです。例えば、endsWith()は使用できませんでした。
  • ユーザアカウントの属性一覧はこちらを参考のこと。
  • ユーザの各種属性を出力したい場合、Format-Listを使用します。Format-Listで使用できるオプションはコマンドリファレンスを参照のこと。

ユーザアカウントの作成・更新・削除

基本的なユーザアカウントの作成

$TenantId="mytenant.onmicrosoft.com" # 環境に合わせてテナント名を指定

# パスワード情報の設定
$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = "Abcd1234!"
$PasswordProfile.ForceChangePasswordNextLogin = $False

# ユーザアカウントの作成
New-AzureADUser `
    -DisplayName "試験 一郎" `
    -PasswordProfile $PasswordProfile `
    -UserPrincipalName "ichiro.shiken@$TenantId" `
    -AccountEnabled $true `
    -MailNickName "ichiro.shiken"

Azureポータルと同等のユーザアカウントの作成

Azure AD B2Cテナントの「ユーザー」から「新しいユーザー」を作成した場合と同様の設定を行うサンプルです。

$TenantId="mytenant.onmicrosoft.com" # 環境に合わせてオブジェクトIDかUPNを指定

# サインインユーザ名、またはサインインメールアドレスを使用する場合は指定
$SignInNames = New-Object `
    -TypeName System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.SignInName]
$SignInName1 = New-Object -TypeName Microsoft.Open.AzureAD.Model.SignInName
$SignInName1.Type = "userName"
$SignInName1.Value = "jiro.shiken"
$SignInNames.Add($SignInName1)
$SignInName2 = New-Object -TypeName Microsoft.Open.AzureAD.Model.SignInName
$SignInName2.Type = "emailAddress"
$SignInName2.Value = "jiro.shiken@example.com"
$SignINNames.Add($SignINName2)

# パスワード情報の設定
$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = "password"
$PasswordProfile.ForceChangePasswordNextLogin = $False

# MailNickName/UserPrincipalName用
$Guid = New-Guid

# ユーザアカウントの作成
New-AzureADUser `
    -DisplayName "試験 二郎" `
    -Surname "試験" -GivenName "二郎" `
    -AccountEnabled $True `
    -SignInNames $SignInNames `
    -MailNickName $Guid `
    -UserPrincipalName "$Guid@$TenantId" `
    -PasswordProfile $PasswordProfile `
    -PasswordPolicies "DisablePasswordExpiration, DisableStrongPassword"
  • New-AzureADUserで使用できるオプションはコマンドリファレンスを参照のこと。
  • $SignInNamesは必須ではありません。$SignInNamesには、ユーザ名($SignInName1)、メールアドレス($SignInName2)のいずれか、または両方の追加が可能です。
  • MailNickName、UserPrincipalName(“@”の前)には、ユーザアカウントのObjectIdとは異なる何らかのGUIDが指定されています。この仕様は分かりませんが、ここでは新規に作成したGUIDを指定しています。

ユーザアカウントの属性の変更

$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定

# 例では単一属性を変更していますが、複数指定も可能です

# 一般的な属性の変更
Set-AzureADUser -ObjectId $ObjectId -DisplayName "試験 一郎"
Set-AzureADUser -ObjectId $ObjectId -UsageLocation "JP"
Set-AzureADUser -ObjectId $ObjectId `
    -Country "国" -PostalCode "123-4567" -State "都道府県" `
    -City "市区町村" -StreetAddress "番地" `
    -PhysicalDeliveryOfficeName "会社" `
    -TelephoneNumber "03-1234-5678" -Mobile "090-1234-5678"

# メールアドレス設定(配列)
Set-AzureADUser -ObjectId $ObjectId `
    -OtherMails @("ichiro.shiken@example.com", "ichiro.shiken@example.org")

# ユーザアカウントの有効化・無効化
Set-AzureADUser -ObjectId $ObjectId -AccountEnabled $True
Set-AzureADUser -ObjectId $ObjectId -AccountEnabled $False

# パスワードの変更 ※検証や開発環境向け(運用環境での使用はリスクあり)
$SecureString = ConvertTo-SecureString "password" -AsPlainText -Force
Set-AzureADUserPassword -ObjectId $ObjectId -Password $SecureString
  • 利用場所(UsageLocation)は、”JP”等の実在する国コード(2桁)を指定する必要があります。(例えば”ZZ”等の実在しないコードを指定するとエラーになります。)
  • 「サインインのブロック」はAccountEnabled属性に対応します。ポータルと属性の意味が逆転しており、サインインをブロックする場合はAccountEnabledに$Falseを指定する必要があることに注意。
  • Set-AzureADUserで使用できるオプションはコマンドリファレンスを参照のこと。-CompanyName等、記載のないオプションがあります。
  • パスワード変更について
    • 簡単にパスワードを変更できるようConvertTo-SecureStringでパスワードを直接指定しています。この方法はコマンドの履歴に残るので本番運用での使用は推奨しません。この警告を無視するために-Forceを指定しています。
    • ConvertTo-SecureStringで使用できるオプションはコマンドリファレンスを参照のこと。
    • Set-AzureADUserPasswordで使用できるオプションはコマンドリファレンスを参照のこと。

ユーザアカウントの削除

$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定
Remove-AzureADUser -ObjectId $ObjectId

カスタム属性と拡張属性の操作

ユーザアカウントの属性には、標準的な属性とそれ以外の拡張属性に分けられます。
拡張属性には、従業員IDやユーザアカウント作成日時等の非標準扱いの属性(以降では「既定の拡張属性」と呼ぶ)や、テナント独自に定義したカスタム属性が含まれます。(両者の違いはこちらをご覧ください。)

テナントのカスタム属性定義の一覧取得

カスタム属性の名称は、実行環境によって異なります。
テナントに定義されているカスタム属性の名称は次のように取得できます。

Get-AzureADApplication | Get-AzureADApplicationExtensionProperty

ObjectId                  Name                                 TargetObjects
--------                  ----                                 -------------
f1986a40-xxx-94d1100b167c extension_9370axxxb044_customInt     {User}
5822ad78-xxx-11e59656fc6e extension_9370axxxb044_customBoolean {User}
8e02c046-xxx-0a76c0d7f84d extension_9370axxxb044_customString  {User}
  • カスタム属性の名称は”extension_{guid}_属性名”となります。詳細はこちらをご覧ください。
  • Get-AzureADApplicationで使用できるオプションはコマンドリファレンスを参照のこと。
  • Get-AzureADApplicationExtensionPropertyで使用できるオプションはコマンドリファレンスを参照のこと。

ユーザアカウントの拡張属性値の一覧取得

$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定

# 拡張属性値の取得方法1
Get-AzureADUser -ObjectId $ObjectId | Select -ExpandProperty ExtensionProperty

Key                                  Value
---                                  -----
odata.metadata                       https://graph...
odata.type                           Microsoft.DirectoryServices.User
createdDateTime                      2023/07/16 6:55:04
employeeId                           1234
onPremisesDistinguishedName
userIdentities                       []
extension_9370axxxb044_customInt     987654321

# 拡張属性値の取得方法2
Get-AzureADUserExtension -ObjectId $ObjectId

Key                                  Value
---                                  -----
...(方法1と同様)...

# 拡張属の値の取得(既定の拡張属性)
(Get-AzureADUser -ObjectId $ObjectId).ExtensionProperty["employeeId"]

1234

# 拡張属性の値の取得(カスタム属性)
(Get-AzureADUser -ObjectId $ObjectId).ExtensionProperty["extension_9370axxxb044_customInt"]

987654321
  • 拡張属性に含まれる既定の拡張属性やカスタム属性を取得できる。
  • Get-AzureADUserExtensionで使用できるオプションはコマンドリファレンスを参照のこと。
  • 既定の拡張属性は、値の有無に関わらず項目が表示される。カスタム属性の場合は値がないと項目自体が表示されないことに注意が必要です。

拡張属性の値の更新

$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定

# 既定の拡張属性employeeIdの値を更新
Set-AzureADUserExtension -ObjectId $ObjectId `
    -ExtensionName employeeId -ExtensionValue 1234

# カスタム属性customIntの値を更新
Set-AzureADUserExtension -ObjectId $ObjectId `
    -ExtensionName extension_9370axxxb044_customInt -ExtensionValue 987654321

# 次のような更新は不可
(Get-AzureADUserExtension -ObjectId $ObjectId)["employeeId"] = "77777"

拡張属性の値の削除

$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定

# 既定の拡張属性employeeIdの値を削除
Remove-AzureADUserExtension -ObjectId $ObjectId -ExtensionName employeeId

# カスタム属性customIntの値を削除
Remove-AzureADUserExtension -ObjectId $ObjectId -ExtensionName extension_9370axxxb044_customInt

ユーザアカウント作成時に拡張属性を指定

$TenantId="" # 環境にテナント名を指定

# パスワード情報の設定
$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = "Abcd1234!"
$PasswordProfile.ForceChangePasswordNextLogin = $False

# 拡張属性の設定(既定の拡張属性とカスタム属性)
$ExtensionProperty = New-Object `
    -TypeName System.Collections.Generic.Dictionary"[String,String]"
$ExtensionProperty["employeeId"] = 123456
$ExtensionProperty["extension_9370axxxb044_customInt"] = 9876543

# ユーザアカウントの作成
New-AzureADUser `
    -DisplayName "試験 三郎" `
    -PasswordProfile $PasswordProfile `
    -UserPrincipalName "saburo.shiken@$TenantId" `
    -AccountEnabled $true `
    -MailNickName "saburo.shiken" `
    -ExtensionProperty $ExtensionProperty

その他のカスタム属性の操作

エクスポート

JSONでエクスポート

# 複数のユーザアカウントをエクスポート(JSON配列として出力)
Get-AzureADUser | ConvertTo-Json

[
    {
        "ExtensionProperty":  {
                                  "employeeId":  "123456",
                                  "extension_9370axxxb044_customInt":  "9876543"
                              },
        "DeletionTimestamp":  null,
        "ObjectId":  "185814a7-2650-4498-8dc8-87e7cfd672d5",
        "ObjectType":  "User",
        ...
    },
    {
        "ExtensionProperty":  {
        ...
    }
]

# 単一のユーザアカウントのエクスポート
$ObjectId="" # 環境に合わせてオブジェクトIDかUPNを指定
Get-AzureADUser -ObjectId $ObjectId | ConvertTo-Json

{
    "ExtensionProperty":  {
                              "employeeId":  "123456",
                              "extension_9370axxxb044_customInt":  "9876543"
                          },
    "DeletionTimestamp":  null,
    "ObjectId":  "185814a7-2650-4498-8dc8-87e7cfd672d5",
    "ObjectType":  "User",
    ...
}

# 単一のユーザアカウントのエクスポート
# ※複数オブジェクトを対象としてToJson()を実行しても配列にならないことに注意
(Get-AzureADUser -ObjectId $ObjectId).ToJson()

{
  "accountEnabled": true,
  "displayName": "試験 一郎",
  "otherMails": [],
  "passwordPolicies": "DisablePasswordExpiration, DisableStrongPassword",
  "signInNames": [
    {
      "type": "emailAddress",
      "value": "ichiro.shiken@example.com"
    }
  ],
  "userPrincipalName": "ichiro.shiken@example.com",
  "createdDateTime": "2020-09-19T15:04:20Z",
  "employeeId": null,
  "userIdentities": [],
  "extension_9370axxxb044_customInt": 9876543
}

# ファイルに直接エクスポートする場合
Get-AzureADUser | ConvertTo-Json | Out-File result1.json
(Get-AzureADUser -ObjectId $ObjectId).ToJson() | Out-File result2.json

CSVでエクスポート

# ObjectId, DisplayNameをCSVとしてエクスポート
Get-AzureADUser | Select ObjectId, DisplayName | ConvertTo-Csv

#TYPE Selected.Microsoft.Open.AzureAD.Model.User
"ObjectId","DisplayName"
"185814a7-2650-4498-8dc8-87e7cfd672d5","試験 三郎"
"2667fcc8-4116-4093-b25f-4a70c36011f6","試験 一郎"
"61f5ff5a-a415-4772-a427-cfb24c16c774","試験 二郎"

# ObjectId, DisplayName, otherMailsをCSVとしてエクスポート
# ※otherMailsは複数値を持つのでハッシュテーブルのカスタム式で変換
Get-AzureADUser | Select ObjectId, DisplayName, `
    @{n='otherMails';e={[string]::join(";",($_.otherMails))}} | ConvertTo-Csv

#TYPE Selected.Microsoft.Open.AzureAD.Model.User
"ObjectId","DisplayName","otherMails"
"185814a7-2650-4498-8dc8-87e7cfd672d5","試験 三郎",""
"2667fcc8-4116-4093-b25f-4a70c36011f6","試験 一郎","ichiro.shiken@example.org;...@example.com"
"61f5ff5a-a415-4772-a427-cfb24c16c774","試験 二郎",""

# ファイルに直接エクスポートする場合 ※日本語の文字化け回避のためにUTF8指定
Get-AzureADUser | Select ObjectId, DisplayName |Export-Csv result.csv -Encoding UTF8