2025年8月3日日曜日

なんやかんや半日がかりのPing/Tracerouteツール

そもそもPowerShellで実行できるかどうか。

Quittaのこちら様から。
PowerShellでこのシステムではスクリプトの実行が無効になっているため、ファイル hoge.ps1 を読み込むことができません。となったときの対応方法 #Windows10 - Qiita

PS C:> Get-ExecutionPolicy

だめだったら次。

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process 

 

上記をクリアののちにスクリプト。全面協力は某先生。

 
main.ps1

trap {
    $_ | Out-File -Append "$PSScriptRoot\error_log.txt"
    break
}


# ユーザー入力(TAG)
$tag = Read-Host "ログファイルの識別子(例:1-1)を入力してください"

# 固定値とIPリスト
$site = "SiteA"
$ipList = @("27.86.32.14", "111.108.12.174", "202.93.74.46")
$positions = @(
    @{X=0;   Y=0},     # 左上
    @{X=960; Y=0},     # 右上
    @{X=0;   Y=540}    # 左下
)

# 実行時刻(hhmmss)
$timestamp = Get-Date -Format "HHmmss"

# 各ウィンドウ起動
for ($i = 0; $i -lt $ipList.Count; $i++) {
    $ip = $ipList[$i]
    $pos = $positions[$i]
    Start-Process powershell -ArgumentList "-ExecutionPolicy RemoteSigned -NoExit -File `"$PSScriptRoot\monitor.ps1`" $tag $site $ip $timestamp $($pos.X) $($pos.Y)"

}


次にtracerouteとping

monitor.ps1

param (
    [string]$Tag,
    [string]$Site,
    [string]$IP,
    [string]$Stamp,
    [int]$X,
    [int]$Y
)

# ログファイルフルパスの取得
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$logName = "$Tag" + "_" + "$Site" + "_" + "$IP" + "_" + "$Stamp" + ".log"
$logPath = Join-Path $scriptDir $logName

# ウィンドウ移動処理を非表示で呼び出し
Start-Process powershell -WindowStyle Hidden -ArgumentList "-ExecutionPolicy Bypass -File move_window.ps1 $X $Y"

# traceroute の実行とログ出力
"----- Traceroute to $IP -----" | Out-File -FilePath $logPath -Encoding Default

# traceroute結果の保存(エンコード指定付き)
# $traceResult = tracert -d -h 12 $IP
# $traceResult | Out-File -FilePath $logPath -Append -Encoding Default

tracert -d -h 12 $IP |
    Tee-Object -Variable traceDisplay |
    Out-File -FilePath $logPath -Append -Encoding Default

$traceDisplay | Write-Output


# ping のループ実行(1秒毎)
while ($true) {
    $now = Get-Date -Format "HH:mm:ss"
    Write-Host "[$now] pinging $IP"
    Add-Content $logPath "[$now]"
    ping -n 1 -w 1000 $IP | Add-Content $logPath
    Start-Sleep -Seconds 1
}

Write-Host "`nスクリプトの終了を確認するには、Enterキーを押してください..."
Read-Host


# 初期行(タイトル)


そして、実は目的を果たせなかったもうひとつ。

move_window.ps1

param (
    [int]$X,
    [int]$Y
)

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("user32.dll")]
    public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);
}
"@

Start-Sleep -Milliseconds 500  # ウィンドウ準備待機
$hwnd = (Get-Process -Id $PID).MainWindowHandle
[Win32]::MoveWindow($hwnd, $X, $Y, 960, 540, $true)