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

この記事は[Office 365 Advent Calendar 2017](https://adventar.org/calendars/2585) に参加(12/19)しています。


今回は「Office365で(ほぼ)全自動ユーザー登録システムを作ってみた」ということで
できるだけ人手(特に管理者の)をかけずに「Office365にユーザーを登録し使えるようにする」ところまでを自動化してみたいと思います。

…といっても、これを書いた2017/12/19 時点では未実装・未検証の部分が多いのですが
「こうすりゃできそう」というアイデアだけでも参考になればと思います。
作っていてハマったり、考慮が必要なポイントも極力書いておきます。
完成してまた色々分かったらアップデートします。

#概要(流れ)

まずシステムの概要・流れを説明します。今回作るのは、

1. Office365を使い始めたいユーザーが、自分の情報(氏名など)を申請する
2. 管理者は、申請情報を確認し問題がなければ承認する
3. 承認されたら、申請情報を記録して、ユーザー登録やライセンス付与などOffice365を使い始めるのに必要な処理を(自動で)行う
4. 処理が終わったら、ユーザー(申請者)に案内メールを送る

というものです。

実現手段は、コストも考慮して「極力Office365で完結すること」を念頭に置いています。

#前提条件

- Office365のテナントがあり、ライセンスを保有していること

(今回使用しているOffice365のサービスはE1で(ほぼ)実現できます)

| 処理 | 実現手段 |
|:-:|:---------------------------------------------|
|申請|Forms|
|承認|Flow|
|申請情報の記録|SharePoint Online (リスト)|
|ユーザー登録|Azure Automation
ライセンス付与 |Azure Automation|
|案内メール   |Exchange Online|

    *Azure Automation は別途Azureのサブスクリプションが必要です
<br>

- オンプレミスのADがあり、Office365とディレクトリ同期済みであること

ADと同期していなくても今回やりたいこと(申請～承認～登録)は実現できます。むしろその方がもっとシンプルにできます。ADと同期してるなら、「わざわざユーザーに申請してもらう必要ないじゃん！」と思う方もいるかもしれません。ADに登録されているユーザーとOffice365を使う人がイコールであれば、それで済むと思います。
(もしくは同期対象をOUなどで分けていてOffice365を使う人が明確になっていれば)

今回は、
・ Office365を使う人が誰だか分からない(使いたい人は使ってね、というスタンス)
かつ、
・ その人がADに登録されていない(新規入社とか)
というケースを前提にしています。既にOffice365に登録されているユーザーに対して、「申請ベースで何か処理ができればいいよ」という場合はそこだけ参考にしていただければと。

では順に見ていきましょう。

## 1. Office365を使いたいユーザーが、自分の情報(氏名など)を申請する

申請の仕組みはMicrosoft Formsを使います。Formsはアンケートやクイズなどを作成するためのサービスです。

[Microsoft Forms とは - Office サポート](https://support.office.com/ja-jp/forms)

使っていないので比較はできませんが、Survey Monkeyの簡易版と思っていただければ。
SharePoint Online にもアンケートアプリやExcelアンケートの機能が以前からありますが、
もっと簡単で、エンドユーザーでも作りやすい印象です。

特徴を挙げると、
 
- 組織(テナント)内のユーザー限定、匿名アクセスどちらにするか、フォームごとに選択できるので
社外(お客様)アンケートなどにも活用できる
- モバイルからでも回答でき(回答する側はアプリ不要、UIも勝手にモバイル向け表示にしてくれる)、回答の内容や集計結果は自動で行ってくれる。ブラウザだけでなくExcelにエクスポートもできるので、その後の分析もしやすい
- 選択や段階評価、日付(カレンダー)指定の設問も用意されている
- 分岐(前の設問の回答により次の設問を変える)も可能

という感じです。
その他の機能や制限事項はこちらに記載があります。
[Microsoft Forms についてよく寄せられる質問 - Office サポート](https://support.office.com/ja-jp/article/Microsoft-Forms-%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6%e3%82%88%e3%81%8f%e5%af%84%e3%81%9b%e3%82%89%e3%82%8c%e3%82%8b%e8%b3%aa%e5%95%8f-495c4242-6102-40a0-add8-df05ed6af61c?ui=ja-JP&rs=ja-JP&ad=JP)

フォームの作り方はそれほど難しくありませんので、ここでは詳しく説明しません。
今回のケースでは、姓名・部署・役職・電話番号などをユーザー(申請者)に入力してもらうことになります。
姓名など、ユーザー登録に必要な情報だけは[必須]にしておきます。
(設問ごとに必須か任意かを指定できます)
部署なども必ず入れてほしい場合は[必須]にして、かつ全角と半角の違いなどによる非統一を避けたければ、入力ではなく部署一覧を事前に用意して選択方式にした方が集計の際に便利でしょう。

申請する人はまだOffice365に ユーザー登録されていない、という前提なので
匿名アクセスを許可する設定にしています。
もし、既にOffice365 に登録されているユーザーからの申請に対して何か処理をしたいのであれば、認証が必要なようにしておけば その人のプロパティが取得できますから
例えばその人の上司(として登録されている人)に承認依頼メールを送る、といったことも可能ですね。

ちなみに、同姓同名を考慮して、ユーザー登録時にセットするID(UPN)には
乱数をつけることにします(乱数の生成方法については後日追記します)。

上記のページと、実際の画面を見ながら試行錯誤すればさほど難しくないと思いますが
PowerShellコマンドが用意されていないので、回答の選択肢が多いとしんどいのが難点です。
※アンケートによくある、「出身地は？」で47都道府県を選ばせるような設問は
(コピペするにしても)１つ１つ入れていく必要があるので、手間がかかります。
しかも、選択肢や分岐の数が多いと上限値に引っかかり、減らさないと保存できないケースがあります。
(保存は自動でしてくれますが、画面右上にしれっとエラーメッセージが出ます。しかも何が原因か分からないという…)

[Microsoft Forms でよく本サポートに寄せられるお問い合わせ – Office Support Team Blog JAPAN](https://blogs.technet.microsoft.com/officesupportjp/2017/09/05/what-is-forms/)
に記載されていますが、
>1 つのコンテンツの設問数、および選択肢に対する 4KB の制限

という謎の？仕様によるもので、実際作っていたフォームでハマりました。

>この 4KB 制限を取り除く修正を実施することを計画していますので、
>将来的には本制限はなくなる予定です

ということですが・・・

## 2. 管理者は、申請情報を確認し問題無ければ承認する

承認の仕組みはFlowを使います。
[プロセスとタスクの自動化 | Microsoft Flow](https://flow.microsoft.com/ja-jp/)

このFlow を使うと、Exchange Online や SharePoint Online などのOffice365 のサービスだけでなく、Twitter やGoogle といった非MSアプリケーションとの連携も可能なので
使い道は無数にあると思います。
こちらも使ったことがないですが、MS版 IFTTT といったところかと。

例えば、

- メールの添付ファイルをOneDrive for Business に保存する
- SharePoint Online にアイテムがアップロードされたら承認依頼メールを送付する

など、テンプレートが多数用意されているので
自分がやりたいことにマッチするものがあれば、接続情報(アカウント)や条件を指定してあげるだけで簡単にワークフローのようなものが作れます。
SharePoint Online 組み込みの標準ワークフローでは実現できないので3rd パーティーのアドオンを入れている、という話はよく聞きますが、もしかしたらそれもFlowで実現できるかもしれません。
今回このテーマにしたのも、このFlowを使ったらできるのでは？と思ったのがきっかけです。

今回使用するテンプレートはこちらです。
[承認を得るためにフォームの回答を送信する | Microsoft Flow](https://flow.microsoft.com/ja-jp/galleries/public/templates/4071c6b040c611e7ad68c1c80e905297/%E6%89%BF%E8%AA%8D%E3%82%92%E5%BE%97%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AE%E5%9B%9E%E7%AD%94%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B/)

１．でユーザーから自身の情報を申請してもらう訳ですが、間違いもあるでしょうし
「あなたのところの部署はライセンス購入してないから申請しても使えないよ」というケースもあるかと思います。
そこで、「申請内容をチェックし、OKならアカウント登録に進む」というプロセスにしていますが、同じような流れであれば以降の処理は何もアカウント登録に限らず、何でもいいわけです。

このテンプレートには、"Approvals" というコネクタが含まれていて、前段の結果(今回はForms からの申請)に対し「承認 or 却下」を特定の誰かに求めるアクションを定義できるのです。
コネクタ＝「Flowで利用できるアプリケーション」になりますので、ピッタリのテンプレートが見つからない場合は、コネクタの中から探してみてください。
コネクタの一覧は[こちら](https://flow.microsoft.com/ja-jp/connectors/)にあります。

テンプレートを使ってフローを作るには、目的のテンプレートのページで、[このテンプレートを使用]をクリックします。そしてフローの編集画面で、以下の処理を作っていくわけです。

- Forms に申請があったら回答の内容を取得する(Flow の開始点をトリガーと呼びます。今回は申請が行われたタイミングでフローが動き出します)
- 取得した内容を必要に応じて加工し、管理者などに承認依頼メールを送る
- 承認依頼メールへのアクションを判定する(承認 or 却下)
- 判定結果に応じてそれぞれの処理を行う(承認されたら、申請情報をSharePoint Online のリストに追加する

といったように。

Flow もわりと直感的に作れるのですが、作りこんでいくと結構落とし穴や「こういう時どうしたらいいの？」という時もあります。今回で言えば、

- Forms の回答内容はどうやって取得したらいいの？チェックできるの？
- 処理が途中でエラーになったら どうしたらいいの？
- 承認依頼メールの中に申請情報って記載できる？
- 元のデータに何かを足したり、条件によって変えたりできるの？

など。
後述といいながら、乱数生成のやり方など時間の都合で細かい手順まで書けませんでしたので、その辺りは後日追加していきます。

Flow を使う上での注意点・考慮事項としては
フローの実行間隔(頻度)が固定で変更できなかったり実行できる回数に上限があったりするので
実際の運用でその辺りが問題にならないかは事前に確認しておいた方がよいですね。
[Approvals - Connectors | Microsoft Docs](https://docs.microsoft.com/ja-jp/connectors/approvals/)
今回使用した承認依頼メールのコネクタに関する仕様です。ページ左側に各コネクタのリンクがあります。

ライセンスによる違いはこちら
[プラン | Microsoft Flow](https://japan.flow.microsoft.com/ja-jp/pricing/#plan-feature-table)

## 3. 承認されたら、申請情報を記録して、ユーザー登録やライセンス付与などOffice365を使い始めるのに必要な処理を(自動で)行う

### 申請情報を記録する

２．で承認依頼メールを送り、管理者が承認したら申請情報を記録します。
承認したということは申請に問題がなかったということなので、そのまま登録に進んでもいいのですが
現状Formsでは申請(回答)者に内容を送る機能がないこともあり、どんな内容だったかを記録することにしました。

記録先はSharePoint Online のリストを使用しています。Forms 同様、リストの中身はExcel に落とせるので
リストのデータ＝AD(とOffice365)に登録されているユーザー情報、になっていれば
これが台帳になりますね。
(ADやOffice365のユーザー一覧をエクスポートするよりは台帳を加工する手間は少ないかと)

また、リストに記録するタイミングを「承認後」ではなく「申請後」にすることで
承認・却下のステータス確認・管理にも使えます。

実際、申請が短期間に多数押し寄せるようなケースでは、「1件1件来たメールを開いて承認なんかしてられるかい！」というケースもあるでしょうから
承認処理自体もリスト上で行ってしまうという手もあります。
(この場合、承認作業はメール上だけでなくFlowの管理画面でもできるので、まとめて確認・承認はそちらでもできますが)

なお当然？ですがSharePoint Online のリストは事前に用意しておく必要があります。
さすがに自動でマッピングしてくれるわけではないので、「Forms のこの設問に対する回答はリストのこの項目(列)に入れてね」というところはフロー内で自分で定義してあげる必要があります。
ですので、フローを作る人が分かっていればForms の設問とリストの列名は一致している必要はありません。


### ユーザー登録やライセンス付与などの処理を(自動で)行う

冒頭にも書きましたが、Active Directoryとのディレクトリ同期が必要ないなど
Office365 に直接ユーザー登録を行う場合、ここでAzure Active Directory (Azure AD) のコネクタとつなげてあげることでユーザー作成ができます。

一方で、ディレクトリ同期を行っていてユーザー登録をActive Directory から行っている場合は少々面倒です。
一部のコネクタはオンプレミス環境(SQL Server など)とも接続できるのですが、残念ながら現時点ではActive Directory との連携は未対応。

そこで登場するのが、Azure Automationです。
[Azure Automation の概要 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/automation/automation-intro)

Azure Automation を使うと、PowerShell のコマンドレットをAzure上で実行することができます。Azure上で動くバッチサーバーのようなもので、一般的な用途としてはAzure のリソース(仮想マシンなど)に対する処理の自動化が多いと思いますが、Hybrid Runbook Worker を使用することで何とオンプレミスのサーバーに対しても処理が行えるのです。

[Azure Automation の Windows Hybrid Runbook Worker | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/automation/automation-windows-hrw-install)

オンプレミスのドメインコントローラー(か、ADと通信可能なサーバー)にこのHybrid Runbook Worker を入れておけば、Active Directory にユーザーを追加したりグループのメンバーに追加したりするPowerShell スクリプトが実行でき(るはず)、そのスクリプトをキックするのがFlowというわけです。
ここが(ほぼ)自動化システムを作る上でのキモなのですが、まだ未着手です。

Flow のコネクタにはAzure Automation もありますから、前述のフロー内で
このスクリプトをキックするジョブを登録してやれば、一連の流れの中でADへのユーザー登録までクラウド上でできることになります。素晴らしい。

そしてもう１つ、この(ほぼ)全自動システムのキモとなるのが
「Office365 ユーザーに対する操作」
です。
これもコネクタがあるのですが、更新できるプロパティ(部署などの属性)が決まっているため、Office365 のユーザーに対して

- ライセンスを割り当てる(同期しても自動で割り当ててくれる訳ではないので)
- 多要素認証を有効化する

といった処理を行うことはできません。
でもせっかくここまで来たら、ユーザーが使える状態にするところまで自動化したいですよね。
ここも恐らくはAzure Automation を使うことになるでしょう。検証できましたら追記したいと思います。
それから、この操作は「ディレクトリ同期によりAD → Office365に作られたユーザー」に対して行うので、Office365 にそのユーザーが作られていることをフローの中で確認する必要があります。
ディレクトリ同期の実行間隔が30分であれば、「ADにユーザーを登録する処理を実行後、例えば30＋α 分待機し、登録が終わっていればライセンスを割り当てる」のようにできればベストですね。

## 4. 処理が終わったら、ユーザー(申請者)に案内メールを送る

これはFlow を使って簡単にできます。Exchange Online (Outlook)のコネクタがありますので、処理の終了後 ユーザーにメールを送ります。
Office365 管理センター(ポータル) から直接ユーザーを登録すると、サインインID とランダムな初期パスワードの記載されたメールが管理者に届きますが、そのイメージです。

定型で編集できない自動通知のテンプレートよりも、ポータルサイト(SharePoint Online)のURLやマニュアルのリンクなど情報を加えられる分、案内としては親切にできるでしょう。

## さいごに

Advent Calendar なのに日付が変わってしまったので(笑)、今日はここまでです。
説明(というか能書き)ばかりで具体的な実装の手順が全然書けていないので:sweat:
「具体的にどう実現すんのよ⁈」というところは追って加筆していきます:muscle_tone2:


ご参考になれば幸いです:santa_tone2: