概要
タイトル通り
環境
- Windows 11
スクリプト
# Visualize-Routes.ps1 (vis.jsを使用したHTMLベースの可視化)
param (
[string]$OutputPath = "$($PSScriptRoot)\network_routes.html",
[switch]$IncludeDefaultRoutes = $false,
[string[]]$ExcludeNextHops = @()
)
function Visualize-NetRouteGraph {
[CmdletBinding()]
param (
[string]$OutputPath = "$($PSScriptRoot)\network_routes.html",
[switch]$IncludeDefaultRoutes = $false,
[string[]]$ExcludeNextHops = @()
)
# ルーティング情報を取得
$routes = Get-NetRoute
# デフォルトルートを除外する場合
if (-not $IncludeDefaultRoutes) {
$routes = $routes | Where-Object { $_.NextHop -ne "::" -and $_.NextHop -ne "0.0.0.0" }
}
# 指定されたNextHopを除外する場合
if ($ExcludeNextHops.Count -gt 0) {
foreach ($excludeHop in $ExcludeNextHops) {
$routes = $routes | Where-Object { $_.NextHop -ne $excludeHop }
}
}
if (-not $routes) {
Write-Warning "ルーティング情報が見つかりませんでした。"
return
}
# ノードとエッジの定義
$nodes = @{}
$edges = @()
$nodeId = 0
$nodeMap = @{}
$edgeMap = @{} # エッジの重複を管理
foreach ($route in $routes) {
$destination = $route.DestinationPrefix
$nextHop = $route.NextHop
$ifIndex = $route.IfIndex
$interface = $null
# ネットワークアダプタ名を取得(エラーハンドリング付き)
try {
$interface = (Get-NetAdapter -IfIndex $ifIndex -ErrorAction Stop).Name
}
catch {
$interface = $null
}
# ノードの作成(重複なし)
if (-not $nodeMap.ContainsKey($destination)) {
$nodeMap[$destination] = @{
id = $nodeId
label = $destination
title = "Destination: $destination"
color = "lightblue"
shape = "box"
}
$nodeId++
}
if (-not $nodeMap.ContainsKey($nextHop)) {
$nodeMap[$nextHop] = @{
id = $nodeId
label = $nextHop
title = "NextHop: $nextHop"
color = "lightgreen"
shape = "ellipse"
}
$nodeId++
}
# エッジのキーを作成(重複チェック用)
# NextHop → Destination の向きにすることで、トラフィックフローを表現
$edgeKey = "$($nodeMap[$nextHop].id)->$($nodeMap[$destination].id)"
# エッジラベルの作成
$edgeInfo = "Metric: $($route.RouteMetric)"
if ($interface) {
$edgeInfo += " (via $interface)"
}
# 既存のエッジがあれば統合、なければ新規作成
if ($edgeMap.ContainsKey($edgeKey)) {
# 既存のエッジにラベルを追加
$edgeMap[$edgeKey].labels += $edgeInfo
}
else {
# 新規エッジを作成
$edgeMap[$edgeKey] = @{
from = $nodeMap[$nextHop].id
to = $nodeMap[$destination].id
labels = @($edgeInfo)
}
}
}
# エッジマップからエッジ配列を作成(ラベルを結合)
foreach ($edgeKey in $edgeMap.Keys) {
$edge = $edgeMap[$edgeKey]
$edges += @{
from = $edge.from
to = $edge.to
label = $edge.labels -join "`n"
}
}
# JSON形式でノードとエッジを作成
$nodesJson = $nodeMap.Values | ConvertTo-Json
$edgesJson = $edges | ConvertTo-Json
# HTMLテンプレートを生成
$htmlContent = @"
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ネットワークルーティンググラフ</title>
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
font-family: Arial, sans-serif;
}
#network {
width: 100%;
height: 100%;
border: 1px solid lightgray;
}
.controls {
position: absolute;
top: 10px;
left: 10px;
background: white;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 100;
}
button {
padding: 5px 10px;
margin: 5px 2px;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="controls">
<button onclick="resetView()">リセット</button>
<button onclick="fitToScreen()">画面に合わせる</button>
</div>
<div id="network"></div>
<script type="text/javascript">
var nodes = new vis.DataSet($nodesJson);
var edges = new vis.DataSet($edgesJson);
var container = document.getElementById('network');
var data = {
nodes: nodes,
edges: edges
};
var options = {
physics: {
enabled: true,
stabilization: {
iterations: 200
},
barnesHut: {
gravitationalConstant: -26000,
centralGravity: 0.3,
springLength: 300,
springConstant: 0.04,
damping: 0.3
}
},
nodes: {
font: {
size: 14,
color: 'black'
},
borderWidth: 2,
shadow: true
},
edges: {
arrows: 'to',
font: {
size: 12,
align: 'middle'
},
shadow: true,
smooth: {
type: 'continuous'
}
},
interaction: {
navigationButtons: true,
keyboard: true,
zoomView: true,
dragView: true
}
};
var network = new vis.Network(container, data, options);
function resetView() {
network.fit();
}
function fitToScreen() {
network.fit({
animation: {
duration: 1000,
easingFunction: 'easeInOutQuad'
}
});
}
window.addEventListener('resize', function() {
network.redraw();
});
network.fit();
</script>
</body>
</html>
"@
# HTMLファイルを保存
$htmlContent | Set-Content $OutputPath -Encoding UTF8
Write-Host "ネットワークルーティンググラフをHTMLで生成しました: $OutputPath"
Write-Host "ブラウザで表示しています..."
# ブラウザで開く
Invoke-Item $OutputPath
}
# 関数を実行(スクリプトの引数を渡す)
$params = @{
OutputPath = $OutputPath
}
if ($IncludeDefaultRoutes) {
$params['IncludeDefaultRoutes'] = $IncludeDefaultRoutes
}
if ($ExcludeNextHops.Count -gt 0) {
$params['ExcludeNextHops'] = $ExcludeNextHops
}
Visualize-NetRouteGraph @params
最後に
作成された HTML をブラウザ開けば OK です
0 件のコメント:
コメントを投稿