Windows 10 v1809 の vEthernet (Default Switch) の IPアドレスが再起動ごとに変更される謎の現象への対処法

何度も書いているが、先日自宅PCのHDDが壊れてSSDに換装したついでにWindows10をクリーンインストールしたのだが、PC環境を刷新したいくつか問題が起きている。
今日は、Hyper-V で起きた問題とその応急処置的対処法について書く。
現象は次のようなモノだ。
Windows10を新規インストール後、Hyper-Vを有効にして仮想環境にUbuntuとCentOSをインストールした。
デフォルト設定のインストールではネットワーク設定はDHCPになっている。
DHCP設定のままならLinux(Ubuntu,CentOS)はインターネットに繋がる。
各Linuxのネットワーク設定を固定IPにしたところインターネットに繋がらなくなった。
当初はLinux側の設定が悪いのだろうと思い色々調べたが間違いが見当たらない。
物理NICと直接繋がる既定仮想スイッチ(Default Switch)のIPアドレスが起動する度変わってしまう。
Linuxから固定IPを設定するにはゲートウェイのIPを指定する必要があり、まずゲートウェイのIPを固定する必要がある。
以前HDDで使用していたWindows10ではゲートウェイのIPを固定IPにすることができていたはずだが、SSDに再インストールした最新Windows10はできなくなっている。
誤解の無いように言っておくが、ここで言うゲートウェイのIPアドレスというのは、物理ネットワークのゲートウェイではなく、Hyper-Vの中に形成される仮想ネットワークのゲートウェイである。
Hyper-V上で稼働する全てのOSはそれぞれが独自の仮想NICを持つ。
Hyper-VにPC本体の物理NICが接続されており、この物理NICに既定仮想スイッチ(Default Switch)が繋がれている。
Windows 10 を含めて、Hyper-V上の仮想環境で稼働するOSは全て、それぞれの仮想NICで、既定仮想スイッチ(Default Switch)に繋がることで、間接的に物理NICに接続し、インターネット(物理ネットワーク)に接続することができる。
やや不自然だが、既定仮想スイッチにはイーサーネットアダプターとしてIPアドレスが付けられており、仮想OSはこの既定仮想スイッチのIPアドレスをゲートウェイとして指定することにより、外部の物理ネットワークに接続出来た。
以前は、既定仮想スイッチまわりの仕様が、現在と違っており、仮想環境のOSはゲートウェイに物理ネットワークのゲートウェイのIPアドレスを指定することができていた。
しかし、最新のWindows10では、物理ゲートウェイを参照することができず、仮想ゲートウェイである既定仮想スイッチを指定しなければならない。
もう一つの違いが、以前は既定仮想スイッチのIPアドレスは固定IPにすることができたが、最新ではできなくなっている点である。
仮想ゲートウェイである既定仮想スイッチのIPアドレスが再起動ごとに変わる可変IPになってしまったため、仮想OS側のIPを固定IPにできなくなってしまったのだ。
(DHCPにすると繋がる)

ネットの情報

ネットの情報を調べてみると、同じ問題に遭遇している人が居る。
Windows10 Build1809のHyper-Vで、規定のスイッチのネットワークアドレスが変わってしまう【Ver1809】
質問のようだが、返事は返ってきていないようだ。
謎: Windows 10 ver 1809 の Default Switch の NAT サブネットが起動ごとに変わる件
この人は、非常に詳しく調べている。
私もマイPCのイベントビューアーを見てみると、ソースが「Hyper-V-VmSwitch」のイベントが沢山発生しており内容を見てみると起動の度に、
イベントID=233
The operation ‘Delete’ succeeded on nic [MACアドレス] (Friendly Name: Default Switch).
イベントID=233
The operation ‘Create’ succeeded on nic  [MACアドレス] (Friendly Name: Default Switch).
イベントID=232
NIC  [MACアドレス] (Friendly Name: Default Switch) successfully connected to port  [MACアドレス] (Friendly Name: Default Switch) on switch  [MACアドレス](Friendly Name: Default Switch).
イベントID=9
Switch [MACアドレス] (Friendly Name: Default Switch) successfully initialized.
イベントID=264
Port [MACアドレス] (Friendly Name: Container NIC [NIC番号]) successfully created on switch [MACアドレス] (Friendly Name: Default Switch).
というイベントが発生している。
「The operation ‘Delete’ succeeded on nic [MACアドレス] (Friendly Name: Default Switch).」
と来て、
「The operation ‘Create’ succeeded on nic  [MACアドレス] (Friendly Name: Default Switch).」
となるわけだから、起動の度に既定仮想スイッチ(Default Switch)を削除して再作成しているのだ。
これでは既定仮想スイッチ(Default Switch)に固定IPなど付番できるわけけがない。
先のブログ記事を読む限り、どうも1809アップデートから既定仮想スイッチの仕様が変わったらしい。
仕様が変わったと言うよりも、構造が変わったようだ。
私は以前の環境で1803を使っていたのだろうか ?
最新版をアップデートしていたつもりだが。
先のブログ記事に
「新仕様なのかバグなのかは不明。」
とあるが、これは「仕様」だろう。
明らかに「構造的問題」だ。

仮想環境のOS(Linux)が固定IPを使えるようにする対処法

先の説明を見て貰えればわかるように、Windows 10 の Hyper-V は既定仮想スイッチ(Default Switch)を起動する度、削除して再作成しているので、固定IPアドレスを付番するのは構造的に無理だと思う。
ただ、Windows 10 起動後に毎回、既定仮想スイッチ(Default Switch)に同じIPアドレスを付番してやることは可能なようだ。
そもそも既定仮想スイッチはその名の通り「スイッチ」であり「ルーター」ではない。
※(ハブとスイッチの機能の違い
)
既定仮想スイッチにIPアドレスが付番できることが既に不自然な現象だ。
どうして「スイッチ」がイーサネットカードになっているのだ ?
イーサネットカードとイーサネットカードをL2で繋ぐのが「スイッチ」ではないのか ?
そのイーサネットカードはL2に居るのか ?
それは本当にイーサネットカードなのか ?
※(L2スイッチに管理用IPを付番できるものもあるがこれはスイッチの機能とは関係なく管理用CPUに接続する為にIPが付番されています
【図解】L2スイッチのIPアドレスとデフォルトゲートウェイ, 複数IPについて
)
Hyper-V ワールドは仮想世界。
目の前で「既定仮想スイッチにIPアドレスが付番され、それをゲートウェイにしてDHCP設定でインターネットにアクセスできる」という非日常な現象が起こっている。
この仮想世界ではきっと魔法が使えるのだろう。
だからきっと「スイッチに固定IPを付番する(自分でも何言っているか分からない)」という魔法が存在するに違いない !
と考え、調べてみた。
参考にしたのは以下の記事だ。
PowerShellの使い方(OS設定編)
「6. IPの固定化
ADなど一部のサービスではDHCPではなくIPを固定化して利用することが推奨されています。そうでなくてもサーバとして運用する場合はIPを固定化して運用するのが普通です。
この章ではそのためのコマンドレットを記載します。」
【自分用メモ】PowerShellによるIPアドレスの設定及び変更
「PowerShellでIPアドレスを設定する場合は、まず、Remove-NetIPAddressしてからNew-NetIPAddressするという手順を踏む。」
「静的なIPアドレスの設定      New-NetIPAddress  ……..」
New-NetIPAddress
「新NetIPAddressのコマンドレットは作成してIPアドレスを設定します。特定のIPアドレスオブジェクトを作成するには、IPv4アドレスまたはIPv6アドレスのいずれかと、インターフェイスインデックスまたはインターフェイスエイリアスを指定します。サブネットマスクとも呼ばれるプレフィックス長とデフォルトゲートウェイを定義することをお勧めします。
このコマンドレットを実行して、DHCPが既に有効になっているインターフェイスにIPアドレスを追加すると、DHCPは自動的に無効になります。インターフェイスで重複アドレス検出(DAD)が有効になっている場合、新しいIPアドレスはDADが正常に終了するまで使用できず、リンク上のIPアドレスの一意性が確認されます。」
New-NetIPAddress コマンドでIPアドレスを指定すると、DHCPは自動的に無効になるらしい。
Get-NetAdapter コマンドでネットワークアダプタの情報が得られる。
管理者権限で PowerShell を開き、以下のように Get-NetAdapter を実行する。
Get-NetAdapter
Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
—-                      ——————–                    ——- ——       ———-             ———
vEthernet (External_Vi… Hyper-V Virtual Ethernet Adapter             27 Up           70-54-D2-8F-AF-84       100 Mbps
イーサネット              Intel(R) 82579V Gigabit Network Conn…      25 Up           70-54-D2-8F-AF-84       100 Mbps
vEthernet (External_Wi… Hyper-V Virtual Ethernet Adapter #4          24 Disconnected B0-C7-45-63-38-D2        10 Gbps
Wi-Fi                     BUFFALO WI-U2-433DM Wireless LAN Ada…      16 Disconnected B0-C7-45-63-38-D2          0 bps
vEthernet (DockerNAT)     Hyper-V Virtual Ethernet Adapter #5          15 Up           00-15-5D-00-07-13        10 Gbps
ネットワーク ブリッジ     Microsoft Network Adapter Multiplexo…       8 Disconnected B0-C7-45-63-38-D2          0 bps
vEthernet (HvsiIcs)       Hyper-V Virtual Ethernet Adapter #3          65 Up           12-15-DF-71-76-0A        10 Gbps
vEthernet (Default Swi… Hyper-V Virtual Ethernet Adapter #2          30 Up           12-15-DF-5D-88-6C        10 Gbps
New-NetIPAddress コマンドでIPアドレスを作成するには
「特定のIPアドレスオブジェクトを作成するには、IPv4アドレスまたはIPv6アドレスのいずれかと、インターフェイスインデックスまたはインターフェイスエイリアスを指定します。」
とある。
ifIndex が Get-NetAdapter の結果に表示されているので、これを使用してみる。
私のネットワーク環境は物理ゲートウェイが「192.168.0.1」なので、「192.168.0.2」を仮想ゲートウェイに割り当てる。
サブネットマスクは「255.255.255.0/24」なので、「24」を指定する。
既定仮想スイッチ(Default Switch)のインターフェイスインデックスが「30」と表示されている。
以下のように New-NetIPAddress を実行してみた。
New-NetIPAddress -IPAddress 192.168.0.2 -PrefixLength 24 -InterfaceIndex 30
IPAddress         : 192.168.0.2
InterfaceIndex    : 30
InterfaceAlias    : vEthernet (Default Switch)
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Manual
SuffixOrigin      : Manual
AddressState      : Tentative
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource      : False
PolicyStore       : ActiveStore
IPAddress         : 192.168.0.2
InterfaceIndex    : 30
InterfaceAlias    : vEthernet (Default Switch)
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Manual
SuffixOrigin      : Manual
AddressState      : Invalid
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource      : False
PolicyStore       : PersistentStore
成功した !
ipconfig で確認すると、
イーサネット アダプター vEthernet (Default Switch):
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: XXXX::XXXX:XXXX:XXXX:XXXX
   IPv4 アドレス . . . . . . . . . . . .: 172.17.XXX.XXX
   サブネット マスク . . . . . . . . . .: 255.255.255.240
   IPv4 アドレス . . . . . . . . . . . .: 192.168.0.2
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .:
仮想スイッチにIPアドレスが、「172.17.XXX.XXX」と「192.168.0.2」の2つ付いている。
意味が分からん !
さすが魔法の国、Hyper-V ワールド !
(サブネットマスクが物理側と仮想側で異なるので、2つのIPアドレスが付くらしい。
何でもありだなHyper-V ワールド!)
早速、Hyper-V マネージャーを起動し、仮想環境の Ubuntu を起動して固定IP設定でゲートウェイに「192.168.0.2」を指定してインターネットに接続してみたところ、見事に繋がった。
Windows10を再起動すると、IPアドレス「192.168.0.2」は消滅していた。
仮想スイッチ自体を起動する度に削除して再作成しているのだから、当然だ。
Get-NetAdapter でインターフェイスインデックスを確認すると以前と違う値が割り当てられていた。
つまり、起動する度に、
「Get-NetAdapter」で InterfaceIndex の値を確認し、「New-NetIPAddress」でvEthernet (Default Switch)にIPアドレス「192.168.0.2」を割り当てなければならないことになる。
デスクトップにコマンドラインのメモを配置し、起動する度に管理者権限でPowerShellから実行するだけだから、大した手間ではないが、なんとか自動化したい。
Get-NetAdapter
New-NetIPAddress -IPAddress 192.168.0.2 -PrefixLength 24 -InterfaceIndex ??
これを一々実行するのはプログラマーとしてはかっこ悪い。
とり会えず、自動化の方法を調べたところ以下のようなスクリプトを組めば良いと分かった。
InitIPDefaultSwitch.ps1 ファイル
$ifi = (Get-NetAdapter -Name ‘vEthernet (Default Switch)’).InterfaceIndex
New-NetIPAddress -IPAddress 192.168.0.2 -PrefixLength 24 -InterfaceIndex “$ifi”
後は、起動する度にスタートアップでこの「InitIPDefaultSwitch.ps1」を実行すれば良いはずだ。
PowerShell ではデフォルトでは、デジタル署名のないps1スクリプトの実行を禁じているので、以下のコマンドでPC内部で作成されたps1ファイルの実行だけ許可する設定に変更する。
現在のセキュリティを確認する
Get-ExecutionPolicy
「AllSigned」なら署名のないスクリプトは実行できない。
管理者権限のPowerShellコマンドプロンプトで以下のコマンドを実行する。
Set-ExecutionPolicy RemoteSigned
再び現在のセキュリティを確認する
Get-ExecutionPolicy
「RemoteSigned」が表示されれば成功。
この辺の解説はこちらを見てください。
【PowerShell】外部ファイル実行時にポリシーエラーが発生する際の対処方法
この設定を行えばあとは「InitIPDefaultSwitch.ps1」を起動時に管理者権限で実行すれば、既定仮想スイッチ(Default Switch)のIPアドレスを毎回固定IPに自動で変更できるようになる。

タスクスケジューラーでps1を実行する

Windows 10 Pro にはタスクスケジューラーという標準ツールがある。
このツールは好きなプログラムを好きなタイミングで自動起動・終了させることができる。
主にバッチ処理の起動に使用される。
このタスクスケジューラで、先ほどの「InitIPDefaultSwitch.ps1」をOS起動時に呼び出してやる。
ただ、タスクスケジューラの使い方は色々コツが必要で、一筋縄では行かない。
それをここで懇切丁寧に書くことはできない。
記事が長くなりすぎる。
タスクスケジューラの使い方については、別の解説サイトがあるのでそちらを見て欲しい。
ここでは簡単に設定方法だけ、記述する。
スクリプトファイルの配置
(1)「C:MySetting」というフォルダーを作る。
(2)そこに「InitIPDefaultSwitch.ps1」ファイルを置く。
C:Usersusername 配下に「InitIPDefaultSwitch.ps1」ファイルを置いても動きません。
必ずユーザープロファイルの外にps1ファイルを置いてください。
タスクスケジューラーの操作
(1)「Windowキー + S」を押して、タスクスケジューラーと入力して起動する。
(2)タスクスケジューラーの画面右側の「基本タスクの作成」を押し「基本タスクの作成」画面を開く。
(3)基本タスクの「名前」には「既定仮想スイッチの固定IP設定」と書く「説明」は好きにして。
(4)トリガーは「コンピュータの起動時」を選ぶ。
(5)操作は「プログラムの開始」を選ぶ。
(6)プログラムの開始は
 「プログラム/スクリプト」には「C:WindowsSystem32WindowsPowerShellv1.0powershell.exe」 を入力する。
 (PowerShell 7 の場合は「”C:Program FilesPowerShell7pwsh.exe”」 になります。
“” を忘れないように !)
 「引数の追加」には「-Command “.InitIPDefaultSwitch.ps1″」を入力する。
 「開始」には「C:MySetting」を入力する。
 「次へ」を押す。
 「完了」を押す。
(7)「最新の情報に更新」を押し、中央の一覧表から「名前」が「既定仮想スイッチの固定IP設定」を選んで、左下の「選択した項目」メニューの「プロパティ」を押す。
(8)「既定仮想スイッチの固定IP設定のプロパティ」画面が開くので、「全般」の「セキュリティオプション」を以下のように変更する。
「タスクの実行時に使うユーザーアカウント」を「NETWORK SERVICE」にする。
(これで自動的に「ユーザーがログオンしているかどうかにかかわらず実行する」に切り替わる)
「最上位の特権で実行する」を選択(有効に)する。
「OK」を押して画面を閉じる。
これで「既定仮想スイッチの固定IP設定」の設定は完了です。
確認の為にOSを再起動して、ログインしてから数分待って、PowerShellを開き、「ipconfig」を実行し、vEthernet (Default Switch) の IPv4 の設定を確認してください。
追加したIPアドレス(私の場合は192.168.0.2)が表示されていれば成功です。
タスクスケジューラーはとても扱いが難しく、細かいミスで動かなくなる。
ネットにタスクスケジューラーの情報が沢山あるので、ご自分で調べて欲しい。
健闘を祈る !
タイトルとURLをコピーしました