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)





2025年6月15日日曜日

Windows環境 pythonでのPing統計 試行するも課題あり

某所で例示してもらったスクリプト


import csv

import subprocess

import tkinter as tk

from tkinter import filedialog

from datetime import datetime

import os


def ping(ip, log_lines):

    success_count = 0

    log_lines.append(f"\n=== Ping開始: {ip} ===")

    for i in range(3):

        cmd = ["ping", "-n", "1", "-w", "200", ip]

        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

        if result.returncode == 0:

            success_count += 1

        log_lines.append(f"\n-- Try {i+1} --")

        log_lines.append(result.stdout.strip())

        if result.stderr:

            log_lines.append("Error:")

            log_lines.append(result.stderr.strip())

    log_lines.append(f"=== Ping結果: {ip} -> {'OK' if success_count == 3 else 'NG'} ===")

    return "OK" if success_count == 3 else "NG"


# ファイル選択ダイアログ

root = tk.Tk()

root.withdraw()

file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])


if file_path:

    now_dt = datetime.now()

    log_filename = now_dt.strftime("%Y%m%d-%H%M") + ".log"

    timestamp = now_dt.strftime("%Y/%m/%d %H:%M")


    log_lines = [

        f"Ping 実施日時: {now_dt.strftime('%Y/%m/%d %H:%M:%S')}",

        f"対象CSV: {os.path.basename(file_path)}",

        "-" * 50

    ]


    # CSV読み込み

    with open(file_path, newline="", encoding="utf-8") as f:

        reader = list(csv.reader(f))


    header = reader[0]

    if timestamp in header:

        print(f"{timestamp} の列がすでに存在しています。")

        exit()


    header.append(timestamp)

    updated_rows = [header]


    for row in reader[1:]:

        if len(row) >= 1:

            ip = row[0].strip()

            if ip:

                result = ping(ip, log_lines)

                row += [""] * (len(header) - len(row) - 1)

                row.append(result)

        updated_rows.append(row)


    # CSVバックアップと保存

    backup_path = file_path + ".bak"

    os.rename(file_path, backup_path)

    with open(file_path, "w", newline="", encoding="utf-8") as f:

        writer = csv.writer(f)

        writer.writerows(updated_rows)


    # ログファイル書き出し

    with open(log_filename, "w", encoding="utf-8") as f:

        f.write("\n".join(log_lines))


    print(f"Ping結果を {file_path} に保存しました。")

    print(f"詳細なping出力ログ: {log_filename}(バックアップ: {backup_path})")


else:

    print("ファイルが選択されませんでした。")