Office 365とかSaaSの自由帳

Office 365の話とかSaaSについてとかいろいろ書きたいと思います。なんだかんだ備忘録になると思います。

あとどのくらい使える?SharePoint Onlineの容量を確認する

今日は簡単なTipsを備忘録がてら書きます。

Office 365/Microsoft 365のSharePoint Onlineの全体の容量を確認する方法ってとても簡単なんです。
オンプレミスの時代とは異なり、容量を超過することはあまり多くないとは思いますが、利用状況を確認しておく上でも知っておいた方が良いと思いますので、個人の備忘録としても書いておきます。
※2020年5月時点での情報です

全体の容量の考え方について

2020年5月現在ですと、基本容量の1TB+契約ユーザー数 * 10GBが全体で利用可能な容量の計算方法です。
例えば50ユーザーで契約した場合下記のような計算となります。
1TB(基本容量) + 50 * 10GB = 約1.5TB

なお、One Driveは各ユーザー1TB割り当てられるので、上記の容量とは別枠です。

また、容量が足りなくなった場合は追加購入が可能です。
価格については管理ポータルから確認可能ですので、詳細については下記の公式ページをご確認ください。
docs.microsoft.com

確認方法

では早速確認方法。

1. 管理者権限でログインし、Microsoft 365管理センターを開きます。
https://admin.microsoft.com/Adminportal#/homepage


2. 画面左メニューの管理センターからSharePoint管理センターをクリックします。
※メニューに表示されていない場合は、「すべてを表示」をクリックしてメニューを展開してください
f:id:takeru55555:20200527153628p:plain


3. SharePoint管理センターが表示されますので、画面左からアクティブなサイトをクリックします
f:id:takeru55555:20200527153819p:plain


4.画面右上に現在利用可能な容量と現在の利用状況が表示されます。
f:id:takeru55555:20200527155138p:plain

また、各サイトコレクションの一覧が容量と共に表示されます。
f:id:takeru55555:20200527154201p:plain

この画面にて全体の利用状況および各サイトコレクションの利用状況を確認することができます。

なお、全体の容量を圧迫することはあまり多くないとは考えております。
ただし、下記のようなケースですと容量を多く使用してしまうことがあるかもしれません。
・大きな容量のファイルをたくさん保管している
・ドキュメントライブラリのバージョン管理が青天井

そうならないようにサイトコレクション作成時にクォータ(容量制限)を設定したり、バージョン管理の設定をしてあげたりなどが必要かなと考えております。
(とはいえ多くの場合容量を圧迫するまで使うことは無いと思いますが・・)

ではまた次回。

Azure AD Connect クラウド プロビジョニングのマルチフォレスト同期を試す!

本日は前回同様Azure AD Connect クラウド プロビジョニングについて書きたいと思います。

Azure AD Connect クラウド プロビジョニングでは、マルチフォレスト同期が非常に簡単にできるようになっていたので、備忘録もかねてまとめておきます。

Azure AD Connect クラウド プロビジョニングのマルチフォレスト同期

Azure AD Connect クラウド プロビジョニングの強みとして、非常に容易にマルチフォレスト同期が可能となったということが挙げられます。Azure AD Connectでは、Azure AD Connectがインストールされているサーバーが各フォレストのドメインコントローラーと接続できることという条件がありましたが、Azure AD Connect クラウド プロビジョニングはネットワーク的に分断されていても各フォレストにエージェントをインストールすることで一つのAzure ADテナントに対して同期が可能になっています。
f:id:takeru55555:20200114201250p:plain

これは従来のAzure AD Connectに比べると非常に画期的なことで、会社のM&Aなどでネットワークが分断されている別フォレストのオブジェクトを同一のAzure ADテナントを使いたい場合などに威力を発揮します。
今まではネットワークを繋げるという作業が必要でしたが、そこには非常に時間がかかる場合も多く、この構成が容易にできることになったのは非常に大きなメリットだと感じております。
また、Azure AD ConnectとAzure AD Connect クラウド プロビジョニングの混在環境もサポートされているので、すでにAzure AD Connectをお使いの企業が別フォレストを同期する際にAzure AD Connect クラウド プロビジョニングを利用するといったことも可能となります。

Azure AD Connect クラウド プロビジョニングの構成

構成方法については前回の記事をご覧いただければと思います。
takeru0620.hatenablog.com

この記事と同様に特別なことは必要なく、別フォレストのADにエージェントをインストール→構成するだけです。
下記画像のようにAzureポータル場で複数フォレストから同期が構成されていることがわかります。
f:id:takeru55555:20200114202109p:plain

また、Azure AD Connectと同様ユニークな属性としてObjectID/ms-DS-ConsistencyGuidとUserPrincipalNameのようで、同一のUserPrincipalNameをもつユーザーをそれぞれに作成した場合、片方の同期がエラーとなりました。
ちなみにこのような同期エラーは下記のようにメールでレポートされます。
f:id:takeru55555:20200114202655p:plain

なお、SourceAnchorはms-DS-ConsistencyGuidが使われるとの記載があるのですが、詳細まで調査しきれていませんが、実態としてはObjectIDが使用されているようでした。
グループ会社が別フォレスを利用していて、かつグローバルでユニークなUserPrincipalNameやメールアドレスを持つ環境ではフォレスト間のユーザーの移動がある場合がありますので、ここはもう少し調査が必要ですね。

まとめ

1フォレストの際と同様非常に簡単に同期の構成をすることができました。
オンプレミスのサーバーにインストールするエージェントではあるのですが、実態はクラウド側で動作するので、オンプレミスの仕組みもどんどんクラウドに統合されている流れだと感じました。
まだプレビューですので、今後のGAに期待ですね。

ではまた次回。

新機能!Azure AD Connect クラウド プロビジョニングを試す

2020年も一週間が経とうとしております。今年もどうぞよろしくお願いいたします。

今日久々に検証のためにADを構築したのですが、実家にあるスーパーファミコンで遊んだみたいな感覚で非常に楽しかったです。
スーパーマリオワールドにハマってたことを思い出します。

さて本日はAzure AD Connect クラウド プロビジョニングを試してみたので、備忘録もかねてブログに書きます。
なお、現時点でまだプレビューですので、今後動作が変更になる可能性があることをご了承ください。

Azure AD Connect クラウド プロビジョニングとは

Azure AD Connectと同様、オンプレミスのActive DirectoryからAzure ADに対してオブジェクト情報を同期するためのもので、軽量のエージェントをオンプレミスのサーバーにインストールし、利用するものとなります。
AzureAD Connectよりも簡易的なもので、デバイス情報の同期ができなかったり、属性情報でのフィルタリングができなかったりとまだまだ改善の余地はありそうです。
詳しくは下記の記事を参照ください。
docs.microsoft.com


できることでいうと、Azure AD Connectの方がよく思えるのですが、Azure AD Connect クラウド プロビジョニングには一つ強力な強みがあり、ネットワークが分断されたフォレストからの同期が可能となっております。従来のAzure AD Connectではマルチフォレスト構成に対応できていたものの、全てのフォレストに通信できなくてはいけない、という要件があったのに対し、Azure AD Connect クラウド プロビジョニングはネットワークが分断されていても一つのAzure ADに同期が可能になっている模様です。
この方法であれば、M&Aを頻繁にし複雑になってしまったAD環境を持つエンタープライズ企業でも対応できそうです。ちなみにこの同期手法はOktaのAD同期の方法と似ていて、Azure ADが苦手としていた部分ですので、今後のIdaaS市場がどうなっていくか楽しみにですね。
この部分についてはまだ検証ができておりませんので、検証ができ次第またまとめます。

Azure AD Connect クラウド プロビジョニングを試す

基本的には下記の記事通り進めれば問題なくインストールできます。
docs.microsoft.com

私が試した環境は下記のようになっております。

  • OS:Windows Server 2019
  • フォレストの機能レベル:Windows Server 2016
  • Azure ADのライセンス:Free

上記の通り、Azure AD Freeで問題なく構成できるか試してみたかったのもあり、365の環境ではないAzure ADを利用してます。

手順を下記の通りです。
※言語設定が英語になっているため英語で表示されております。日本語は上記の記事からご確認ください。

1. AzureポータルからAzure ADのAzure AD Connectメニューを表示し、「Manage provisioning(Preview)」をクリック
f:id:takeru55555:20200107212054p:plain

2.「Download agent」でエージェントをダウンロードし実行
f:id:takeru55555:20200107212232p:plain

3. 必要情報を入力 ※基本は次へ、次へで問題ないです
ライセンス条項の同意
f:id:takeru55555:20200107212244p:plain

資格情報の入力 ※Azure ADのグローバル管理者を設定してください
f:id:takeru55555:20200107212339p:plain

フォレストを追加
※NETBOISドメイン\ユーザー名の形式で設定しました
※ちなみにどのドメインコントローラーから情報を取得するかを選択可能なようです。
f:id:takeru55555:20200107212359p:plain

f:id:takeru55555:20200107212410p:plain

構成完了
f:id:takeru55555:20200107212549p:plain

4. 再度1の画面に戻り「Manage provisioning(Preview)」をクリック
f:id:takeru55555:20200107212054p:plain

5.「New Configuration」をクリック

6. DeployをEnableにし、その他必要情報を入力し、「save」をクリック
f:id:takeru55555:20200107212815p:plain

7. ステータスが「Healthy」になっていることを確認
f:id:takeru55555:20200107213449p:plain

以上で完了です。これで問題なくADの情報を同期することができました。
f:id:takeru55555:20200107213008p:plain

なお、Azureポータルの操作はAzureADのグローバル管理者で実施しなかったところ、6で正常に保存できませんでしたので、ご注意ください。

特定OUのみを同期する

上記はあくまで全ユーザーを同期するための手順です。ただし、実際のユースケースではOU単位や特定のセキュリティグループに所属したユーザーだけ同期したいといった要件が多いかと思います。(むしろ私は全ユーザー同期するという要件は聞いたことないです)
従来のAzure AD Connectであればサーバー側の設定の変更で対応していましたが、Azure AD Connect クラウド プロビジョニングはAzureポータルから同期対象を設定可能です。
設定手順は下記の通りです。

1. AzureポータルからAzure ADのAzure AD Connectメニューを表示し、「Manage provisioning(Preview)」をクリック
f:id:takeru55555:20200107212054p:plain

2. 既存のConfigurationの名前をクリック
f:id:takeru55555:20200107213008p:plain

3.「Scope」の「All usersをクリック」、「Selected organizational units」でOUを「distinguishedName形式」で入力
f:id:takeru55555:20200107213737p:plain

4.「Save」で設定を保存する

設定は以上です。特定OU以外のユーザーは削除済みユーザーとなっております。
f:id:takeru55555:20200107213917p:plain

非常に簡単に構成することができました。なお、OUとセキュリティグループの組み合わせには対応しておらず、どちらかに設定する必要があります。
また、冒頭でも記載の通り、属性でのフィルタリングには対応していないので、こういった要件がある場合はAzure AD Connectを選択する必要がありそうです。
この辺りの細かな仕様は今後のアップデートに期待ですね。

ではまた次回。

SaaS連携!Azure ADのOne Click SSOを試してみた!Dropbox編

どうも、takeru55555(@takeru55555)です。
この記事はOffice 365 Advent Calendar 2019の12/17の回として書かせていただいております。365のAdvent Calendarにはかれこれ四年連続で参加させていただいており、今年も例年通り当日ギリギリに書いております笑
(そしてあまりにも飽きっぽくて毎年この時期にしか記事を書かないことは内緒です。)

私はこのはてなブログの他にnoteも書いているのですが、先日IDのライフサイクルを考慮したSaaS設計が今後より重要性を増してくる、という内容の記事を書かせていただきました。
note.com

今回はこの内容をもう少し技術的な観点でIDaasとしてのAzure ADについて書きたいと考えております。
なお、技術的な話にフォーカスしておりますので、会社の中でSaaSを管理しているSaaSアドミン、もしくはIT部門でIDaasを検討している、もしくは運用している方向けの記事とさせていただければと考えております。

SaaS時代のIDの重要性

先日オーランドで行われたIgniteに行ってきました。たくさんのセッションがあったのですが、その中でもID管理に関連するセッションが多々あり、今後より重要性を増してくる分野なことは明らかです。
その裏付けとして、2022年までにグローバルで活躍するミッドサイズ以上の企業の40%がIDaasを利用するだろうという数値も出ておりました。
私自身も日頃お客様と会話する中で業務部門が主導でSaaSを導入することが増えてきているという話をよく聞きます。時代はSaaS全盛。その流れは必然なのですが、重要なことは、生産性とセキュリティをトレードオフにせずに両方を最大限生かすということだと考えています。
業務部門がセキュリティを鑑みずに勝手にシステムを導入することも違うし、IT部門が頭ごなしに業務部門の導入計画に対してNoということでもありません。
必要なことは生産性とセキュリティを高めること、そしてその一つの答えがIDaasであると考えています。

ちなみに私が参加したセッションの中で非常に面白いと感じたのが、HRとIT部門と業務部門がいかに協業しIDのライフサイクルを鑑みてSaaSを導入すべきか、というセッションです。このセッションではSMBCさんも事例として取り上げられておりました。(日本の企業が取り上げられるのは嬉しいですね)
Channel 9でも視聴可能ですので、興味がある方は是非。(非常に聞き取りやすい英語です)
https://myignite.techcommunity.microsoft.com/sessions/81726

今回はIDaasとしてAzureADを使い、かつ新しい昨日のOne Click SSOという機能を試してみます。

One Click SSOとは?

One Click SSOはAzure ADの比較的新しい機能で、非常に容易にSAML連携を構成できる機能です。詳細は下記のブログを参照してください。
docs.microsoft.com

なお、今回はタイトル通りDropboxSAML連携をし、シングルサインオンを構成してみたいと思います。

DropboxとOne Click SSOでSAML連携

基本的には下記の手順の通りです。
docs.microsoft.com

感動するくらい簡単にSSOが実現できます。
特にすごいと感じたのが、ブラウザのアドオンを入れておくと、Azure ADからDropboxを呼び出し、ほとんどの作業を自動でやってくれます。
今までSAMLの構成は入力すべき項目が多く、非常にわかりづらいものだったのですが、これは非常に画期的だなと感じました。

なお、手順で少しわかりづらいところがあり、「Azure AD SSO の構成」- 「4.[基本的な SAML 構成] 」の中で「応答URL」は下記の値を入れてください
https://www.dropbox.com/saml_login

また、「サインオン URL」については、「[Single sign-on](シングル サインオン) セクション」でDropboxから生成される値を上書きする形なります。
そのため、まずは適当な項目(https://www.dropbox.com/sso/test)等を入力してください。

上記の手順で非常に簡単に構成ができます。

プロビジョニングも実施する

プロビジョニングも非常に簡単に構成できます。
これについても下記のドキュメント通りです。
docs.microsoft.com

このドキュメントの通り構成することで簡単に構成することができました!
f:id:takeru55555:20191217215750p:plain

まとめ

上記の通り非常に簡単に構成することができました。ただし、One Click SSOに対応しているSaaSはまだ多くありません。
対応しているSaaSは下記の通りです。
docs.microsoft.com

今後の進化に期待ですね!

ではまた次回。

Microsoft Teamsでクリスマスをより感じよう!(Flowで日付と日付の差分を算出)

ご無沙汰しております!いや〜ダメですね、続かないです、ブログ・・笑
前回は約一年前ということで、だいぶ間が空いてしまいました。。最近Office 365を触る機会も少なくなってきたので、どんどん触って書いていきたいなと思っている次第でございます。

さて、12月ですね!12月といえばクリスマス!クリスマスといえばAdvent Calendar!ということで今年もOffice 365のAdvent Calendarに参加しております。
adventar.org

今日は12/6ですが、12月と思えない変な天気ですね〜。昨日、一昨日はとにかく暖かく(20度以上!)、せっかくのクリスマスシーズンなのに春先のような気温でクリスマスのワクワクを感じられません。
大人になってもクリスマスのワクワクを感じていたいものですね。

ということで、本日はクリスマスのワクワクをTeamsに!をテーマにしていきたいと思います笑

クリスマスのワクワクを感じるために

子供のころクリスマスのどの辺りにワクワクしたかなと考えた時に、日めくりカレンダーのようにクリスマスまであと何日かな〜、と数えていった瞬間なんかを覚えています。
そして、やはりクリスマスといえばクリスマスツリー、サンタ、プレゼント、ケーキあたり。こういったものを見るとワクワクが高まるんだと思います。

Flowを使ってあと何日カウントダウンをTeamsにポストする

ということで、今日から数えてあと何日でクリスマス、を投稿する仕組みを考えていきたいと思います。
一番手っ取り早くFlowを使っていきます。ただし、Flowでは日付同士の差分、みたいなものを出すのがすごく難しいと思います。(どなたか!良いやり方知っていれば教えてください)
そこで今回はこちらを参考に、クリスマスの日付(12/25)と今日の日付の差分を算出していきたいと思います。

やっていることとしては、本日の日付をDo Until で目的の日付(今回ですと12/25)までカウントアップしていきます。その間配列に値をappendしていき、配列のLengthを算出する、といった手法となります。
では早速見ていきましょう。

変数の設定

f:id:takeru55555:20181206214356p:plain

Do-Until文

f:id:takeru55555:20181206214417p:plain

Teamsに投稿

f:id:takeru55555:20181206215902p:plain

少しトリッキーですがこうすることで、クリスマスまで残り◯日という値を算出することができます。

チーム名やチャネル名にクリスマス絵文字を使いクリスマス感を演出する

Teamsではチーム名やチャネル名にUnicode絵文字を利用可能ですので、よりTemas映えを目指しましょう。
f:id:takeru55555:20181206214842p:plain

完成!!

こんな感じであと何日〜というのが、ポストされます。
f:id:takeru55555:20181206214708p:plain

もっと踏み込んで、例えばFlowのTeamsアクションではなくWebhookにしてメッセージを装飾したり、Bingの画像検索のAPIを組み合わせたりして日替わりイルミネーション画像をポストするなどするとよりTeams映えしてクリスマス感が増します!
とってもワクワクしますね!(果たしてワクワクと何度書いたでしょうか)

ではまた次回♪

ノンコーディング!Exchange Onlineの予定の場所の近くの○○屋さんをTeamsに自動通知する

この記事はOffice 365のAdvent Calendar 2017に参加しております。
adventar.org


今回のAdvent Calendarは元々Teamsのチーム作成をSharePoint Onlineのワークフロー+Azure Automationで管理者の申請制にしてみよう!という記事を書こうと思ってたのですが、12/19担当の@matkjinさんが同様のアプローチをされていたので、こちらはまた次回ということで・・(記事のリンクはこちらです)

ということで、何書こうかなー?と考え、以前Office 365勉強会でお話させていただいた、打ち合わせ場所の近くの○○屋さんをTeamsに通知する方法をMicrosoft Flowを使った完全ノンコーディングバージョンでお届けしたいと思います。

以前はAzure Functionsを使ったアプローチだったのですが、今回は全てOffice 365の"利用者"でできるものしか使っておりません。(以前のアプローチはこちらのスライドを参照)
〇〇屋さんは皆さんのお好きなものを当てはめてください。(今回も例としてハンバーガー🍔)

それでは初めましょう。

必要なもの

なお、ぐるなびAPIを利用するためにはこちらからアカウントを発行してください。

今回のアプローチ

以下のような流れです。

  1. Exchange Onlineに予定を住所付きで登録 (例)社外打ち合わせ等
  2. 予定が始まる〇分前にFlowが動作する
  3. 住所をGeocodingのAPIに渡し、緯度と経度取得
  4. 緯度と経度をぐるなびAPIに渡し、近くの○○屋さんを取得
  5. 取得した情報をTeamsに通知する
  6. 美味しいお店に行けてハッピー

f:id:takeru55555:20171221190424p:plain

実装してみる

今回はすべてFlow側の実装となります。ちなみに処理をシンプルにするためにエラー処理や例外処理は記述しておりません。例えば住所が空欄の場合や会議室が入っている場合などは別途例外処理を記述する必要がありますのでご注意を。
それでは実装してみましょう。

  • トリガーとして、「予定しているイベントがすぐに開始されるとき」を選択し、以下のように設定。今回は予定の2時間前にFlowが動作するようにしました。

f:id:takeru55555:20171221192856p:plain

  • 次に「HTTP - HTTP」を選択します。Geocodingには以下のよにGETでAPIを叩きます。

http://www.geocoding.jp/api/?q=<住所をエンコードした値>

なお、日本語をエンコードするために、encodeUriComponent 式を利用します。
encodeUriComponent(triggerBody()?['Location']?['DisplayName'])

f:id:takeru55555:20171221193825p:plain

ちなみにこの結果はXMLで返ってきます。

  • 次も「HTTP - HTTP」を選択します。以下のようにGETでぐるなびAPIを叩きます。

http://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid=<発行されたキー>&format=json&input_coordinates_mode=1&latitude=<緯度>&longitude=<経度>&range=3&freeword=<検索ワードをエンコードしたもの>
APIにはいろいろなパラメータが用意されているので仕様書を参考にしていただき色々組み替えてください

なお、緯度と経度はGeocodingの結果であるXMLから値を取り出すために、以下のようにFlowに装備されているxpath式を使います。
緯度
 xpath(xml(body('Http')),'string(/result/coordinate/lat)')
経度
 xpath(xml(body('Http')),'string(/result/coordinate/lng)')

f:id:takeru55555:20171221194955p:plain

こちらはJOSNで返ってきます。

  • 次に「JSONの解析」アクションを使います。実際の応答である「本文」からスキーマを生成することができますが、お店によってはnullのフィールドがあったりすると解析できずエラーとなる場合があります。そこで今回は全店舗で情報を持っているであろう店舗名、URL、住所のみを取るようにしました。

サンプルのスキーマは以下の通りです。

{
    "type": "object",
    "properties": {
        "@@attributes": {
            "type": "object",
            "properties": {
                "api_version": {
                    "type": "string"
                }
            }
        },
        "total_hit_count": {
            "type": "string"
        },
        "hit_per_page": {
            "type": "string"
        },
        "page_offset": {
            "type": "string"
        },
        "rest": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "@@attributes": {
                        "type": "object",
                        "properties": {
                            "order": {
                                "type": "string"
                            }
                        }
                    },
                    "name": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string"
                    },
                    "address": {
                        "type": "string"
                    }
                },
                "required": [
                    "@@attributes",
                    "id",
                    "update_date",
                    "name",
                    "name_kana",
                    "latitude",
                    "longitude",
                    "category",
                    "url",
                    "url_mobile",
                    "coupon_url",
                    "image_url",
                    "address",
                    "tel",
                    "tel_sub",
                    "fax",
                    "opentime",
                    "holiday",
                    "access",
                    "parking_lots",
                    "pr",
                    "code",
                    "budget",
                    "party",
                    "lunch",
                    "credit_card",
                    "e_money",
                    "flags"
                ]
            }
        }
    }
}

f:id:takeru55555:20171221195524p:plain

  • 実際のデータが「rest」に格納されるので、後はループを回してTeamsに投稿していくだけです。ここでは「Apply to each」およびTeamsへの「Post message」にて投稿していきます。以下のような感じですね。

f:id:takeru55555:20171221195855p:plain

使ってみる

さて適当な予定を突っ込んで開始に時間前まで待ってみましょう。ちゃんと来ていますね。
f:id:takeru55555:20171221201816p:plain

今回はTeamsのPost messageアクションを使いましたが、少しシンプルすぎるので、もう少し見やすいようにするのであれば、TeamsのWebhookでメッセージを投稿した方が良いかもしれません。

まとめ

さて今回はハンバーガーという私の趣味一直線でしたが、例えばコーヒー屋さんでも良いでしょうし、色々応用が利きます。
Office 365の管理権限なんかも必要ないので、是非お試しください~~~

ではまた次回。

TeamsでChatOps!? TeamsからAzuru FunctionsとAzure Automationで仮想マシンの管理を行なう

先日タイに出張していたのですが、連日30度を越えていて非常に暑かったです。
帰ってきたら20度以上の温度差で少し風邪をひいてしましました。体調管理には気を付けたいものです。

さて今回は思い付きのアイディアを形にしていく自由研究スタイルでいきたいと思います笑
私は検証用にAzureで仮想マシンを動かしておりますが、やっぱり節約しなきゃ!ということで小まめに停止をしております。
ただ毎回Azureのポータルで操作するのってやっぱり面倒くさいですよね。
ということで、TeamsのBot経由でやってしまおう!というのが今日の内容です。今回は仮想マシンの停止のみですが、スクリプトの書き方によってはもちろん仮想マシンの起動や作成、インスタンス変更なんかもできます。すべてはスクリプトの書き方次第でどうとでもなります。
そんなプチChatOps(そんな大それたものではないけれど)が今回のテーマでございます。
Azureを使うのでサブスクリプションが無い方は試用版を取得しておいてください。

やろうとしていること

今回はシンプルに以下のような流れを想定しています。
Microsoft TeamsでBotユーザーに対して特定の文字列(stop-vm)を打つとAzure FunctionsにHTTPリクエストを投げる
②Azure Functionsが起動し、ユーザーに対してメッセージを返すともにAzure AutomationにHTTPリクエストを投げる
③Azure Automationが仮想マシンの停止スクリプトを実行
仮想マシンのシャットダウンが完了したらIncoming Webhookでユーザーに通知

とっても雑な絵ですが、こんな感じ。
f:id:takeru55555:20171207175039p:plain

直接Azure Automationに投げてもできるかもしれませんが、Azure Functionsを経由した方がインタラクティブに対応できますし、これから開始や仮想マシンごとの停止、インスタンスの変更などを考えたときにFunctionsの方が自由度が効くと思ってこうしております。

これを実現するために、以下の準備を行います。

1.一連の処理が終わったら特定のチャネルにメッセージを送信できるようにIncomingWebhookを用意しておく
2.Azure Automationで仮想マシンの停止のRunbookを用意しておく
3.Azure Functionsで関数を用意しておく
4.Teamsにカスタムボットを登録し、Azure FunctionsにHTTPリクエストを投げれるようにしておく

それではそれぞれ見ていきましょう。

1. Teams側でIncoming Webhookを追加しておく

こちらは以前の記事を参照して用意しておいてください。
f:id:takeru55555:20171215004100p:plain

2. Azure AutomationのRunbookを用意する

以下のページを参考に、仮想マシンを操作するRunbookを作成しました。
Azure Automation で VM を自動停止する – Japan Azure Technical Support Engineers' Blog

今回は「Runbook の編集」章で記載がある、「サブスクリプション内の、すべての VM」を停止するようにします。

なお、仮想マシンが停止後、Incoming Webhook経由でメッセージを投げるために、後半のforeach文を以下のようにしております。

foreach ($VM in $VMs) {
    # VM を停止
    $StopRtn = $VM | Stop-AzureRmVM -Force -ErrorAction SilentlyContinue
    $URI = <1. で作成したIncoming WebhookのURL>

    # 正常に VM が停止したかの確認&ステータスの出力
    if ($StopRtn.Status -ne 'Succeeded') {
        Write-Output ($VM.Name + " failed to stop.")
        Write-Error ($VM.Name + " failed to stop. Error was:") -ErrorAction Continue
        Write-Error (ConvertTo-Json $StopRtn.Error) -ErrorAction Continue
        $body = ConvertTo-JSON @{
            text  = $VM.Name + " failed to stop."
        }
    Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json'
    }
    else {
        Write-Output ($VM.Name + " has been stopped.")
        $body = ConvertTo-JSON @{
            text  = $VM.Name + " has been stopped."
        }
    Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json'
    }

Runbookを保存したら、Webhookを追加します。
Webhookの追加をクリック。
f:id:takeru55555:20171215004207p:plain

任意の名前など必要な設定値を入力して作成。URLが表示されるので控えておいてください。
f:id:takeru55555:20171215004249p:plain

3. Azure Functionsを用意する

今回は全てPowerShellで書こうと思いますので、「PowerShell」-「HTTP - trigger」を選択します。
f:id:takeru55555:20171215004644p:plain

とても簡単ですが、以下のようなものを準備しておきました。

$requestBody = Get-Content $req -Raw | ConvertFrom-Json
$text = $requestBody.text
Out-File -Encoding Ascii -FilePath $res -inputObject $input

$vms = Get-Content $inputTable | ConvertFrom-Json
if($text -like "*stop-vm*"){
    $hash = @{
        type = "message";
        text = "OK. Wait a moment.";
    }
    $URI = <2で取得したAzure AutomationのWebhookのURL>
    Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json'
}
else{
    $hash = @{
        type = "message";
        text = "please use the folowing comend.<br>stop-vm -vm 'VM name'";
    }
}
$input = $hash | ConvertTo-Json
Out-File -Encoding Ascii -FilePath $res -inputObject $input

stop-vmコマンドが来たら2で作成したAzure Automationに投げる、それ以外はヘルプ的なものを出す、といった形にしています。

こちらもWebhookを追加します。
f:id:takeru55555:20171215020616p:plain

4. Teams側でカスタムボットを追加する

 チームの管理から「カスタムボットの作成」をクリック
f:id:takeru55555:20171215005629p:plain

3で発行したURLや名前、説明を入力し、作成
f:id:takeru55555:20171215161409p:plain

これで準備が完了です。

さっそく試してみる

それでは登録したBotユーザーに対してStop-VMと話しかけてみましょう。
f:id:takeru55555:20171215015819p:plain

VMがシャットダウンされましたね。
ちなみにStop-VM以外を打つと以下のようにヘルプ的なものが出るようになってます。
f:id:takeru55555:20171215015738p:plain

Azure Functionsはタイムアウトする場合があるので、その辺の考慮は必要ですが、簡単ですし応用も効きます。
是非お試しあれ。

さて次回も自由研究系で何かを書いていこうと思います。

ではまた次回。