ieserver.netさんを利用されている方で、余計なアプリは入れたくないというような方向けのScriptです。
Windows8/2012以降のOSで実行可能です。
Invoke-RestMethodの箇所を弄れば、Windows7/2008R2でも動きます。
実装している処理と流れは、下記の3つです。
- ISPから付与されたGlobalIPの変更をチェック(外部サイトを利用)
- GlobalIPを取得するサイトは2つ準備し、1箇所目がダウンしていた場合も2箇所目で取得させています
- 変更があったらUpdate
- 変更されたIPとプロバイダで付与されているFQDNをメール通知
汚いソースなので、「こうすれば綺麗だよ」とか優しく教えていただける方はコメントお願いします。
[2015.04.12 追記]
IPアドレス更新に失敗した場合、メール通知されずIP変更に気づかないケースが発生したため
旧IP記録ファイルにLoopBackを書き込むことでメール通知されるまで
IP変更時と同様の動作となるよう改版しました。
$LOOPBACKの記述があるところが該当箇所です。
ieserverUpdater.ps1
# ドメイン名
$DOMAIN = "ieserverで選択したドメイン名:dip.jp等"
# パスワード
$PASS = "ieserverで登録したパスワード"
# サブドメイン名
$HOSTNAME = "取得したサブドメイン名"
# FQDN
$DDNS_FQDN = $HOSTNAME + "." + $DOMAIN
# IP アドレスを取得するページのURL
$IP_URL1 = "http://www.forts.jp/ip"
$IP_URL2 = "http://httpbin.org/ip"
# ieserver.net のDDNSサーバーの登録ページのURL
$DDNS_URL = "https://ieserver.net/cgi-bin/dip.cgi?"
$UPDATE_URL = $DDNS_URL + "username=" + $HOSTNAME + "&password=" + $PASS + "&domain=" + $DOMAIN + "&updatehost=Go"
# ログファイルを保存するディレクトリ
$DATAPATH = "ログを保存するディレクトリパス"
$WAN_IP_FILE = "wan_ip.txt"
$OLD_IP_FILE = "old_ip.txt"
$LOG = "log.txt"
# メール通知失敗対策用 旧IPアドレス
$LOOPBACK = "127.0.0.1"
# メール送信設定(Gmailを使う想定です)
$SMTPSERVER = "smtp.gmail.com"
$EMAILFROM = "Gmailのメールアドレス"
$EMAILTO = "送信先メールアドレス(複数の場合、コンマで区切る)"
$SUBJECT = "Change IP Notification"
$GMAILPWD = "Gmailのパスワード:アプリパスワード設定時はそれを。。。"
# ログの削除日数指定
$DELDAYS = 7
# ログの出力
function WRITE_LOG($LOGMSG)
{
$TIMESTAMP = Get-Date;
Add-Content ($DATAPATH + "\" + $LOG) ($TIMESTAMP.ToString("yyyy/MM/dd HH:mm:ss") + " " + $LOGMSG)
}
# 変更有無チェック
function COMP_IP
{
if ($OLD_IP -eq $NEW_IP)
{
WRITE_LOG("01:IPアドレス変更無し")
Set-Content ($DATAPATH + "\" + $WAN_IP_FILE) $NEW_IP
}
else
{
WRITE_LOG("02:IPアドレス変更有り")
Set-Content ($DATAPATH + "\" + $OLD_IP_FILE) $NEW_IP
Set-Content ($DATAPATH + "\" + $WAN_IP_FILE) $NEW_IP
UPDATE_AND_CHECK
}
}
# IPアドレスの更新と確認
function UPDATE_AND_CHECK
{
$RESLT_UPDATE = Invoke-WebRequest $UPDATE_URL
ECHO $RESLT_UPDATE.StatusCode
if ($RESLT_UPDATE.StatusCode -eq 200)
{
$UPDATE_CHECK = Resolve-DnsName $DDNS_FQDN -Server $DOMAIN
ECHO $UPDATE_CHECK.IPAddress
if ($UPDATE_CHECK.IPAddress -eq $NEW_IP)
{
WRITE_LOG("13:IPアドレス更新成功")
SEND_MAIL
}
else
{
WRITE_LOG("93:IPアドレス更新失敗")
Set-Content ($DATAPATH + "\" + $OLD_IP_FILE) $LOOPBACK
WRITE_LOG("94:LOOPBACKアドレスセット")
}
}
else
{
WRITE_LOG("94:ieServer接続不可")
}
}
# メール通知
function SEND_MAIL
{
$BODY = "New IP = " + $NEW_IP + "`nISP FQDN = " + $ISP_FQDN
$SMTPCLIENT = New-Object Net.Mail.SmtpClient($SMTPSERVER, 587)
$SMTPCLIENT.EnableSsl = $true
$SMTPCLIENT.Credentials = New-Object System.Net.NetworkCredential($EMAILFROM, $GMAILPWD);
$SMTPCLIENT.Send($EMAILFROM, $EMAILTO, $SUBJECT, $BODY)
WRITE_LOG("14:メール通知完了")
}
# ログの自動削除
Get-ChildItem ($DATAPATH + "\" + $LOG) | Where-Object{((Get-Date) - $_.CreationTime).Days -gt $DELDAYS } | ForEach-Object { $_.Delete() }
# 記録しているIPアドレスの取得
if (Test-Path ($DATAPATH + "\" + $OLD_IP_FILE))
{
$LAST_IP = Get-Content ($DATAPATH + "\" + $OLD_IP_FILE)
}
else
{
$LAST_IP = "0.0.0.0"
}
$LAST_IP=$LAST_IP.Split("`n")
$OLD_IP = $LAST_IP[0]
ECHO $OLD_IP
# IPアドレスの取得
try
{
$URL1_IP = Invoke-RestMethod -Uri $IP_URL1
$NEW_IP1 = $URL1_IP.Split("`n")
$NEW_IP = $NEW_IP1[0]
ECHO $NEW_IP
$ISP_FQDN = (nslookup $NEW_IP).Split(" ")
$ISP_FQDN = $ISP_FQDN[11]
ECHO $ISP_FQDN
WRITE_LOG("11:URL1でIPアドレス取得")
COMP_IP
}
catch
{
WRITE_LOG("91:URL1でIPアドレスが取得できませんでした")
try
{
$URL2_IP = Invoke-RestMethod -Uri $IP_URL2
$NEW_IP = $URL2_IP.origin
ECHO $NEW_IP
$ISP_FQDN = (nslookup $NEW_IP).Split(" ")
$ISP_FQDN = $ISP_FQDN[11]
ECHO $ISP_FQDN
WRITE_LOG("12:URL2でIPアドレス取得")
COMP_IP
}
catch
{
WRITE_LOG("92:URL2でIPアドレスが取得できませんでした")
}
}