2012年1月6日金曜日

Win2k8R2: WMIを使ってNICのアダプタ名から接続名を調べたりIPアドレスを変更したり。

Windowsの接続名("ローカル エリア接続"とか)はいい加減!
サーバにはNIC(Network Interface Card)が複数付いているのが当たり前である。
WindowsのNICには、通常 "ローカル エリア接続"、"ローカル エリア接続 2"…という具合に自動的に連番の接続名(NetConnectionID)が付けられるが、この名前付けはどうもランダムに行われているようで、まったく同じ構成のサーバでも、違う名前が付いたりすることがよくある。
一方、NICのデバイス名(デバイス マネージャーやコントロールパネルで見えるやつ)はブレることがまずない。
例えば最近のHPのサーバで、NICがNC382iの場合、デバイス名は1番ポートから順に
  • HP NC382i DP Multifunction Gigabit Server Adapter
  • HP NC382i DP Multifunction Gigabit Server Adapter #2
  • HP NC382i DP Multifunction Gigabit Server Adapter #3
という具合に名前が付いており、同一構成のサーバを同じようにキッティングすれば、同じ名前が付く(上はあくまで例で、必ず#2,#3…となるわけではない。悪しからず)。
どのNICがどの接続名になっているのかを知るにはコントロールパネルを見ればいい。デバイス名と接続名が両方表示される。

Figure.1 コンパネで接続名とデバイス名を見る
※上の実行例は、私の自宅リビングのWindows7 PCでの結果。Windows Server 2008での実行結果でなくて申し訳ない。

しかし、同じ構成のサーバを何十台、何百台と構築する場合、いちいち目視で確認などしていられない。
(実際には本番環境のサーバはチーミングを組む事が多いが、ここでは横においておく)。
VBScriptを使って、デバイス名をキーに接続名を調べてみる

以下は、WMIを使ってデバイス名から接続名を調べるVBScriptである。
引数にデバイス名を与えると、対応する接続名が表示される。
' GetNetConnectionIDfromAdapterName.vbs
' Get Network Adapter Name and NetConnectionID
' 2011.12.17 dsp74118

option explicit

Function GetNetConnectionID(adapterName)

 dim computer
 dim wmiService
 dim netAdapter
 dim netAdapters
 dim targetConnectionID

 computer = "."
 GetNetConnectionID = "Not Found"

 set wmiService = GetObject("winmgmts:\\" & computer & _
         "\root\CIMV2")
 set netAdapters = wmiService.ExecQuery( _
  "SELECT * FROM Win32_NetworkAdapter")

 For Each netAdapter in netAdapters
  if netAdapter.Name = adapterName then
   GetNetConnectionID = _
                         netAdapter.NetConnectionID
   exit for
  end if
 Next

End Function

' main
dim adapterName
dim connectionID
adapterName = WScript.Arguments.Item(0)
connectionID = GetNetConnectionID(adapterName)
WScript.Echo adapterName & " = " & connectionID
Figure.2 実行例
※上の実行例は、私の自宅リビングのWindows7 PCでの結果。Windows Server 2008での実行結果でなくて申し訳ない。

これで任意のNICの接続名を取得することに成功したので、後は
Dim wshShell
set wshShell = WScript.CreateObject("Wscript.Shell")
wshShell.run("netsh -c interface set interface name=""" & _
 connectionID & """ newname=""ServiceLan""")
とかやって接続名を変更してみたり、
wshShell.run("netsh interface ip set address """ & _
 connectionID & """ static " & _
 "192.168.0.108 255.255.255.0 192.168.0.1 1")
とかやってIPアドレスを変更してみたりなど、やりたい放題。
実はPowerShellだと…
PowerShellにはGet-WmiObjectというコマンドがあって、同じ事がもう少し簡単に(かつカッコよく)できたりする。

PowerShellでIPアドレスを変更してみる
$nicconf = Get-WmiObject win32_networkadapterconfiguration |
 Where-Object {$_.Description -eq "デバイス名"}
$nicconf.EnableStatic("192.168.0.108","255.255.255.0")
$nicconf.SetGateways("192.168.0.1")
$DNSServers = "192.168.0.1","8.8.8.8"
$nicconf.SetDNSServerSearchOrder($DNSServers)
PowerShellで接続名を変更してみる
$nic = Get-WmiObject Win32_NetworkAdapter |
 Where-Object {$_.Name -eq "デバイス名"}
$nic.NetConnectionID = "ServiceLan"
$nic.Put()
やはり、これからの時代はPowerShell使いになるしかないな。

0 コメント:

コメントを投稿