PowerShell:将IP地址转换为子网

4

我可以使用以下方法提取我的计算机主机IP地址:

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

如何根据子网掩码(例如/24/20/16等)获取其对应的子网地址?
如果主机IP地址为192.168.100.45,子网掩码为/24255.255.255.0,则代码应该获取子网地址值为192.168.100.0

请参考这个问题的优秀答案,它涉及简单的二进制数学。 - Ron Maupin
确实,那个链接提供了一个非常好的答案来回答那篇特定帖子中的问题。但是对于这篇文章,在最简单的逻辑中,我希望得到如何将变量 $IPAddr 的值(即 192.168.100.45)和其 CIDR 子网掩码 /24 转换为相应的网络地址 192.168.100.0 的指导,并将其传递给另一个变量以用于脚本的另一部分。 - Jee
你能解析netsh输出的结果吗?比如说,netsh interface ip show config 'Ethernet' - vonPryz
这个想法是使用纯PowerShell命令,在运行脚本时避免调用外部进程。但如果您能建议一个代码,可以从上述netsh单行输出中剥离子网地址值,并直接将该值传递给另一个命令的变量,那么这绝对值得一试。 - Jee
由于目标是确定计算机的实际子网地址(而不仅仅是子网掩码),如果在 PowerShell 中有比从另一个命令输出的值进行计算或转换更简单的方法,那就太好了。 - Jee
2个回答

7
您可以使用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 - PowerShell中使用IPv4地址的方法

感谢您提供详细的答案,其中包括必要的函数,当然还有您的文章。非常有帮助。可以在任何可能的前缀和子网掩码中使用。=) - Jee
那是很棒的东西。运行得非常好。 - Rodrigo Werlang

3

微软的IP地址实现非常慢,而且不幸的是他们也将八进制值按错误顺序排列。对于所有与IP相关的计算,我决定使用自己的函数效果更好。这是我的代码片段:

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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接