tech.guitarrapc.cóm

Technical updates

PowerShellでIPアドレスやHOSTNAMEを取得

さて、面白い試みの記事があります。
Find a list of all IP addresses assigned to the local system
やっている事は簡単で、制限付きの状況で、PCにアサインされている全てのIP Addressを取得しなさいというモノです。 で、勝者の基準は簡単「短いコード」であること。 さてさて。

IP ADDRESSを取得したい

制限

記事の制限は以下です。
  1. WMI禁止
  2. IPCONFIG禁止
  3. $env:ComputerName or localhostでPC名参照禁止
  4. 返戻値はIP Addressオブジェクトであること
  5. Windows8や他OSのネットワークコマンドレット使用禁止

解法

この制限って.Net使うしかないんじゃ…ということでこれかなー。
[Net.Dns]::GetHostAddresses("").IPAddressToString
結果は以下です。※IPv6はマスクしています
fe80::xxxx:xxxx:xxxx:xxxx%13
fe80::yyyy:yyyy:yyyy:yyyy%15
192.168.50.60
2001:0:zzzz:zzzz:zzzz:zzzz:zzzz:zzzz
これなら、生きているIP Addressのみが取得できるのでいいですね。

全てのインターフェースを取得する解法

全てのインターフェースの、となると…以下でしょうか。
[Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces().GetIPProperties().UnicastAddresses | % {$_.Address.IPAddressToString}
結果は以下です。
fe80::xxxx:xxxx:xxxx:xxxx%13
192.168.50.60
fe80::wwww:wwww:wwww:wwww%12
169.254.94.86
::1
127.0.0.1
fe80::vvvv:192.168.50.60%14
2001:0:zzzz:zzzz:zzzz:zzzz:zzzz:zzzz
fe80::yyyy:yyyy:yyyy:yyyy%15

Windows8以降のコマンドレットで全てのインターフェースのアドレスを取得

制限からは外れますので一応ということで。 Windows8/2012以降に追加されたWMI3.0のコマンドレットを利用していいなら、以下のやり方でも出ます。
(Get-NetIPAddress).IPAddress
結果は以下です。
fe80::xxxx:xxxx:xxxx:xxxx%13
fe80::wwww:wwww:wwww:wwww%12
fe80::yyyy:yyyy:yyyy:yyyy%15
2001:0:zzzz:zzzz:zzzz:zzzz:zzzz:zzzz
fe80::vvvv:192.168.50.60%14
::1
192.168.50.60
169.254.94.86
127.0.0.1
ただしInterfaceAliasがイーサネットでないものも取得されます。

Windows8以降のコマンドレットで既存のイーサネット一覧を取得したい

さて、既存のイーサネット一覧は以下で取得出来ます。
(Get-NetIPAddress).InterfaceAlias
結果は以下です。
イーサネット 2
イーサネット
Teredo Tunneling Pseudo-Interface
Teredo Tunneling Pseudo-Interface
isatap.{537212D5-9148-4F65-8521-8F69C06955FE}
Loopback Pseudo-Interface 1
イーサネット 2
イーサネット
Loopback Pseudo-Interface 1

Windows8以降のコマンドレットで特定インターフェースのアドレスのみ取得

よってイーサネットのアドレスに限定したい場合は以下になります。
(Get-NetIPAddress | where {$_.InterfaceAlias -eq "イーサネット"}).IPAddress
結果は以下です。
fe80::xxxx:xxxx:xxxx:xxxx%13
192.168.50.60
あるいは、これでしょう。
Get-NetIPAddress | where {$_.InterfaceAlias -eq "イーサネット"} | select -ExpandProperty IPAddress
結果は以下です。
IPAddress
---------
fe80::xxxx:xxxx:xxxx:xxxx%13
192.168.50.60
コマンドレットで取得する場合、IPAddressToStringをしなくともIP Addressオブジェクトです。 また、IPv4AddressやIPv6Addressもプロパティから指定可能です。

Windows8以降のコマンドレットでインターフェース毎のアドレスを取得

コマンドレットでインターフェース毎にIP Addressを取得するサンプルです。
Get-NetIPAddress | sort InterfaceAlias | select InterfaceAlias,IPAddress
結果は以下です。
InterfaceAlias                            IPAddress
--------------                            ---------
isatap.{xxxx-xxxx}                        fe80::vvvv:192.168.50.60%14
Loopback Pseudo-Interface 1               127.0.0.1
Loopback Pseudo-Interface 1               ::1
Teredo Tunneling Pseudo-Interface         fe80::yyyy:yyyy:yyyy:yyyy%15
Teredo Tunneling Pseudo-Interface         2001:0:zzzz:zzzz:zzzz:zzzz
イーサネット                               169.254.94.86
イーサネット                               fe80::wwww:wwww:wwww:wwww%12
イーサネット 2                             fe80::xxxx:xxxx:xxxx:xxxx%13
イーサネット 2                             192.168.50.60

HostNameの取得はできるの?

出来ます。 同じ制限でhostnameを使わせないなら以下です。

制限

  1. WMI禁止
  2. HOSTNAME禁止
  3. $env:ComputerName or localhostでPC名参照禁止
  4. 返戻値はHOSTNAMEオブジェクトであること
  5. Windows8や他OSのネットワークコマンドレット使用禁止

解法

[Net.Dns]::GetHostName()
結果は以下です。
Windows8Prox64

コマンドレットの解法

また、コマンドレットなら以下です。(Windows8以前でも利用できる…はずです。) ※複数同じ名称が出るため、select -UniqueでComputerNameの重複を一つにまとめています。
Get-NetIPConfiguration | select ComputerName -Unique
結果は以下です。
Windows8Prox64

環境変数の解法

制限にかかりますので一応ということで
$env:ComputerName
結果は以下です。
Windows8Prox64

HOSTNAMEの解法

制限にかかりますので一応ということで
hostname
結果は以下です。
Windows8Prox64

まとめ

それぞれの手法を出したのは結果が微妙に異なり、また利用できる状況毎の例を考えるためです。 正直WMIを利用するのは最終手段にしたいとことなので、今回挙げたやり方が自分の中では決定版です。 が、もっといいやり方がないかなー、というところではありますので…ぜひコメントをいただけると幸いです。 以下にソースを纏めました。 参考になれば幸いです。
# ---------------------------------------------------
# IP Addressを取得
# ---------------------------------------------------

#1 : .Netリソースからlive interfaceのみ取得
[Net.Dns]::GetHostAddresses("").IPAddressToString
""
#2 : .NetリソースからAll interfaceを取得
[Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces().GetIPProperties().UnicastAddresses | % {$_.Address.IPAddressToString}
""
#3 : Windows8/2012以降のコマンドレットで全インターフェースに関して取得
(Get-NetIPAddress).IPAddress
""
#4 : インターフェース全体の取得
(Get-NetIPAddress).InterfaceAlias
""
#5 : Windows8/2012以降のコマンドレットでインターフェースを指定して取得
Get-NetIPAddress | where {$_.InterfaceAlias -eq "イーサネット"} | select -ExpandProperty IPAddress
""
#6 : Windows8/2012以降のコマンドレットでインターフェース毎にIPAddressを取得
Get-NetIPAddress | sort InterfaceAlias | select InterfaceAlias,IPAddress
""



# ---------------------------------------------------
# HOSTNAMEを取得
# ---------------------------------------------------

#1 : .Netリソースからホスト名を取得
[Net.Dns]::GetHostName()
""
#2 : コマンドレットでホスト名を取得
Get-NetIPConfiguration | select ComputerName -Unique
""
#3 : 環境変数でホスト名を取得
$env:ComputerName
""
#4 : %windir%\system32\hostname.exeでホスト名を取得
hostname