Edited at

Office365で(ほぼ)全自動ユーザー登録システムを作ってみた~実装編

この記事はOffice 365 Advent Calendar 2018 (12/4) に参加しています。

昨年の Office 365 Advent Calendar 2017 では

Office365で(ほぼ)全自動ユーザー登録システムを作ってみた

という記事を書きました。

実際にこの内容に沿った仕組みを作って運用を始めているのですが、今回は「具体的にどうやって実現しているのか」というところをご紹介したいと思います。

(前回、「アップデートします」だの「追って加筆します」なんて言っているうちに、早一年・・・)

流用できそうなアイデアないかな、と思った方は、昨年の記事もご参考にしていただければと思います。


概要(流れ)

ここは前回と同様ですが、おさらいです。

ひと言でいえば、以下のような社内ワークフロー


  • 申請を受け付けて、

  • 承認を依頼して、

  • 承認されたら処理を行って、

  • 処理が終わったら完了通知

を、アドオンやパッケージの導入とか、自前でWebサイトの構築とかせずに実現することを目指したもので、Office365 の運用にまつわる業務をこれで極力自動化・省力化することで

・管理者の負荷を下げましょう(そして他のことに時間を使いましょう)、

・申請者や承認者を待たせずに、かつ手間も減らしましょう、

という話です。

今回行っている具体的な管理者としての業務(処理)は、申請が承認された後に

まずオンプレのADにユーザーを作成、Azure AD ConnectでOffice365に同期後


  • Office365のライセンスを付与

  • 多要素認証有効化

  • グループへのメンバー追加

などを行っています。

最後のメンバー追加以外は現時点でFlow のアクションには無いようなので、

Azure Automation を使いRunbook にPowerShell スクリプトを登録、これをMicrosoft Flow からRunbook のジョブを作成して実行しています。

ここはちょっと敷居が高いというか、PowerShell 書ければわりと簡単に組み込めるのですが、Office365 しか使ってないよ、という場合はAzure のサブスクリプションが必要になります(Office365の方はE1があれば十分です)。

Flow のコネクタ・アクションも続々増えていますけれども、現状提供がなく、PowerShellならできるものなら この仕組みで粗方できてしまうかと

(本来であればGraph APIなどを使った方がスマートだと思いますし、Azure 使ってなくても同じことできそうですが、新しい方に中々シフトできないでいる私のような人でもFlow を活用できますよ)

あとワークフローで重要なのはステータス管理ですね。今回の仕組みはスムーズに流れれば申請~通知まで、ディレクトリ同期の定期実行タイミング(30分) を入れても1時間以内には終わると思いますが、承認者が忘れていたり、Flow が途中でコケてたりするので(これが結構あるんですよね)

「今どこまで終わってんの?」というのが確認できた方が良いと思います。

今回は申請情報も含めて、SharePoint Online のリストを使って記録しています。

ひとまずここで全体の流れ(フロー)と実際に使っている機能・サービスをまとめておきます。

Sequence.png

*SPO: SharePoint Online のリストを表しています

*Outlook(メール送信)は実際にはFlow の中でOutlookコネクタ(アクション)を使用して行っています

*Azure: Automation の機能を使用しています

*AzureAD はOffice365のユーザー・グループの登録先として記載しています


余談ですが・・・

上の図は WebSequenceDiagrams というサービスを使って書いています。

無償、Web(ブラウザ)ベース、Googleアカウントでサインインすれば複数の図が保存でき、印刷やPDF出力もできるので簡単なシーケンス図を描きたい時に便利です。

自分で作図するのではなく、図におこしたい内容(登場人物と処理の流れ)をテキストで記述すると勝手に図にしてくれるので

線(矢印)を引っ張って伸ばしたりつなげたりしなくて済みます。

Cacoo など使えばもっとカラフルで見やすく描けますが、簡単なフローなら十分だと思います。

↓↓↓上図を作成するのに実際に記述したテキスト↓↓↓

image.png

*ちなみに、今まで全部英語しか使っていなかったので気づきませんでしたが、エディタに直接日本語入力はうまくできませんでした。。

メモ帳など、別のアプリで入力した日本語をコピペしたら、ちゃんと入りました



実装手順(のポイント)

ではここから各処理の具体的な実装方法の話に入っていきたいと思います。

できれば最初から最後までStep by Step でお伝えしたいのですが、それではどうにも私の枠である12/4に間に合わず途中で終わってしまいそうなのでポイントに絞ってご紹介します。

今後はもっとアウトプットを増やしていきたいので、昨年の二の舞にならないよう、細かい内容はまめに書いていくつもりです。


1. 申請を受け付ける(Forms)

Forms を使って申請フォームを用意することについては昨年の記事でも触れているのでそちらをご覧ください。

※変化の激しいOffice365ですが、個人(Microsoft アカウント)向け無償版が出るなどForms もこの1年で拡張がありましたね。

昨年の記事で紹介したMSのブログを久しぶりに見たら、一部の上限が緩和されたというコメントが。


2018/09/07 Update! Forms の回答上限が 5,000 から 50,000 になったことを反映しました。


Microsoft Forms でよく本サポートに寄せられるお問い合わせ – Office Support Team Blog JAPAN より



しかし相変わらず設問数100個まで、1コンテンツ4KBまで(タイトル脇につけられるロゴ・画像は除く)、は変わっていないようです(試していませんが)。

現状、フォームを分割して対応していますが、そうすると このForms への申請をトリガー(Flow が動き出すきっかけ)としている後続のFlow もその数だけ用意しなければならず、[名前を付けて保存]で複製できるとはいえFlow の中身は共通部分が多いのになんだかなあ、という感じです。

*フロー同士の連携(あるフローの終了を別のフローのトリガーにする) こともできなくはないようなのですが(Webhookを使えばいいのか?)、せっかくノンコード・ローコードを謳っているのだから そこはオブジェクト指向を見習って一部のFlow をメソッド(共通部品)化するとか、Flow の中で別のFlow を呼び出せるようにするとか、していただきたいものです・・・って書きながら「もしかしてカスタムフロー(アクション)で実現できたりするのか?! っていうかこういう時のためのもの?!」という思いが頭をよぎりました。調べてみよう。

それからアクセス制御ができないのも不便というか、困るケースがあると思います。現状テナント内のFormsが使えるユーザー(全員)か匿名アクセス許可の2択しかありません。「総務部向け」「大阪事業所限定」「マネージャーのみ」みたいに回答(申請) できる人を絞りたいことって結構あると思うのですが・・・

「この人は申請していい人か?」というのはもちろん後で申請見て判断できるとはいえ、ユーザーからしたら「申請できないフォームなんか公開しないでよ もう!」というのも ごもっともかなあ、と。

やはり同じことを考えている人はいるようで、意外に投票数が少なかったですが以下にUser Voiceとして挙がっていましたので賛同された方はぜひVote(投票)してください。

Add access restriction instead of all organization users – Customer Feedback for Microsoft Forms

できないことばかり挙げてしまいましたが、シンプルなフォーム・アンケートであればForms でも十分活用できて便利なので、今後の拡張に期待します。

Forms でのフォームの作り方は

Microsoft Forms を使用してフォームを作成する - Office サポート

に詳しく載っていますし、わりと直感的に作れると思うのでそちらを見ていただければと(全然「実装編」になってない感)

今回気を使ったポイントとしては、申請者によって回答の選択肢を変えたかったので分岐の設定を使っているのですが、その人に関係のない(回答の必要がない)設問は表示されないようにしたかったので、以下の箇所でこの質問でこの選択肢を選んだら次の質問はコレ、と指定しています。

アンケートでよくありますよね、[いいえ]を選んだら即終了、的な

「あ、俺みたいな人間の意見は求められてないんだな」みたいなアレですw

まずフォームの編集画面の右側[…]から[分岐の設定]へ。

image.png

上図の例でいうと、2の設問でその他を選んだら次の3にいかずに終了、としたい場合は

[フォームの末尾] にしておくことで、2の段階では3を表示させないようにすることができます。

あとは今回申請情報をSharePoint リストに記録しているので、リストにどうしても入れておきたい項目はFormsで必須の設問にしておくようにしました。

(でないと空欄だった時にリスト側が必須になっているとFlow がコケてしまうので)

もしくはForms では任意にして空欄を許可しておいて、Flow の中で空欄かチェック→リストには「(空欄)」「未指定」とか入れる、でもいいんですけどね。せっかく全自動を目指しているのに「この項目何入れたらいいんですか?」なんて問い合わせが来たら元も子もないんで。。

実際、「メールアドレスを入れてもらう項目があって、入れたアドレスが間違ってて通知が送れない」なんてことがありました。残念ながら(これもほしい機能の1つですが) Forms 側に入力チェック機能が無いんで、Flow 内で承認依頼を出す前にチェックして不備があったら却下通知、といった考慮も必要かと。

後で自分がラクしたければ事前の仕込みが肝心ですね。。


2. 申請内容の確認・承認(Flow)

続いては承認フローです。

Forms からの申請をトリガーに(検知) して承認フローを開始する、というところは前回ご紹介しました。

ポイントは

1. 承認・却下をどう判定するか

2. 承認してもらうための情報を伝える

あたりかと。

まず1.ですが、これは


Approvals - Connectors | Microsoft Docs


に明記されています。

Response(応答) として承認は[Approve]、却下は[Reject] になりますので、承認依頼の後にこれを判定して処理を分岐させます。

image.png

ここでは条件を「応答がApprove(承認)だったら」としていますので、

後続の[✔ はいの場合]で承認時、[× いいえの場合]で却下時のアクションを定義しています。

例えば、「申請情報+承認結果をSharePoint リストに新規アイテムとして追加しつつ、申請者には状況(承認 or 却下されました) 通知をする」といった具合です。

なお承認者に指定したユーザーのところにメールで依頼が飛ぶのですが、その際にコメントを添えることができますので、

image.png

却下の場合は特に却下理由をコメントに入れてもらうよう、承認者に伝えておくと良いと思います。

(ただ却下されただけだと、理由が分からず全く同じ申請を出されたり、「何がいけなかったんですか?」なんて問い合わせが来そうですからね)

image.png

↑このように、却下通知メールの本文に 承認者のコメントを入れるようにする

2.の「承認してもらうための情報を伝える」の方は、前後しちゃいましたが承認依頼を送る時の話です。

当然、承認者が承認or却下する材料が必要なので、今回だと申請情報を以下のようにペタペタ貼り付けていくことになります。

([詳細]のところが承認依頼メールの本文に入ります)

image.png

んでこれはあまりイケてない書き方でして、気を付けないとFlowでは見た目改行してても届いたメールではそれが1行になって見づらくなってたりします。

申請が多いと承認者は大変ですよね。自分だけラクしてたんじゃ喜ばれませんから、ここはやはり気遣いも必要かな、と。

そこで、このQiitaで記事を書く時にも使えるMarkdown がこの[詳細]でも使えますので、以下を参考に見やすいレイアウトを工夫してみてください。

(今回のように情報を羅列するならテーブル形式が良いのかな)


Markdown を使用して Microsoft Flow の承認を書式設定する | Microsoft Docs


Markdown はよく知らなかったのですが、改行にもお作法があるんですね。

image.png

気遣いと言えばもう1つ、いくら受信したメールで承認できるとはいえ(それだけでも便利だと思いますが) 一度に沢山来ると捌くの大変・・・という時は

Flow ポータル を見に行くと溜まっている承認依頼がまとめて表示されていて そこで承認or却下もできますので、承認者の方に案内してあげると良いかもしれません。

image.png

ついでに、承認者多忙・出張外出多しでなかなか承認下りず待たされる・・・というワークフローあるあるも考慮すると、会社携帯にモバイルのFlowアプリをぜひ入れてもらってですね、出先でも申請内容チェックして承認できたらかなり業務のスピード上がるんじゃないでしょうか。

出先じゃ判断つかないからムリ!とか言われたら結局止まっちゃいますから、そんな時のため?なのか[再割り当て]なんてボタンもありますね。よく考えられているな、と思いました。

これで「俺の代わりに承認しといて!」なんてこともできる(と思います、まだ試していませんが・・・)

image.png

あとこれはFlow 全般に言えることですが、アップデートが激しいので、気づいたら利用しているアクションが古くて 実はコケてたり、期待通りに動作しなくなってたりするので要注意です。

今回利用していたApprovals(承認)コネクタも、いつの間にかV2が出てV1がDEPRECATED(廃止) になってました。

image.png

廃止されてなくても、ちょっとした仕様変更の影響でいきなり動作しなくなったりもするので、そんな時はまず動かない部分(アクション)を一度消して、全く同じように作ってみましょう。それだけで動いたりしますので。

MSのサポートに尋ねた時も、「心当たりがなければ試してみて」と案内されるので、実際有効な方法なのでしょうね。

反対に、アップデートのおかげでできることが増えて超便利!今までの苦労は何だったんだ!という場合もあるので、ここは面倒でも「どこが変わった?」をチェックしておくことをオススメします。



申請情報の記録・ステータス管理

また余談というか、次に入る前に申請情報・ステータスの記録について。

今回はこのようにSharePoint Online のリストに書き込んでいます。

image.png

リストは予め用意しておく必要があります。リスト側で定義した「列が必須かどうか」、「データ型(文字列・日時・選択肢) 」を意識しておかないと書き込みに失敗するので注意しましょう。

また書き込む際、Forms から来た申請情報そのままだと都合が悪い場合は

ここで加工することができます(上図で[fx]と表示されている箇所)

リスト項目の入力欄をクリックすると、右側にポップアップが出ますので

[式]の方を選ぶと使える関数(処理・操作)の候補が出てきます。

image.png

Excel の関数に慣れている方は、似たような感じなのでそんなに違和感ないと思います。関数指定すればパラメーターのヒントも出ますしね。

例えば今回は申請時にアルファベットで入れてもらった姓名からID(アカウント名)を生成するのに文字列を連結する関数を使いました。

concat(variables('UserID'),'@',variables('Domain'))

メールアドレスを決める時、ドメインが固定(分かりきっている)ならユーザーに指定してもらう必要もありませんし、入れてもらうとスペルミスの恐れもあるので、必要最低限の情報で済ませるとエラーチャックも少なくて済みますよね。

variables(xx) というのはFlow の中で定義した変数(加工した値・情報をFlow の実行中にとっておくための「箱」)です。

上記の式のように直接書いてもいいのですが、さっき↑の図で[式]を選んだ箇所の左、[動的なコンテンツ]を式の入力中にクリックすればForms から取得した情報などを式の中に埋め込めるので記法を覚えなくても使えて便利です。

(式とコンテンツを行ったり来たりするのが ちと面倒ですが)

用意されている関数のリファレンスは以下にありますので、「こんなことできないかな?」と思ったら探してみてください。


ワークフロー定義言語の関数リファレンス - Azure Logic Apps | Microsoft Docs


ステータス管理については、SharePoint リストに追加したアイテム(項目)

はFlowの中で取得できますので、

・申請されたらリストにアイテムを追加

・承認されたらそのアイテムのステータスを[承認済み]とする

・処理が終わったらそのアイテムのステータスを[対応済み]とする

のようにアイテムを都度書き換えて行けば、時間のかかる処理も「いまどの状態?」が分かりますし、もしFlowが途中でコケたら「どこまで終わってる?」が見えます。


3. 承認後の処理(Azure Automation)

最後の処理、ここが本題というか肝心の実際に管理者がやるところですね。

Office365向けのシステムなのにAzureの機能を使うというのは若干反則?な気もしますが、Office365向け「だからこそ」、PowerShellが分かれば利用できるので

「Graph APIとかよく分からん!」という方も取り入れやすいんじゃないかと思います。


Azure Automation のRunbook (PowerShell スクリプト) を用意する

Flow からPowerShellを実行するために、Azure Automation のRunbook を作成します。

そのためにまずAutomation アカウントというものを作成しておきましょう。


Azure クイックスタート - Azure Automation アカウントを作成する | Microsoft Docs


なお前置きとして、今回はオンプレミスのActive Directory にユーザーを作成するために Hybrid Runbook Worker という機能を使います。

Hybrid Runbook Worker は文字通りハイブリッド(Azure=クラウドとオンプレミス) 環境でオンプレミス側で処理を実行させることができる仕組みです。

概要はこちらに


Azure Automation の Hybrid Runbook Worker | Microsoft Docs


これを使えばもうサーバーにリモート接続したり、リモートPowerShellを実行したりしなくても済むので、何も今回のようにFlow から呼び出さなくたって大いに活用すべき機能ですが、このHybrid Runbook Worker を利用するためにはエージェントをオンプレのサーバーに入れておく必要があります。

エージェントを入れる手順 も公開されているので、そちらをご参照ください。

※ちなみにオンプレだのハイブリッドだの言ってますが、実は今回Azure の仮想マシンに対して使っています。エージェントを介して通信するという点では結局Azure上の仮想マシンだってAzureのサービスから見たらオンプレのサーバーと同じ位置づけなので、同様に使えます。

むしろAzureの仮想マシンだとこのインストールを大幅に簡素化(というかお任せ)できる裏ワザがあるのですが、紙面(じゃなくて時間)の都合でまた別途ご紹介したいと思います。

Advent Calendar なのにもう日付変わっちゃった・・・

Hybrid Runbook Worker のエージェントをサーバーに入れたら、後はそのサーバーで実行したい処理をRunbook に定義します。

Runbook の作り方、実行の仕方はココが分かりやすいです。


Azure クイックスタート - Azure Automation Runbook を作成する | Microsoft Docs


Hello World の出し方からAzure ポータル上でのテスト、結果(出力)の確認までひと通り載っていますので、Runbook を触ったことのない方でもすぐに覚えられると思います。

そしてこのページの[Runbook を実行する]の画面にもありますが、

実行時にHybrid Runbook Worker を実行対象として選択できるので

Runbook で書いたPowerShell スクリプトをオンプレサーバーに対して実行する(というか送り込む)ことができるのです。

ここまでがRunbook を用意するまでの流れで、後はHello World の代わりに実行したいスクリプトを編集ウィンドウに書けば良いのです。

(オンプレのADにユーザーを作りたければ、New-ADUser コマンドレット、といったように)

あとは処理によりますが、実行アカウント(の権限)が必要ならばAutomationアカウントの設定で資格情報を保存しておいて、

image.png

Hybrid Runbook Worker グループ(同じWorkerを持つサーバーの集まり)の設定で実行時の資格情報を指定できますよ。

image.png

【ここでお詫び】

シナリオとしてご紹介していた、ADにユーザー作成(してOffice365に同期された)後の処理(ライセンス付与、MFA有効化、グループへのメンバー追加など)はAutomationの動作検証がまだ済んでいないので、後日追記させていただきます。

ホントはここまでできてこその効率化・自動化なのですが、Advent Calendar としては時間切れになってしまい申し訳ないです。



Flow からAzure Automation を利用する

さて、Azure Automation (Runbook) の用意ができたらいよいよそれをFlow から呼び出すのですが、私が試した限りではFlowからRunbook を実行するには事前に「サブスクリプションとAzure Active Directory ディレクトリの関連付け」というのをやらなければなりませんでした。

(これをしないとFlow からAzure 環境に接続してもサブスクリプションの情報が取得できなかったのです)

Flowの作成者(兼Office365の全体管理者)アカウントをAzureサブスクリプションの所有者(いわば神様、何でもできる権限のある人)に加えてあげてもダメだったので、ちょっと解せないところはありますが・・・

ディレクトリ関連付けの手順自体はわりと単純です。


既存の Azure サブスクリプションを Azure Active Directory ディレクトリのテナントに追加する方法 | Microsoft Docs


Azure サブスクリプションとAzure Active Directory のディレクトリの関係がよう分らん、という人もこのページを読めば少し整理できるかもしれませんので ご一読ください。


※また余談・・・

これは後で気付いたのですが、Flow を作成したアカウントでAzure に接続するのではなくAutomation側でサービスプリンシパルを用意しておけばディレクトリの関連付けをしなくても済んだかもです。

試す機会があればまた書きたいと思いますが、ご参考までにサービスプリンシパルを使って接続する時はこのようにします。

image.png

image.png

※上記のディレクトリの関連付けをしておけば、ここで普通に[サインイン]で接続して終わりです

image.png

↑に何を入れればいいの?ですが、まずこちらを参考にAutomation 用の実行アカウントというものを作ります。


Azure Automation の実行アカウントを管理する | Microsoft Docs


これに沿って実行アカウントを作成すると、Automation用のアプリケーションというものがAzure Active Directory に自動登録されるので、そのアプリの設定画面で必要な情報は取得・生成できます。

image.png

image.png

※FlowからAzure Automationに接続する際に求められる[クライアントID]はこのアプリケーションIDになります。

そしてクライアント シークレットは上図の[設定]から以下[キー]をクリックして、

image.png

説明(何用のキーなのか分かるような名前が良いでしょう)と期間(有効期限)を指定して保存すると、

image.png

キーが生成されるのでコピーして[クライアント シークレット]に貼り付けます。

警告の通り、二度と表示されないので控えておきましょう(ただし漏れないよう厳重に。管理者パスワードと同じ扱いです。忘れたらまたキーを生成すればいいだけですが、使っている箇所が多いと再入力が面倒ですからね・・・)

image.png

最後のテナントIDはAzure Active Directory のプロパティで確認できます(ここでは[ディレクトリID]となっています。ややこしいですが、サブスクリプションIDではないので注意!)

image.png


Flowから作成したジョブ(=実行したスクリプト)は完了まで待機する設定があるので、完了後の結果を判定したり出力を受け取ることが簡単にできます。

image.png

ユーザー作成して、Office365のプロビジョニングまで終わったら申請者や承認者にメール通知、までFlowの中で全部できたら、管理業務もだいぶ楽になると思いませんか?(アカウント台帳もついでに作れちゃうし!)

このような業務を行う頻度や回数が多い人ほど、仕込むことで効果が出るはずですよ。



さいごに

今後の課題・改善点や運用上のポイントを挙げるとすれば、まず


  • フローの中で単発で実行したい処理を別のフローで作っておく

Flowを作り込んで長くなってしまったが故に、デバッグ(テスト)しづらくなると感じてます。この処理ちゃんと動いてんのか?とか、全部流す必要ないんだけど途中のここだけ使いたい、みたいなシーンがあるので。

やはりこうなるとフロー同士の連携、フローを束ねる機能がほしいなあ・・・

あとは


  • ノンコード・ローコードと言えども例外・エラーハンドリングは大事!!

Flowを使っている方はもう分かっているとは思いますが、前段のアクション結果を踏まえて後続の処理を決める(ための適切な条件分岐) もそうですし、意図せず途中でコケた時のことも想定しておかないと、ですね。

実際には正常に完了していないのにユーザーに通知が行っちゃった日にはもう・・・問い合わせやフォローが減らなかったら、せっかくFlowを作った効果が薄くなっちゃいますからねえ。。


実装編といいつつも、あまり細かい手順に触れられていない割りに長々と、ダラダラ書いてしまった上に一部未完成、と反省していますが、とにかく目を通してくださり、ありがとうございました。

これを読んでくださった方の運用自動化・効率化のヒントになれば幸いです。

「こうしたらもっと簡単にできるよ」「できないって書いてるけど実はできるよ」なんてのがありましたら、胸の内に秘めておかずにドヤ顔でwぜひコメント・ご意見・ご指摘・感想いただけると嬉しいです。

自分でしょい込んだ肩の荷を下ろしたところでw このへんで。