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を取得したい

制限

記事の制限は以下です。

  • WMI禁止
  • IPCONFIG禁止
  • $env:ComputerName or localhostでPC名参照禁止
  • 返戻値はIP Addressオブジェクトであること
  • Windows 8や他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

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

制限からは外れますので一応ということで。 Windows 8/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がイーサネットでないものも取得されます。

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

さて、既存のイーサネット一覧は以下で取得出来ます。

(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

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

よってイーサネットのアドレスに限定したい場合は以下になります。

(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もプロパティから指定可能です。

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

コマンドレットでインタフェース毎に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を使わせないなら以下です。

制限

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

解法

[Net.Dns]::GetHostName()

結果は以下です。

Windows8Prox64

コマンドレットの解法

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

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 : Windows 8/2012以降のコマンドレットで全インターフェースに関して取得
(Get-NetIPAddress).IPAddress
""
#4 : インターフェース全体の取得
(Get-NetIPAddress).InterfaceAlias
""
#5 : Windows 8/2012以降のコマンドレットでインターフェースを指定して取得
Get-NetIPAddress | where {$_.InterfaceAlias -eq "イーサネット"} | select -ExpandProperty IPAddress
""
#6 : Windows 8/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