IP change alert state machineでは、表示名ではなくInterfaceIndexとsorted IPv4 snapshotを最初の対象キーにします。変更や集計へ進む前に前回JSONを読む前のcurrent/previous二世代を保存し、別対象を同じ結果へ混ぜないことが出発点です。
この手順の合格条件は「previousとcurrentを比較後に新snapshotを保存した状態」です。Microsoft Learn:Get-NetIPAddressのstable keyとCompare-Objectによる保存前差分が定義するGet-NetIPAddressのstable keyとCompare-Objectによる保存前差分を根拠にし、画面へ値が出たことだけを成功とは判定しません。
停止条件:初回実行・VPN/APIPA・一時addressを区別できない。該当するときは操作を進めず、旧state fileをbackupから戻しtaskを無効化するを実行可能な形で確認してから再計画します。
IP change alert state machine|結論を検証可能な形にする:previousとcurrentを比較後に新snapshotを保存した状態
IPアドレス変更の検知の変更幅は一端末・一ユーザー・一設定に絞ります。Join-Pathの前にIP、DNS、ゲートウェイ、NetworkCategory、接続中の管理経路を退避し、Get-NetIPAddressが不一致なら追加変更を止めます。
Get-NetIPAddressとGet-NetIPAddressの差分は、変更を意図した列だけである必要があります。現在のRDPやVPNが唯一の管理経路で、変更後に再接続できない場合は作業を中止し、状態ファイル作成前に保存先とACLを確認する。監視停止時はスケジュールタスクと状態ファイルを別々に確認し、他用途のファイルを触らない。
| 判断要素 | IPアドレス変更の検知で記録する内容 |
| 対象の識別 | InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイル |
| 最初の確認 | Get-NetIPAddress |
| 変更または操作 | Join-Path |
| 再確認 | Get-NetIPAddress |
| 中止条件 | 現在のRDPやVPNが唯一の管理経路で、変更後に再接続できない |
Get-NetIPAddressは次のように読み取りから実行します。出力を整形する前のオブジェクトも残し、InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルを欠落させないようにします(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
$current = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '169.254*' -and $_.PrefixOrigin -ne 'WellKnown' } | Select-Object InterfaceAlias, IPAddress, PrefixLength
$current
IPアドレス変更の検知の出力が複数行なら、InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルで目的の一行を特定します。フィルターで消えたエラー件数も別に記録します。
IP change alert state machine|同名候補を内部識別子で分ける:InterfaceIndexとsorted IPv4 snapshot
IPアドレス変更の検知で使うPowerShellの版は $PSVersionTable で、コマンドの提供元は Get-Command Get-NetIPAddress で確認します。通常ユーザー。ProgramDataへの書き込みは管理者。対象候補が複数ならInterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルを使い、表示名の部分一致だけで選びません(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
- IPアドレス変更の検知: 実行端末と現在ユーザーを記録する
- Get-NetIPAddress: Source、Version、利用可能なパラメーターを確認する
- InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイル: 変更前の値を日時付きで保存する(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
- IP、DNS、ゲートウェイ、NetworkCategory、接続中の管理経路: 復旧に使えることを読み取り確認する(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
- 現在のRDPやVPNが唯一の管理経路で、変更後に再接続できない: 該当すれば本番実行を見送る
「はじめに」を検証する際は名前解決、経路、TCP到達性、アダプター状態を別々に測る順序を崩しません。IPアドレス変更の検知の別スコープや別ユーザーの値を混ぜないことが重要です。
監視対象はInterfaceIndexで固定し、VPN、仮想NIC、169.254のAPIPA、WellKnown由来を除外したIPv4一覧を並べ替えてbaselineにします。状態ファイル用ディレクトリのACLを確認し、初回実行は警告せず現在値を保存するだけにします。DHCP更新時刻とPrefixOriginも参考値として残し、正規のリース更新を障害と混同しません。
「基本のコード」を検証する際は名前解決、経路、TCP到達性、アダプター状態を別々に測る順序を崩しません。IPアドレス変更の検知の別スコープや別ユーザーの値を混ぜないことが重要です。
コードは前回と現在のInterfaceIndex、IPAddress、PrefixLengthをCompare-Objectで比較し、差分がある時だけローカル警告を出します。比較に成功した後で状態を更新し、外部送信や通知失敗によって正しいbaselineを失わない順序にします。
IPアドレス変更の検知で「保存先の選定」を扱うときは、保存先の選定の表示名だけでなくInterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルを記録します。Get-NetIPAddressでも同じ対象が返ることを確かめます。
IP変更検知のbaselineにはInterfaceIndex、AddressFamily、IPAddress、PrefixOriginを並べ替えて保存します。初回はbaseline作成だけで通知せず、次回に同じキー集合をCompare-Objectへ渡して差分がある場合だけalertします。
IPアドレス変更の検知の検証ではGet-NetIPAddressが返すオブジェクトを文字列だけに変換せず、固有IDと状態列を残します。後段の比較に使えるためです。
Where-ObjectはIPアドレス変更の検知の2番目の確認手段です。Get-Help Where-Object -Fullで利用できるパラメーターを調べ、出力型と対象件数を記録します(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
IPアドレス変更の検知の検証ではSelect-Objectが返すオブジェクトを文字列だけに変換せず、固有IDと状態列を残します。後段の比較に使えるためです。
Join-PathはIPアドレス変更の検知の4番目の確認手段です。Get-Help Join-Path -Fullで利用できるパラメーターを調べ、出力型と対象件数を記録します(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
IPアドレス変更の検知の検証ではSet-Contentが返すオブジェクトを文字列だけに変換せず、固有IDと状態列を残します。後段の比較に使えるためです。
Write-WarningはIPアドレス変更の検知の6番目の確認手段です。Get-Help Write-Warning -Fullで利用できるパラメーターを調べ、出力型と対象件数を記録します。
IP change alert state machine|復旧に必要な値を退避する:旧state fileをbackupから戻しtaskを無効化する
IPアドレス変更の検知の変更前にはIP、DNS、ゲートウェイ、NetworkCategory、接続中の管理経路を保存します。保存したファイルや値が実際に読めることを確認し、同じ端末内の上書きだけをバックアップと呼びません(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
IPアドレス変更の検知でJoin-Pathを使う例は一対象に限定しています。WhatIfを利用できる場合は先に対象を表示し、外部コマンドでは読み取りオプションか検証端末を使います(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
$stateDirectory = Join-Path $env:ProgramData 'ITtrip'
$state = Join-Path $stateDirectory 'ip-state.json'
$previous = if (Test-Path -LiteralPath $state) { Get-Content -LiteralPath $state -Raw | ConvertFrom-Json } else { $null }
$current = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '169.254*' -and $_.PrefixOrigin -ne 'WellKnown' } | Select-Object InterfaceIndex, InterfaceAlias, IPAddress, PrefixLength | Sort-Object InterfaceIndex, IPAddress
New-Item -ItemType Directory -Path $stateDirectory -Force | Out-Null
if ($null -ne $previous) {
$difference = Compare-Object -ReferenceObject @($previous) -DifferenceObject @($current) -Property InterfaceIndex, IPAddress, PrefixLength
if ($difference) { Write-Warning 'IPv4 address set changed' }
} else {
Write-Verbose 'Initial run: baseline created without an alert' -Verbose
}
$current | ConvertTo-Json | Set-Content -LiteralPath $state -Encoding utf8
Join-Pathの出力では対象件数、警告、終了コードを確認します。途中まで成功した場合は、変更済みと未変更を分けて記録します。
IP change alert state machine|件数と識別値で合否を決める:previousとcurrentを比較後に新snapshotを保存した状態
Get-NetIPAddressでは、変更前に保存したInterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルと同じ対象を選びます。名前解決、経路、TCP到達性、アダプター状態を別々に測ることで、別スコープの値を成功結果として採用しません(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
$saved = Get-Content -LiteralPath $state -Raw | ConvertFrom-Json
$live = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '169.254*' -and $_.PrefixOrigin -ne 'WellKnown' } | Select-Object InterfaceIndex, InterfaceAlias, IPAddress, PrefixLength | Sort-Object InterfaceIndex, IPAddress
Compare-Object -ReferenceObject @($saved) -DifferenceObject @($live) -Property InterfaceIndex, IPAddress, PrefixLength
- Get-NetIPAddress: 同じ対象IDを再取得できた
- IPアドレス変更の検知: 意図した値または件数だけが変化した
- 名前解決、経路、TCP到達性、アダプター状態を別々に測る: 関連機能も異常がない
- 対象インターフェースの選択違い、VPNや仮想NIC、IPv4/IPv6の取り違え: 取得失敗をゼロ件として扱っていない(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
- VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する。監視対象インターフェースを限定し、IPを外部へ無断送信しない。: 環境固有の制約に反していない
IP change alert state machine|不明な状態を成功へ丸めない:初回実行・VPN/APIPA・一時addressを区別できない
IPアドレス変更の検知でアクセス拒否が出た場合は、すぐ管理者として再実行せず通常ユーザー。ProgramDataへの書き込みは管理者という必要範囲を確認します。対象側のACLや管理ロールも分けて調べます。
IPアドレス変更の検知が時間経過後に元へ戻る場合は、GPO/MDM、同期、サービス再起動、別スコープを調べます。繰り返し上書きして管理設定と競合させません。
VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する。監視対象インターフェースを限定し、IPを外部へ無断送信しない。 この条件を満たさない結果は、コマンドの終了コードが0でも合格にしません。
断定できません。IPアドレス変更の検知では対象インターフェースの選択違い、VPNや仮想NIC、IPv4/IPv6の取り違えでも空になります。エラーを表示し、権限とスコープを確認してからGet-NetIPAddressまたは別の公式な取得方法で照合します。
IP change alert state machine|復旧失敗時の停止点を置く:旧state fileをbackupから戻しtaskを無効化する
状態ファイル作成前に保存先とACLを確認する。監視停止時はスケジュールタスクと状態ファイルを別々に確認し、他用途のファイルを触らない。
IPアドレス変更の検知を戻した後はGet-NetIPAddressとGet-NetIPAddressを再実行し、InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルが変更前記録と一致することを確認します。復旧処理にも失敗したら連続操作を止め、保存したIP、DNS、ゲートウェイ、NetworkCategory、接続中の管理経路とログを担当者へ渡します(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
IP change alert state machine|引継ぎに必要な列を残す:前回JSONを読む前のcurrent/previous二世代
- Get-NetIPAddressの実行時刻、対象件数、エラー件数を残した
- InterfaceAlias、InterfaceIndex、IPアドレス、接続プロファイルで対象を一意に特定した(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。
- IP、DNS、ゲートウェイ、NetworkCategory、接続中の管理経路を変更前に保存して読めることを確認した(IPアドレス変更の検知の判断では「VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する」を優先し、Get-NetIPAddressが空なら成功扱いしません)。
- Join-Pathの対象を一端末・一ユーザー・一設定に限定した
- Get-NetIPAddressと実利用テストの両方を確認した
- 現在のRDPやVPNが唯一の管理経路で、変更後に再接続できない場合は実行を中止した
IP change alert state machine|運用で生じる疑問を切り分ける:初回baselineでは警告を出すべきか
権限だけが原因とは限りません。VPN、仮想NIC、APIPA、IPv6一時アドレスで変化が頻発する。監視対象インターフェースを限定し、IPを外部へ無断送信しない。 現在のRDPやVPNが唯一の管理経路で、変更後に再接続できないなら昇格して続行せず、対応Edition、対象ID、ポリシー、復旧経路を確認します(IPアドレス変更の検知では通常ユーザーの範囲でGet-NetIPAddressが返す固有値を基準にします)。

コメント