【问题标题】:PowerShell: Convert IP Address to SubnetPowerShell:将 IP 地址转换为子网
【发布时间】:2018-07-12 02:36:00
【问题描述】:

我能够使用 ff: 提取计算机的主机 IP 地址:

$IPAddr = Get-NetIPConfiguration -InterfaceAlias "Ethernet" | select IPv4Address 

如何根据子网掩码(如/24/20/16等)获取对应的子网地址?

因此,如果主机 IP 地址为192.168.100.45,子网掩码为/24255.255.255.0,则代码应获取192.168.100.0 的子网地址值。

【问题讨论】:

  • 查看this question的优秀答案;这是简单的二进制数学。
  • 确实如此,该链接为该特定帖子中的问题提供了极好的答案。但是对于这篇文章,在最简单的逻辑中,我希望获得有关如何将 CIDR SM 为/24 的变量$IPAddr(即192.168.100.45)的值转换为其对应的 SN 值的指导192.168.100.0,并将其传递给另一个变量以用于我的脚本的另一部分。
  • 你能解析来自netsh 输出的结果吗?说,netsh interface ip show config 'Ethernet' ?
  • 这个想法是使用纯粹的 PowerShell 命令来避免在运行脚本时调用 shell 之外的进程。但是,如果您可以建议一个代码,从上述netsh one-liner 的输出中去除子网地址值,然后将该值直接传递给另一个命令的变量,那么无论如何都值得一试。
  • 由于目标是确定计算机的实际子网地址(而不仅仅是子网掩码),如果在 PS 中可以有比计算或转换的值更简单的方法吗?由另一个命令输出,那就太好了。

标签: powershell networking ip


【解决方案1】:

您可以使用IPAddress 类。示例:

[IPAddress] (([IPAddress] "192.168.100.45").Address -band ([IPAddress] "255.255.255.0").Address)

这将输出一个包含 IP 地址192.168.100.0IPAddress 对象。

要将位计数转换为等效的位掩码字符串,可以使用如下函数:

function ConvertTo-IPv4MaskString {
  param(
    [Parameter(Mandatory = $true)]
    [ValidateRange(0, 32)]
    [Int] $MaskBits
  )
  $mask = ([Math]::Pow(2, $MaskBits) - 1) * [Math]::Pow(2, (32 - $MaskBits))
  $bytes = [BitConverter]::GetBytes([UInt32] $mask)
  (($bytes.Count - 1)..0 | ForEach-Object { [String] $bytes[$_] }) -join "."
}

使用这个函数,你可以写:

[IPAddress] (([IPAddress] "192.168.100.45").Address -band ([IPAddress] (ConvertTo-IPv4MaskString 24)).Address)

这会输出一个包含 IP 地址 192.168.100.0IPAddress 对象。

其他几个函数可能有用:

function Test-IPv4MaskString {
  param(
    [Parameter(Mandatory = $true)]
    [String] $MaskString
  )
  $validBytes = '0|128|192|224|240|248|252|254|255'
  $MaskString -match `
    ('^((({0})\.0\.0\.0)|'      -f $validBytes) +
    ('(255\.({0})\.0\.0)|'      -f $validBytes) +
    ('(255\.255\.({0})\.0)|'    -f $validBytes) +
    ('(255\.255\.255\.({0})))$' -f $validBytes)
}

function ConvertTo-IPv4MaskBits {
  param(
    [parameter(Mandatory = $true)]
    [ValidateScript({Test-IPv4MaskString $_})]
    [String] $MaskString
  )
  $mask = ([IPAddress] $MaskString).Address
  for ( $bitCount = 0; $mask -ne 0; $bitCount++ ) {
    $mask = $mask -band ($mask - 1)
  }
  $bitCount
}

ConvertTo-IPv4MaskBitsConvertTo-IPv4MaskString 的倒数,并使用 Test-IPv4MaskString 来验证掩码是否为有效的 IPv4 掩码。

我不久前写的一篇文章中提供了更多详细信息:

IT Pro Today - Working with IPv4 Addresses in PowerShell

【讨论】:

  • 感谢您的详细回答,其中包括必要的功能,当然还有您的文章。非常有帮助。可以在任何可能的前缀和子网掩码下工作。 =)
  • 这是很棒的东西。工作得很好
【解决方案2】:

Microsoft 的 IP 地址实现非常缓慢,不幸的是,他们还将八位字节值的顺序错误。对于所有与 IP 相关的计算,我决定更好地使用我自己的函数。这是我的代码-sn-p:

function ipNr($s) {
    [byte[]]$ip = $s.Split(".")
    [array]::Reverse($ip)
    [bitconverter]::ToUInt32($ip,0)
}

function ipString($n) {
    $ip = [bitconverter]::GetBytes($n)
    [array]::Reverse($ip)
    [string]::Join(".", $ip)
}

function maskNr($b) {
    (1 -shl $b)-1 -shl (32-$b)
}

$ip = "192.168.100.45"
$prefixLength = 24
$subnetId = ipString ((ipNr $ip) -band (maskNr $prefixLength)) 
write-host "$subnetId/$prefixLength"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 2013-05-09
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多