Azure Automationを使ったMicrosoft 365グループ作成
2022-12-13
azblob://2022/12/16/eyecatch/microsoft-365-group-creating-using-azure-automation-000.jpg

前書き

本記事ではAzure AutomationでのMicrosoft 365関連のPowerShellスクリプト実行について解説します。

今回は一例としてMicrosoft 365グループの作成を実行します。

Microsoft 365グループとは、TeamsやSharePointが利用できるグループのことです。

この記事では下記の内容を実現します。

・Azure Automationを使ってPowerShellを実行する

・各種GraphAPIの権限をAutomationアカウント(Managed Identity)に付与する

・M365グループ作成をGraphのコマンドで実現する


1. Azure Automationアカウントを作成する

Azure PortalからAzure Automationアカウントを作成します。

 作成をクリックして完了です。


 

2. AutomationにPowerShell モジュールを登録する

下記モジュールを追加します。

  • Microsoft.Graph.Authentication
  • Microsoft.Graph.Groups
  • Microsoft.Graph.Teams
  • Microsoft.Graph.Users
  • Microsoft.Graph.Users.Actions


3. AutomationアカウントのマネージドIDへ権限付与

ユーザー権限を利用せずにAzure Automationアカウントの権限でスクリプトを実行するため、 Azure AutomationアカウントのマネージドIDに権限を付与します。

まずはAzure PortalからマネージドIDの情報ををコピーします。

取得する情報はAzure Automationアカウント>アカウント設定>IDまで遷移した先のオブジェクト(プリンシパル)IDです。

次にローカル環境から下記のコマンドを実行して権限を付与します。

今回はMicrosoft 365グループを作成するために必要な権限を設定しています。

#認証
Install-Module -Name Microsoft.Graph.Applications
$Permissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
  "GroupMember.ReadWrite.All"
  "User.ReadWrite.All"
  "RoleManagement.ReadWrite.Directory"
  "Team.Create"
)
Connect-MgGraph -TenantId $TenantId -Scopes Group.ReadWrite.All, GroupMember.ReadWrite.All, Directory.AccessAsUser.All

$TenantID="M365のテナント ID を指定する"
$ObjectIdOfAutomation="Azure AutomationアカウントのオブジェクトIDを指定する"
$GraphServicePrincipal =  Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"

$AppRoles = $GraphServicePrincipal.AppRoles | ?{($_.Value -in $Permissions) -and ($_.AllowedMemberTypes -contains "Application")}

foreach($AppRole in $AppRoles)
{
  $params = @{
    "PrincipalId" = $ObjectIdOfAutomation
    "ResourceId" = $GraphServicePrincipal.Id
    "AppRoleId" = $AppRole.Id
  }

  New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $ObjectIdOfAutomation `
    -BodyParameter $params `
    -Verbose
}

 

4. Azure AutomationでRunbookを作成する

後半戦です!

Azure PortalのAzure Automationアカウントの管理画面に移動しましょう。

Runbookを作成して下記スクリプトを登録後、テスト実行してみましょう。

#Init
Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Groups

#Azure Automationアカウントの認証でAzコマンドを実行できるように認証を通す
Connect-AzAccount -Identity
#認証された情報からトークンを取得(Graph接続用)
$token = (Get-AzAccessToken -ResourceTypeName MSGraph).token

#取得したトークンを利用してGraphコマンドを実行できるようにする
Connect-MgGraph -AccessToken $token
#テスト用コマンド(実行コマンドに書き換えます)
Get-MgGroup |select -First 1

マネージドIDを使うと認証周りがすっきりしますね。

正しくコマンドが動くと下記の画面が表示されます。 MailNicknameが1件取得できていれば成功です。


補足:記事作成中に詰まったポイント

Runbookでコマンドを実行する際にこんなエラーが出ました。むむ、Connect出来ていない。

モジュールMicrosoft.Graph.Authenticationの一部のランタイムバージョンにおいて、このエラーが発生するようです。 

今回は1.9.6のモジュールを特定してインポートして解決しました

参考URL https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/1439

対象のモジュールは下記スクリプトで取得できます。

#対象モジュールを検索して、c:\temp配下にモジュールを保存
Find-Module -Name Microsoft.Graph.Authentication -RequiredVersion 1.9.6 | `
Save-Module -Path C:\temp\
#↓はGUIZIPにしても良いです
Compress-Archive -Path C:\temp\Microsoft.Graph.Authentication\ -DestinationPath C:\temp\zip\Microsoft.Graph.Authentication.zip -Force

ファイルが作成出来たらAzure PortalのAzure Automationアカウント>共有リソース>モジュール>モジュールの追加をクリック

アップロード種別に「ファイルの参照」を選択、 ZIPファイルを指定してインポートすればモジュール更新完了です。


5. 実行したいコマンドを登録する

詰めに入ります。

下記のスクリプトをRunbookに登録して実行しましょう。

内容はMicrosoft 365グループを作成するスクリプトです。実行する場合は$groupDisplayNameから$descriptionを任意の値に修正して実行してください。

#Init
Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Groups
Import-Module Microsoft.Graph.Teams 

$groupDisplayName = "作成するグループの表示名" 
$mailNickName = "作成するグループのメールニックネーム(半角英数・記号)"
$groupOwnerUPN = "OwnerのUPNを入力します"
$groupMembers = "作成するグループに追加したいメンバーのUPNをカンマ区切りで入力"
$description = "作成するグループの注釈"

#Azure Automationアカウントの認証情報でAzAccountに接続(Azコマンドを利用できる)
Connect-AzAccount -Identity
#認証された情報からトークンを取得(Graph接続用)
$token = (Get-AzAccessToken -ResourceTypeName MSGraph).token

#Azure Automationアカウントの認証情報でMgGraphに接続する(MgGraphコマンドを利用できる)
Connect-MgGraph -AccessToken $token #-Scopes Group.ReadWrite.All, GroupMember.ReadWrite.All

#グループオーナーのID情報を取得する
$groupOwner = (Get-MgUser -UserId $groupOwnerUPN).Id
$owner = "https://graph.microsoft.com/v1.0/users/" + $groupOwner
$members = @()
$groupmembers.split(',') |% `
{
    $members += "https://graph.microsoft.com/v1.0/users/" + (Get-MgUser -UserId $_).Id
}
if((Get-MgGroup -Search "MailNickname:$($mailNickName)" -ConsistencyLevel eventual).count -eq 0){

    $NewGroupParams = @{
      "displayName" = $groupDisplayName
      "mailNickname"= $mailNickName
      "description" = $description
      "owners@odata.bind" = @($owner)
      "members@odata.bind" = @($members)
      "groupTypes" =  @("Unified")
      "mailEnabled" =  "true"
      "securityEnabled" = "false"
      ##参照レベルの変更(Public/Private/HiddenMembership)
      "Visibility" = "private"
    }

    $Group = New-MgGroup -BodyParameter $NewGroupParams

    # 作成完了まで数秒時間が掛かるためスリープ
    Sleep 30
    $NewTeamParams = @{
      "template@odata.bind"="https://graph.microsoft.com/v1.0/teamsTemplates('standard')"
      "group@odata.bind"="https://graph.microsoft.com/v1.0/groups('$($Group.Id)')"
    }
    NewTeam = New-MgTeam -BodyParameter $NewTeamParams
    "Success!!"

}else{
    "Group [$($mailNickName)] was Already Created..."
}

実行してエラーが出なければ成功です。

Microsoft 365 管理センターなどからグループが作成されたことを確認しましょう。


おわり:この仕組みの使い道について

今のままではスクリプトにパラメーターがハードコーディングされていて使い物になりません。

下記を実現して自動化することで初めて本領を発揮します。

1. 何かのトリガーから発火

2. Runbook実行

3. 結果(成功/失敗)を通知

4. 作業ログを記録

活用例についても別の記事で紹介しようと思います。