ラベル DDNS の投稿を表示しています。 すべての投稿を表示
ラベル DDNS の投稿を表示しています。 すべての投稿を表示

2009年5月8日金曜日

PowerShellでDDNSサービスを更新(3)

PowerShellでDDNSサービスを更新(1)PowerShellでDDNSサービスを更新(2) 、の続き。
ddo.jp に対してPowerShell で更新をかけようというもの。
 
 

HTTPでクエリストリング付きのGETを送る


PowerShell から WebClient クラスを使ってクエリ文字列をくっつけたGETはどうすればいいのか。
 

単純にくっつけてみる



[sourcecode language='sh']# 引数格納、URL形式
param([string]$url)


# 途中で例外を吐いたらここに飛び、抜ける
trap [Exception] {
echo $error[0].exception
break
}


# クエリ文字列を作成
$query = "?dn=hoge.example.jp&pw=piyopiyo"


# .NetFramework の WebClient クラスを拝借
$webCli = New-Object System.Net.WebClient

# コンテンツを取得、無理やりくっつけてみる
$body = $webCli.DownloadString($url + $query)
[/sourcecode]

で、実行してHTTPで送られている内容をキャプチャ。※テストなのでhostヘッダが "sawano.members.icraft.jp"
GET /index.html?dn=hoge.example.jp&pw=piyopiyo HTTP/1.1
 
Host: sawano.members.icraft.jp
Connection: Keep-Alive


あら、これでも送れてるのね。
しかし釈然としない、WebClient クラスには QueryString とかいうプロパティがあるみたいので、それを使うのが普通っぽい。
 
 


WebClient.QueryString で


はて、QueryString を設定するにはどうしたらいいのかね。
連想配列で突っ込んでみたら、案の定怒られた。
[sourcecode language='sh']# 連想配列でクエリの内容を設定してみる
$query = @{dn = "hoge.example.jp";pw = "piyopiyo"}
$query

# .NetFramework の WebClient クラスを拝借
$webCli = New-Object System.Net.WebClient
$webCli.QueryString = $query[/sourcecode]
 

Name Value
---- -----
dn hoge.example.jp
pw piyopiyo
"QueryString" の設定中に例外が発生しました:
""System.Collections.Hashtable" を
"System.Collections.Specialized.NameValueCollection" に変換できません。"

 

ほう、左様か。NameValueCollection ってのを使えばいいの?
 

[sourcecode language='sh']# 引数格納、URL形式
param([string]$url)


# 途中で例外を吐いたらここに飛び、抜ける
trap [Exception] {
echo $error[0].exception
break
}

# NameValueCollection をマニュアル通り定義してみる
$query = New-Object System.Collections.Specialized.NameValueCollection

$query.add( "dn", "hoge.example.jp" )
$query.add( "pw", "piyopiyo" )


# .NetFramework の WebClient クラスを拝借
$webCli = New-Object System.Net.WebClient

# WebClient の QueryString プロパティを設定
$webCli.QueryString = $query

# コンテンツを取得
$body = $webCli.DownloadString($url)[/sourcecode]


で、実行とHTTPキャプチャ。
GET /index.html?dn=hoge.example.jp&pw=piyopiyo HTTP/1.1
 
Host: sawano.members.icraft.jp
Connection: Keep-Alive


できたようだ。
 
 
 

これでややこしそうなところは一通り準備がそろった。イベントログ書き出し・メールくらいは如何様にでもなろう。
 

終わりにしようかどうしようか。

2009年5月7日木曜日

PowerShellでDDNSサービスを更新(2)

PowerShellでDDNSサービスを更新(1) の続き。
ddo.jp に対してPowerShell で更新をかけようというもの。
 

IPアドレスが更新されているかチェック


毎回更新していると相手さんに負荷がかかるので、IPアドレスが登録時のものと変わっているかチェックする。
 
IPアドレスをゲットして、ローカルにおいたテキストに保存しつつ更新というシナリオ。
 

"get_ipandtest.ps1" というスクリプトを作成。
[sourcecode language='sh']# 引数格納、URL形式
param([string]$url)

# IPアドレスの書式を正規表現で定義しておく
$IPFmt = "^(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9]\.){3}(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])$"


# 途中で例外を吐いたらここに飛び、抜ける
trap [Exception] {
echo $error[0].exception
break
}

# テキストファイルに保存していたIPアドレスを取得
# なかったら0.0.0.0 などを突っ込む
if (Test-Path myAdd.txt) {
$testIP = Get-Content myAdd.txt -TotalCount 1 -encoding UTF8
} else {
$testIP = "0.0.0.0"
}

# テストIPのチェック用
echo $testIP

# .NetFramework の WebClient クラスを拝借
$webCli = New-Object System.Net.WebClient

# コンテンツを取得
$body = $webCli.DownloadString($url)

# 改行を消しちゃう
$body = $body -replace "`n", ""

# コロン区切りで配列に格納、DDOでは2つ目がIPアドレス
$ip = $body.split(":")



# IPアドレスの書式をチェック
if ($ip[1] -match $IPFmt) {
echo "IPアドレス ゲット成功デース"
} else {
Write-Output "ゲットシタモノハ IPアドレスデハ アリマセーン"
break
}

echo $ip[1]


# グローバルIPアドレスが変わったかどうかチェック
if ($ip[1] -eq $testIP) {
echo "IPアドレスハ カワッテマセーン"
} else {
Write-Output "IPアドレス カワッテマス、テキスト更新シマース"
$ip[1] | Out-File myAdd.txt -encoding UTF8
}
[/sourcecode]

echo と Write-Output が混ざっているのには特に意味はなく、両方できるんだなーというのを試している。
 
 

動作させてみる


初回動作では myAdd.txt がないので、0.0.0.0 を相手に比較。
 
 

PS > ./get_ipandtest.ps1 http://info.ddo.jp/remote_addr.php
0.0.0.0
IPアドレス ゲット成功デース
125.4.***.***
IPアドレス カワッテマス、テキスト更新シマース

 

2回目の動作では、myAdd.txt があるのでそれと比較してグローバルIPが変わっているかチェックさせる。
PS > ./get_ipandtest.ps1 http://info.ddo.jp/remote_addr.php
125.4.***.***
IPアドレス ゲット成功デース
125.4.***.***
IPアドレスハ カワッテマセーン

 

あとは クエリストリングつけて、HTTP で GET をするだけだ。
さらにつづく。