2010年10月17日日曜日

グローバルIPアドレスを確認し、変更あればメールで通知

Subversion を外部から接続しようとした場合、
固定グローバルIPアドレスを使用しているわけではないので、
変更されてしまうと困ったことになります。

ちなみに、フレッツ光を自宅では使用しているのですが、
グローバルIPアドレスを固定にするには、タダではありませんし、
今のところ、お金を払うほど必要としているわけでもありません。

まあ、そうそう変わることはないと思うのですが、
変わったら、そのことをメールで通知させることはできないか?
ということを考えてみました。

メールで教えてくれれば、その都度、Subversion の接続を変えればいいと
思うわけです。


幸いなことに、内部(自宅内のPC)から接続すれば、グローバルIPアドレスが
何なのか教えてくれるWEBサイトがあります。

ということは、そのようなWEBサイトにアクセスして、
IPアドレスを抽出して、前回確認時と比較して、不一致だったらメール送信、
という処理を作成すればよいわけです。

んでもって、それをタスクで定期的に実行させれば、望み通りとなります。


以上の考えを元に、PowerShell スクリプトを作成してみました。

PowerShell は今回が初めてだったので、結構苦労しました・・・


グローバルIPアドレスを確認するWEBサイトは、以下を使用させて頂くことにしています。

自分のグローバルIPアドレス確認ツール、「IP君」


HTMLのBODY部に依存しているので、
確認に使用するWEBサイトが変われば、PowerShell スクリプト修正が必要です・・・

もし、ご利用される方がいらっしゃいましたら、
「# メール送信アドレス」の $smtp (メール・サーバー)、$to (メール送信先アドレス)、
$from (メール送信元アドレス) を修正してやってください。

get_GlobalIP.ps1
# 接続先URL
$url = "http://www.axisnetworks.biz/tools/gip/"
Write-Output "接続先: $url"

# メール送信先アドレス
$smtp = "xxxxx.ne.jp"
$to   = "xxxx@yyyyy.com"
$from = "xxxx@xxxxx.ne.jp"


# グローバルIPアドレス保存用ファイル
$path = Split-Path $MyInvocation.MyCommand.Path -Parent
$file = Join-Path $path get_GlobalIP.txt

# ファイル存在確認&前回確認時のIPアドレス読込み
If (Test-Path $file) {
  $old_address = Get-Content $file
} else {
  $old_address = "<記録なし>"
}
Write-Output "前回確認済みのグローバルIPアドレス: $old_address"


# GETリクエスト実行
$req = [System.Net.WebRequest]::Create($url)
$req.Method=”GET”
$resp=$req.GetResponse()

# レスポンスの読込み&確認
$encode = $resp.ContentEncoding
$sr = New-Object IO.StreamReader($resp.GetResponseStream(), $resp.ContentEncoding)

while ( ($line = $sr.ReadLine()) -ne $null ) {
  $line = $sr.ReadLine()
  if ($line -like '*<p class="style4" name="ip">*') {
    if ($line -match "(?<address>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)") {
      $new_address = $matches.address
      if ($old_address -eq $new_address) {
        Write-Output "IPアドレス変更なし: $old_address == $new_address"
      } else {
        Write-Output "IPアドレスが変更: $old_address -> $new_address"
        # ファイル上書き
        Write-Output "ファイル更新: $file"
        $matches.address | Out-File -FilePath $file
        
        # メール送信
        Write-Output "メール送信: $to"
        $mail = New-Object Net.Mail.MailMessage($from, $to)
        $mail.Subject = "グローバルIPアドレス変更"
        $mail.Body = "IPアドレスが変更: $old_address -> $new_address"
        $mail.SubjectEncoding = [Text.Encoding]::GetEncoding("ISO-2022-JP")
        $mail.BodyEncoding = [Text.Encoding]::GetEncoding("ISO-2022-JP")
        $sc = New-Object Net.Mail.SmtpClient($smtp)
        $sc.Send($mail)
        $mail.Dispose()
      }
    }
  }
}

$sr.Close()
$resp.Close()


実行は、コマンド・プロンプトで以下のように実行します。

> powershell .\get_GlobalIP.ps1


最後に、powershell.exe、get_GlobalIP.ps1 ともにフルパスを指定して、
タスク登録すれば完成です。(= ̄▽ ̄=)V


ちなみに、これまでに(自分のように)PowerShell を実行したことがなければ、
以下のようなエラーが表示されるかもしれません。

スクリプトの実行がシステムで無効になっているため、ファイル C:\(配置場所)\get_GlobalIP.ps1 を読み込めません。詳細については、「get-help about_signing」と入力してヘルプを参照してください。


上記エラーが出た場合、PowerShell の実行ポリシーを変更する必要があります。
管理者で起動したコマンド・プロンプトにて、以下を実行します。

> powershell Set-ExecutionPolicy RemoteSigned