先日「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