LoginSignup
0
1

More than 5 years have passed since last update.

Azure AutomationでSQL DatabaseのSELECT件数をメール(Slack)通知する

Last updated at Posted at 2017-12-11

SQL Databaseへの定期的なクエリ発行を、Azure Automationで実現しました。
指定したテーブルの件数を取得して、メール or Slack に通知する手順です。
メール通知はSendGridを使用しています。

SendGridアカウント作成

  • 以下の記事が分かりやすかったので引用させて頂きました。
    Azureのメール送信はSendGrid

  • 今回の手順ではAPIキーの発行は不要です。

Automationアカウント作成

  • 以下の記事が分かりやすかったので引用させて頂きました。
    Azure Automation で VM を自動停止する

  • アカウントの作成と、Azureモジュールのアップデートまで実施しましょう。

Automation資格情報追加

Runbookの中でSendGridとSQL Databaseの認証にAutomation資格情報を利用します。

SendGrid資格情報を追加する

  • Automationアカウントを選択し、[資格情報の追加]をクリックします。
    image.png

  • 名前には、任意の値を入力します。
    image.png

  • ユーザ名には、SendGridアカウント情報より取得したUSERNAMEを入力します。
    image.png

  • パスワードには、SendGridアカウント作成時に指定したパスワードを入力します。

SQL Database資格情報を追加する

  • 上記手順と同様にSQL Databaseの資格情報を追加します。ユーザ名とパスワードには、SQL Databaseのユーザ情報を入力してください。

Email通知用Runbook作成

  • Automationアカウントより、[Runbook]→[Runbookの追加]を選択します。
    image.png

  • 名前には、任意の値を入力します。Runbookの種類には、[PowerShell ワークフロー]を選択します。
    image.png

  • Runbook編集が画面が表示されます。
    image.png

  • 以下のコードを貼り付けます。workflow名はRunbookの名称と合わせるようにして下さい。

workflow kwhrtest
{

    param(
        [parameter(Mandatory=$True)]
        [string] $SqlServer,

        [parameter(Mandatory=$False)]
        [int] $SqlServerPort = 1433,

        [parameter(Mandatory=$True)]
        [string] $Database,

        [parameter(Mandatory=$True)]
        [string] $Table,

        [parameter(Mandatory=$True)]
        [PSCredential] $SqlCredName,

        [parameter(Mandatory=$True)]
        [String] $SmtpCredName,

        [parameter(Mandatory=$True)]
        [string] $MailTo
    )

    # Get the username and password from the SQL Credential
    $SqlUsername = $SqlCredName.UserName
    $SqlPass = $SqlCredName.GetNetworkCredential().Password

    # Get the username and password from the SMTP Credential
    $SmtpCredential = Get-AutomationPSCredential -Name $SmtpCredName

    inlinescript {
        # Define the connection to the SQL Database
        $Conn = New-Object System.Data.SqlClient.SqlConnection("Server=tcp:$using:SqlServer,$using:SqlServerPort;Database=$using:Database;User ID=$using:SqlUsername;Password=$using:SqlPass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;")

        # Open the SQL connection
        $Conn.Open()

        # Define the SQL command to run. In this case we are getting the number of rows in the table
        $Cmd=new-object system.Data.SqlClient.SqlCommand("SELECT COUNT(*) from dbo.$using:Table", $Conn)
        $Cmd.CommandTimeout=120

        # Execute the SQL command
        $Ds=New-Object system.Data.DataSet
        $Da=New-Object system.Data.SqlClient.SqlDataAdapter($Cmd)
        [void]$Da.fill($Ds)
        $html = $Ds.Tables[0].Rows[0][0]

        # Close the SQL connection
        $Conn.Close()

        function EncodeSubject($s) {
            $enc = [Text.Encoding]::GetEncoding("csISO2022JP")
            $s64 = [Convert]::ToBase64String($enc.GetBytes($s), [Base64FormattingOptions]::None)
            return [String]::Format("=?{0}?B?{1}?=", $enc.HeaderName, $s64)  
        }

        $From = "[任意の送信元メールアドレス]"
        $Subject = EncodeSubject(EncodeSubject("[メール件名]"))

        Send-MailMessage `
            -To $using:MailTo  `
            -Subject $Subject  `
            -Body "$html 件 <br /> です" `
            -UseSsl `
            -Port 587 `
            -SmtpServer 'smtp.sendgrid.net' `
            -From $From `
            -BodyAsHtml `
            -Encoding ([System.Text.Encoding]::UTF8) `
            -Credential $using:SmtpCredential
    }
}
  • 入力したら[保存]を選択し、[テストウィンドウ]を選択する。
    image.png

  • パラメータ入力画面を以下の内容で入力します。

    • SQLSERVER : SQL Databaseサーバー名
    • SQLSERVERPORT : 1433
    • DATABASE : データベース名
    • TABLE : テーブル名
    • SQLCREDNAME : 前手順で任意の名前で作成した資格情報名を入力する
    • SMTPCREDNAME : 前手順で任意の名前で作成した資格情報名を入力する
    • MAILTO : メール送付先アドレス

 image.png

  • [開始]を選択する。
    image.png

  • メールがくれば成功
    image.png

Runbookスケジュール設定

  • Runbook概要ページより、[スケジュール]を選択する。
    image.png

  • [スケジュール]→[新しいスケジュールを作成します]の順に選択し、任意の値を入力する。
    image.png

  • [パラメータと実行設定]を選択し、以下のように入力する。

    • SQLSERVER : SQL Databaseサーバー名
    • SQLSERVERPORT : 1433
    • DATABASE : データベース名
    • TABLE : テーブル名
    • SQLCREDNAME : 前手順で任意の名前で作成した資格情報名を入力する
    • SMTPCREDNAME : 前手順で任意の名前で作成した資格情報名を入力する
    • MAILTO : メール送付先アドレス image.png
  • 指定した時間に実行されていれば成功

Slack通知用Runbook作成

  • E-Mail通知部分をSlack通知に置き換えてみます。

  • SlackのIncoming WebHooksを使っていますので事前にSlackでURLを取得しておいてください。

workflow kwhrtest-slack
{

    param(
        [parameter(Mandatory=$True)]
        [string] $SqlServer,

        [parameter(Mandatory=$False)]
        [int] $SqlServerPort = 1433,

        [parameter(Mandatory=$True)]
        [string] $Database,

        [parameter(Mandatory=$True)]
        [string] $Table,

        [parameter(Mandatory=$True)]
        [PSCredential] $SqlCredName
    )

    # Get the username and password from the SQL Credential
    $SqlUsername = $SqlCredName.UserName
    $SqlPass = $SqlCredName.GetNetworkCredential().Password

    inlinescript {
        # Define the connection to the SQL Database
        $Conn = New-Object System.Data.SqlClient.SqlConnection("Server=tcp:$using:SqlServer,$using:SqlServerPort;Database=$using:Database;User ID=$using:SqlUsername;Password=$using:SqlPass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;")

        # Open the SQL connection
        $Conn.Open()

        # Define the SQL command to run. In this case we are getting the number of rows in the table
        $Cmd=new-object system.Data.SqlClient.SqlCommand("SELECT COUNT(*) from dbo.$using:Table", $Conn)
        $Cmd.CommandTimeout=120

        # Execute the SQL command
        $Ds=New-Object system.Data.DataSet
        $Da=New-Object system.Data.SqlClient.SqlDataAdapter($Cmd)
        [void]$Da.fill($Ds)
        $html = $Ds.Tables[0].Rows[0][0]

        # Close the SQL connection
        $Conn.Close()

        $msg = "$html 件です"
        $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
        $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($msg)
        $payload = @{
                text = $enc.GetString($utf8Bytes);
                username = "Azure Automation";
                icon_emoji = ":azure:"
        }
        Invoke-RestMethod -Uri "[Slack WebHook URL]" -Method Post -Body (ConvertTo-Json $payload)
    }
}
  • Slackに通知されれば成功

image.png

補足

メールの件名に日本語が使えない?

通常はSend-MailMessageで-Encodingを付与すると、日本語で件名・本文を指定することが可能ですが、Automationで実行すると以下のエラーを吐きます。

Send-MailMessage : String contains invalid Unicode code points.
Parameter name: strInput

Automation側の問題のようで以下のように2重エンコードすると回避できました。

function EncodeSubject($s) {
$enc = [Text.Encoding]::GetEncoding("csISO2022JP")
$s64 = [Convert]::ToBase64String($enc.GetBytes($s), [Base64FormattingOptions]::None)
return [String]::Format("=?{0}?B?{1}?=", $enc.HeaderName, $s64)
}
$Subject = EncodeSubject(EncodeSubject("Automationからのお知らせ"))

以上

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1