如何使用PowerShell获取IP地址

IT管理员可以通过PowerShell和命令行完成许多任务;处理Windows网络就是其中之一。在本教程中,您将学习如何使用PowerShell通过Get-NetIPAddress命令和WMI从Windows计算机的网络适配器获取IP地址。

先决条件

本教程将假定您正在运行Windows 10或更高版本,并已安装了Windows PowerShell v5.1。同时假定您处于Active Directory环境中。如果不是,请务必了解New-CimSession命令的Credential属性

使用Get-NetIPAddress

PowerShell拥有各种cmdlet,用于处理网络连接,例如Get-NetAdapterGet-NetAdapterBinding,甚至还有一个专门用于查找IP地址的Get-NetIPAddress。如果你想在简单的脚本中使用PowerShell获取IP地址,务必使用这些cmdlet。

保持简单。如果PowerShell提供了更简单的方法来完成某事,请使用它!

例如,要在本地计算机上查找所有网络适配器的IPv4地址,运行一行命令。

Get-NetIPAddress -AddressFamily IPV4
Finding IPV4 addresses with Get-NetIPAddress

上面的输出引用了特定的网络适配器,如以太网适配器,并仅返回IP地址。

Getting the IP address from a specific adapter

完成了!仅使用PowerShell获取IP地址是一个简单的过程,至少比使用其他手段要简单得多。

如果你不喜欢PowerShell,你还可以使用ipconfig命令来获取IP地址。在你需要了解的Ipconfig命令中了解更多关于ipconfig的信息。

为什么要使用CIM/WMI?

当你运行`Get-NetIPAddress` cmdlet时,PowerShell实际上是在查询WMI以检索该信息。为什么知道这一点很重要呢?因为你可以直接自己查询WMI。但为什么要使用WMI,而不是使用一个单一的命令呢?

使用WMI而不是像`Get-NetIPAddress`这样的单一命令的最常见原因之一是当你已经在查询WMI时。WMI包含许多在构建用于清单目的的脚本时非常有用的系统信息。

在使用PowerShell与WMI通信时,你可以创建一个类似于PSRemoting会话的CIM会话。使用会话是一种有效的方式,可以在一次身份验证计算机并重复使用该连接。

在构建作为较大脚本一部分的任务时,使用CIM获取IP地址。

在没有会话的情况下查询CIM

当你正在使用CIM构建PowerShell脚本来查询各种信息时,应该使用可重用的CIM会话。重用单个会话不仅加速脚本运行,还减少代码重复。

对于例子,也许你想查找远程 Windows 计算机正在运行的操作系统。CIM 在 Win32_OperatingSystem 类的 Caption 属性中保存操作系统名称。要获取这些信息,你可以使用下面的Get-CimInstance cmdlet,指定计算机名称 (REMOTECOMPUTER)、CIM 类 (Win32_OperatingSystem),并仅引用对象上的 Caption 属性。

(Get-CimInstance -ComputerName REMOTECOMPUTER -ClassName Win32_OperatingSystem).Caption

当运行 Get-CimInstance 时,PowerShell 必须找到远程计算机,将登录凭据传递给它,并最终查询 CIM 以获取所需的信息。在没有会话的情况下运行 Get-CimInstance 会带来很多开销。

如果你正在构建服务器清单脚本,还想查找关于存储、内存、网络等的信息呢?在这种情况下,你会有很多像下面这样的 Get-CimInstance 命令。

Get-CimInstance -ComputerName REMOTECOMPUTER -ClassName Win32_LogicalDisk
Get-CimInstance -ComputerName REMOTECOMPUTER -ClassName Win32_OperatingSystem
Get-CimInstance -ComputerName REMOTECOMPUTER -ClassName Win32_PhysicalMemory
Get-CimInstance -ComputerName REMOTECOMPUTER -ClassName Win32_NetworkAdapter

在上述代码片段中,你的脚本将连接到 REMOTECOMPUTER 四次,如果计算机名称更改怎么办?你将不得不查找/替换计算机名称,这在编码时永远不是一个好迹象。

创建 CIM 会话

与使用会话的 Get-CimInstance 不同,你应该使用 New-CimSession cmdlet 创建一个单一的 CIM 会话,并重复使用该会话。

而不是一遍又一遍地对远程计算机进行身份验证,可以使用New-CimSession创建单个CIM会话,然后像下面这样将该会话传递给Get-CimInstance

$remoteComputer = 'REMOTECOMPUTER'
$cimSession = New-CimSession -ComputerName $remoteComputer

Get-CimInstance -CimSession $cimSession -ClassName Win32_LogicalDisk
Get-CimInstance -CimSession $cimSession -ClassName Win32_OperatingSystem
Get-CimInstance -CimSession $cimSession -ClassName Win32_PhysicalMemory
Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapter

会话结束后,断开连接并从内存中删除。

$cimSession | Remove-CimSession

像上面这样使用CIM会话是使用CIM/WMI的好方法。

找到正确的网络适配器

由于Windows计算机可能具有不同的网络适配器,您必须首先缩小范围,确定要从中获取IP地址的网络适配器。使用WMI时,请使用Win32_NetworkAdapterConfiguration类。该类提供了Get-NetIPAddress返回的大部分信息。

首先,使用远程计算机的名称创建一个PowerShell脚本,然后创建一个新的CIM会话,然后在其下方添加CIM会话移除行。

$remoteComputer = 'REMOTECOMPUTER'
$cimSession = New-CimSession -ComputerName $remoteComputer

$cimSession | Remove-CimSession

构建CIM会话代码后,插入WMI查询。

$remoteComputer = 'REMOTECOMPUTER'
$cimSession = New-CimSession -ComputerName $remoteComputer

Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapterConfiguration

$cimSession | Remove-CimSession
Querying WMI with a CIM session to get network adapter information

您可以看到上面的默认输出不显示IP地址。您需要深入了解一下。它也不返回单个实例。如何缩小范围以找到您要查找的IP地址的适配器?

为此,请首先使用Select-Object显示所有属性。

Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapterConfiguration | Select-Object -Property *

浏览输出,您会注意到一些没有IP地址的网络适配器,一些有一个IP地址,一些有多个IP地址!您必须将其限制下来。您必须找到一些标准标准以对其进行过滤,以便它适用于所有服务器。

Lots of output from The Win32_NetworkAdapterConfiguration class!

在每个适配器上,您应该看到IPEnabled属性。当此属性设置为True时,TCP/IP协议将绑定到此网卡,这是拥有IP地址的先决条件。您必须将具有IPEnabled属性设置为True的网卡缩小范围,然后您就能找到所需的适配器。

在过滤WMI实例时,最好使用Get-CimInstance上的Filter参数。PowerShell社区有一句座右铭,它说“向左过滤”。如果有机会,这句话意味着始终尽可能向左过滤输出。

除非必须,否则不要使用Where-Object。由于处理不必要对象的开销减少,性能会快得多。

Get-CimInstance上的Filter参数使用Windows查询语言(WQL)。WQL是SQL的一个小子集。Filter参数期望与SQL相同的约束WHERE子句语法。

要找到所有IPEnabled属性设置为True的Win32_NetworkAdapterConfiguration类的CIM实例,请使用SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'True' WQL查询。

由于我们已经在Get-CimInstance中为ClassName参数指定了类名,所以我们需要在Filter中指定IPEnabled = 'True'。这样将只返回带有IP地址的网络适配器。

Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'" | Select-Object -Property *

当您运行上述代码片段时,您应该看到Get-CimInstance只返回一个(或有限的一组)实例。

现在您有了一个单一的 CIM 实例,并且知道您要查找的属性(IPAddress),让我们看看它是什么样子的。您将看到,在这个实例中,它返回了一个单一的 CIM 实例,但是IPAddress属性有三个字符串,包括 IPV6 地址。

(Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'").IPAddress

192.168.0.40
fe80::e4e1:c511:e38b:4f05
2607:fcc8:acd9:1f00:e4e1:c511:e38b:4f05

您需要进一步过滤一些元素。因为 WQL 无法深入过滤IPAddress属性值,所以现在您必须解析出 IPv4 地址。

IPv4 地址通常是数组中定义的第一个。通过引用索引 0 来挑选出这个。当您这样做时,您将看到它只返回一个单独的 IPV4 IP 地址字符串。

(Get-CimInstance -CimSession $cimSession -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'").IPAddress[0]

192.168.0.40

IPv4 地址可能并不总是数组的第一个元素。实际上,IPAddress 属性甚至可能不是一个数组。不同适配器和各种配置的 IP 配置差异巨大。您可能需要在过滤它们时有所创意。

结论

如果您需要使用 PowerShell 从计算机获取 IP 地址,请首先查看 Get-NetIPAddress 命令。如果您正在编写一个更大的脚本或由于某些原因无法运行此命令,请考虑使用 Get-CimInstance 和 CIM 会话来完成这项工作。

Source:
https://adamtheautomator.com/powershell-get-ip-address/