サブネットの中でどのアドレスが空いているかわからない!
こんな時にはExPingなどの便利ツールでいい感じにやるのが非常に効率的な方法であるのだが、そういったソフトがない状況でもなんとかする方法を考えました。(そんな状況下ではおそらくこの記事は見れない)
PowerShell
Windows 10ではWindows PowerShell 5.1が標準搭載されているため、PowerShellでならどのWindows PCでも使えるかつ、batchよりも読みやすい(個人的な見解)ので汎用性はあるかと
PowerShellでPingを打つコマンド
参考 ⇒ 【PowerShell】対象PCへPingコマンドを実行する【PC死活監視】
$rst = Test-Connection 8.8.8.8 -Quiet
# Trueなら成功
$rst
あとはネットワークアドレス/サブネットマスク
からその中でホストがとりうるIPを自動計算することが出来れば自動でPingを打たせることが出来るはず。
IPアドレス計算
最終的にはForEach
で繰り返せる形に持っていきたいのでネットワークアドレス/サブネットマスク
の文字列(e.g. 192.168.1.0/24
)からホストの総数とホストの始まりとなる第4オクテットを抜き出せればよいはず。
イメージとしては下記の感じ。
$network = "192.168.37.0/24"
$networkAddress = $network.Split("/")[0]
$mask = $network.Split("/")[1]
# サブネットにあるIPの総数を求めそこからブロードキャストアドレスを引く
$hostCount = [Math]::Pow(2,(32 - $mask)) - 1
# ネットワークアドレスから第1 ~ 第3オクテットを切り出す
$firstToThird = $networkAddress.Split(".")[0..2] -join "."
# の第4 オクテットを切り出す
$forth = $subnetIp.Split(".")[3]
# 第4オクテットの値 + 1がそのサブネット内のホストの始まりとなる
$hostStart = [int]$forth + 1
入力した文字列を受け取る
PowerShellではRead-Host
で入力文字列を受け取ることが出来ます。
$result = Read-Host 何か入力してください
同期型の自動Pingスクリプト
ということで上記の組み合わせで自動Pingスクリプトを作ってみました。
funciton RangePing(){
$network = Read-Host Pingを打つネットワークを入力してください
$networkAddress = $network.Split("/")[0]
$mask = $network.Split("/")[1]
# サブネットにあるIPの総数を求めそこからブロードキャストアドレスを引く
$hostCount = [Math]::Pow(2,(32 - $mask)) - 1
# ネットワークアドレスから第1 ~ 第3オクテットを切り出す
$firstToThird = $networkAddress.Split(".")[0..2] -join "."
# の第4 オクテットを切り出す
$forth = $networkAddress.Split(".")[3]
# 第4オクテットの値 + 1がそのサブネット内のホストの始まりとなる
$hostStart = [int]$forth + 1
ForEach ($i in $hostStart..$hostCount){
$ipAddress = "$firstToThird.$i"
$res = Test-Connection $ipAddress -Quiet
$answer = ""
if($res){
$answer = "OK"
}
else{
$answer = "NG"
}
Write-Host "$ipAddress is $answer"
}
}
これで一つのサブネットの端から端までPingができるようになりました。
しかし、こいつは1つのPingが終わらないと次のPingを打ってくれないため終わるまでにはとても時間がかかってしまうというデメリットもあります。
あとは単純にWindowsのPingのデフォルトとして4回打っているからというのもあります。
ここはTest-Connection
の-Count
オプションで調整することができます。
非同期での並列処理をここに組み込めば解決しそうですが、これは次の課題とします。