先日「PowerShell 複数のコマンドプロンプトを引数付きで実行するサンプル」を投稿しました。
あとから考えると「コマンドプロンプトを複数個起動するのはカッコ悪い」、「そのためにわざわざPowerShell使う必要性はないだろ?」と思ったので、PowerShell スクリプト1本で複数個所にPingを定期送信するスクリプトを書いてみました。
背景
無線LANのアクセスポイントが不定期で不安定になるケースを何度も経験しています。現象は下記のとおり。
- Pingの応答速度が100~2000ms、又は到達不能
- アクセスポイントを再起動すると一時的に改善する
- Pingを定期的に送信し続けると「なぜか」安定する(謎現象)
パワーセーブモードやアンテナの出力など設定箇所を微調整してみましたが、解決に至っていません。残念・・・
PowerShell からPingを定期送信する
本題に戻ります。Windows 標準機能でPingを送信する方法として
- Ping コマンド
- Test-Connection コマンドレット
- System.Net.NetworkInformation.Ping クラス
(個人的主観になりますが)実際に触った限り、下記特性がありました。
実行結果が高速に表示され、かつ、出力結果を成形できる点から今回のサンプルではSystem.Net.NetworkInformation.Ping クラスを使います。
サンプル
サンプル スクリプトは、送信先を指定しPingを定期的に送信させます。
送信する間隔やログ出力の有無を指定できるので、paramステートメント内の変数を適時修正してください。
param(
#ログ出力を有効or無効
[bool]$logOutputSwitch = $false,
#Ping送信先
[string[]]$ips = @("192.168.1.1","192.168.1.2","192.168.1.3"),
#実行秒間隔
[int]$sec = 3,
#ログ フォルダ名
[string]$folder = "d:\log",
#ログ ファイル名
[string]$file = "Pinger.log"
)
#ログ フォルダ作成
if($logOutputSwitch -eq $true){
if((Test-Path -Path $folder) -eq $False){
try{
#ログ フォルダ作成
New-Item -Path $folder -ItemType directory | Out-Null
}
catch{
#フォルダ作成に失敗した場合はc:\tempフォルダを作成
$folder = 'c:\log'
New-Item -Path $folder -ItemType directory | Out-Null
}
}
}
#ログファイル名
$file = "$folder\$file"
#Pingクラス
$ping = New-Object System.Net.NetworkInformation.Ping
#無限ループ
#中止はCtrl+C
while($true){
$log = "----------------------------------------`n"
$log += "Exec Time:$(Get-Date)`n"
$log += "IP Address`tTime(ms)`n"
$ips | ForEach-Object{
try{
#RTTを取得
$rtt = $ping.Send($_).RoundtripTime
$log += "$_`t$rtt`n"
}
catch{
#エラーの場合
$log += "$_`tError`n"
}
}
#ログ出力
if($logOutputSwitch -eq $true){
#ログファイルへ出力
$log | Out-File -FilePath "$file" -Encoding default -Append
}
else{
#コンソールへ出力
Write-Host $log
}
#スリープ
Start-Sleep -Seconds $sec
}
実行結果は下記のようになります。
※出力は分かりやすくするためスクリーンショットの一部を着色しています。
動作確認が取れたOS
- Windows 7 64bit + WMF 4.0
- Windows Server 2008 R2 64bit + WMF 4.0
- Windows 10 64bit

