Windowsサーバーのシャットダウン時にPowerShellでSlackに通知する


業務で使用している開発サーバをGCE(Google Compute Engine)に移行する事になりました。

料金を抑えるためプリエンプティブインスタンスで運用していますが、プリエンプティブインスタンスは24時間稼働するとプリエンプト(強制的にシャットダウン)されるほか、任意のタイミングでプリエンプトされる事もあります。
※詳しくは<プリエンプティブ インスタンスの制限>を参照。

いつの間にかサーバーが落ちている!という事がたまにあるので、シャットダウンのタイミングでSlackに通知する事にしました。


Slack APIの準備

外部からSlackにメッセージを送るには、「Incoming Webhooks」を利用します。

  1. Slackの左上のメニューから「Slackをカスタマイズ」をクリックし、次のページで
    ≡Menu ⇒ App管理を開く(或いは、https://***.slack.com/apps/manage を開く)

  2. 「カスタムインテグレーション」→「Incoming Webhooks」をクリック

  3. 【設定を追加】をクリック

  4. チャンネルを選択し、【Incoming Webhook インテグレーションの追加】をクリック

  5. 「Webhook URL」をコピーしてテキストエディタに貼り付けておく

  6. 名前やアイコンはデフォルトではこうなっているので、

    変えたければ少しカスタマイズする。

PowerShellスクリプトの準備

Incoming Webhookの設定ページにも記載がありますが、メッセージを送るにはJSON形式でPOSTするだけです。

今回はWindowsサーバーから送信するので、PowerShellを使います。
以下をコピーし、サーバーの任意の場所に保存します。拡張子は「.ps1」です。
せっかくなので、メッセージは引数で受け取るようにしました。
※ $webHookURL には上でコピーしておいた「Webhook URL」を設定します。

SlackNotifycation.ps1
# 引数必須設定
Param(
    [parameter(mandatory=$true)][String]$Arg1
)

# ★ここにIncoming Webhooksの「Webhook URL」を記載
$webHookURL = "https://hooks.slack.com/services/*********/"

# メッセージをエンコーディング
$enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
$payload = @{
    text = $enc.GetString([System.Text.Encoding]::UTF8.GetBytes($Arg1));
}
$body = ConvertTo-Json $payload

# Slackに通知
Invoke-RestMethod -Uri $webHookURL -Method Post -Body $body

サーバーでシャットダウン時のタスクを設定する

通常の「タスクスケジューラ」ではシャットダウンタスクは作成できません。
以下の手順でグループポリシーに追加します。

  1. [ファイル名を指定して実行](Winキー+R)でgpedit.mscと入力し実行
  2. 左側のツリーから[コンピュータの構成]-[Windowsの設定]-[スクリプト(スタートアップ/シャットダウン)]を選択
  3. 右側の[シャットダウン]をダブルクリック 4.「PowerShellスクリプト」タブで【追加】をクリックし、.ps1ファイルを指定する。スクリプトのパラメーターにメッセージを入力する。

実行結果

以下のようにSlackに通知されれば成功です!