はじめに
Exchange Online PowerShell
Exchange Online PowerShell は、コマンド ラインから Microsoft 365 organizationのExchange Online部分を管理できる管理インターフェイスです (Exchange Online ProtectionおよびMicrosoft Defender for Office 365)。
Teamsのチームに一括登録したいよ…


今回はチームメンバーを一括設定するPowerhellのコードを紹介するから安心してね!
完成コード
写真の設定は下記のコードをコピペすることで簡単に設定が可能だよ。
※このあとコードを解説して行きます。
完成版
# Microsoft Graphに接続:
Connect-MgGraph -Scopes "Group.ReadWrite.All"
# csv読み込み
$Path = ".¥test.csv"
$csvData = Import-Csv -Path $Path
$add_group = "test@test.onmicrosoft.com"
$total = $csvData.Count
$count = 0
foreach ($data in $csvData) {
$count++
# 進捗状況を表示
Write-Progress -Activity "M365グループメンバーを追加中" -Status "$count/$total" -PercentComplete (($count / $total) * 100)
# 変数の設定
$add_user = $data.address
# グループIDとユーザーIDを取得:
$group = Get-MgGroup -Filter "mail eq '$add_group'"
$user = Get-MgUser -Filter "userPrincipalName eq '$add_user'"
try {
# メンバーをグループに追加:
New-MgGroupMember -GroupId $group.Id -DirectoryObjectId $user.Id
Write-Output "[ $($group.DisplayName) ]に[ $($user.DisplayName) ]をメンバー追加しました。"
}
catch {
Write-Output "[ $($group.DisplayName) ]に[ $($user.DisplayName) ]のメンバー追加が失敗しました。"
}
}
解説
# Microsoft Graphに接続:
Connect-MgGraph -Scopes "Group.ReadWrite.All"
MicrosoftGraphAPIへ接続を行います。
「Scopes」には今回チームを編集するので「Group.ReadWrite.All」を入れています。
※オプション(-Scope)については詳細はここで説明しませんが、正しいものを設定しないと編集が不可となる項目もありますので注意してください。
# csv読み込み
$Path = ".¥test.csv"
$csvData = Import-Csv -Path $Path
$add_group = "test@test.onmicrosoft.com"
csv読み込みを行います。
csvの内容は下記となっています。
address |
---|
test1@test.onmicrosoft.com |
test2@test.onmicrosoft.com |
test3@test.onmicrosoft.com |
こんな変更で・・・
「$add_group」で指定したグループアドレス(Teamsチーム)にメンバーを追加するため、
今回は直接指定しています。
csvデータにもう一列追加して追加するグループアドレスを記載するように変更すれば、
1つのcsvで複数のチームにメンバーを追加することができます。
# 追加データの全量
$total = $csvData.Count
# 追加したデータの数
$count = 0
後述する「進捗確認バー(プログレスバー)」を表示させるための数値を変数に格納しています。
foreach ($data in $csvData) {
$count++
# 進捗状況を表示
Write-Progress -Activity "M365グループメンバーを追加中"
-Status "$count/$total"
-PercentComplete (($count / $total) * 100)
「foreach」を使用してcsvデータ($csvData)から1行取り出し、($data)に格納します。
「Write-Progress」を使用して進捗状況を出力しています。
Write-Progress
-Activity タイトル
-Status 現在の完了している数量/csvデータの全量
-PercentComplete. Statusのパーセンテージ
# 変数の設定
$add_user = $data.address
1行取り出したデータを「$add_user」 に格納しています。
# グループIDとユーザーIDを取得:
$group = Get-MgGroup -Filter "mail eq '$add_group'"
$user = Get-MgUser -Filter "userPrincipalName eq '$add_user'"
チームにメンバーを追加する際には「ID」を使用するので準備します。
「Get-MgGroup」コマンドを使用して、テナント内に存在するグループを取得します。
その際に「Filter」オプションをつけることで「Get-MgGroup」コマンドで取得可能な列の「mail」と、
最初に用意した「$add_group」が一致しているデータを条件としています。
取得したデータを「$group」に格納します。
Filterの記述について
"userPrincipalName eq '$add_user'"
このように左側に取得するデータの列、右側に条件として指定したい値をシングルオートで囲んで記述します。
その後条件の全体をダブルクオートで囲みます。
「Get-MgUser」コマンドを使用して、テナント内に存在するユーザーを取得します。
上記と同様に「Filter」オプションをつけることで「Get-MgUser」コマンドで取得可能な列の「userPrincipalName」と、
最初に用意した「$add_user」が一致しているデータを条件としています。
取得したデータを「$user」に格納します。
こんな変更もあり・・
「Get-MgGroup」コマンドでは多くの列を取得可能です。
より処理を高速化したい場合は使用する「ID」のみに絞り込んでもいいかもしれません
try {
# メンバーをグループに追加:
New-MgGroupMember -GroupId $group.Id -DirectoryObjectId $user.Id
Write-Output "[ $($group.DisplayName) ]に[ $($user.DisplayName) ]をメンバー追加しました。"
}
catch {
Write-Output "[ $($group.DisplayName) ]に[ $($user.DisplayName) ]のメンバー追加が失敗しました。"
}
}
「try-catch」コマンドを使用して、成功した時の処理と失敗した時の処理を分けて記述しています。
「New-MgGroupMember」コマンドを使用してメンバを追加していきます。
-GroupId と -DirectoryObjectId にはそれぞれグループIDとユーザーIDを指定します。
IDについて
Microsoft 365 の ID には、ユーザー識別子であるユーザー ID(UID)と、ユーザー名であるユーザー プリンシパル名(UPN)があります。また、フェデレーションユーザを表す一意性のある ID として「ImmutableID」もあります
成功/失敗した場合には「Get-MgGroup」で取得したデータの列に存在する「DisplayName」と「Get-MgUser」で取得したデータの列に存在する「DisplayName」を使用して出力結果にわかりやすいように表示しています。
どうして?
$group.DisplayName ではなく、$($group.DisplayName) と記述しているのは、変数の展開を明示的に行うためです。
--ChatGPT引用--
通常、変数のプロパティを参照するだけなら $group.DisplayName
で十分ですが、以下のような場面では $()
を使わないと意図した動作にならない場合があります。
1. 文字列の中でオブジェクトのプロパティを展開する
$group = @{ DisplayName = "Admin Group" }
Write-Output "Group name is $group.DisplayName"
これは期待通り動かず、そのまま $group.DisplayName
という文字列が出力されます。
おわり