将 IP 地址与文本文件进行比较 - Power Shell

compare IP address with text file - Power Shell

提问人:user18209625 提问时间:5/15/2023 最后编辑:user18209625 更新时间:5/15/2023 访问量:51

问:

我有一个包含数百个条目的大型 txt 文件,如下所示:

AUT-NE;server1.test.root.local;10.164.202.0;30-254
AUT-DE;server2.test.root.local;10.164.202.0;30-254
AUT-LI;server3.test.root.local;10.164.22.0;1-254
....

所以 txt 文件的结构是:location; servername;IP 网络地址;IP 范围

我想将 IP 地址(=>字符串)与 txt 文件进行比较,并检查哪个服务器是正确的服务器。 例如:客户端的 IP 地址为 10.164.22.101,则正确的服务器将是 server3.test.root.local,因为 10.164.22.101 在 10.164.22.1 -10.164.22.254 范围内。

因此,在这种情况下,我的输出应该是这样的:“找到匹配项:server3”

如何使用 Powershell 执行此操作?

我有

$ip = "10.164.22.101"
$sep = $ip.LastIndexOf(".")

$network = $ip.substring(0,$sep) 
$node = $ip.substring($sep+1)

所以$network是 10.164.22,$node是 101。

但是,如何进行正确的节点比较并找到匹配的服务器呢?

谢谢!

字符串 列表 PowerShell 比较 文本文件

评论


答:

1赞 iRon 5/15/2023 #1

请参阅:性能注意事项/在大型集合中按属性查找条目

通常需要使用共享属性来标识不同集合中的同一记录,例如使用名称从一个列表中检索 ID,从另一个列表中检索电子邮件。循环访问第一个列表以在第二个集合中查找匹配的记录速度很慢。特别是,第二个集合的重复筛选有很大的开销。

# $List =  Import-Csv -Delimiter ';' .\List.csv
$List = ConvertFrom-Csv -Delimiter ';' @'
location;servername;IP Network Address;IP Range
AUT-NE;server1.test.root.local;10.164.202.0;30-254
AUT-DE;server2.test.root.local;10.164.202.0;30-254
AUT-LI;server3.test.root.local;10.164.22.0;1-254
'@

相反,请创建一个哈希表,该表使用相关子网作为键,并使用匹配对象作为值:

$LookupHash = @{}
$List| Foreach-Object {
    $LookupHash[$_.'IP Network Address' -Replace '(?<=\d+\.\d+\.\d+)\..*'] = $_
}

在哈希表中查找键比按属性值筛选集合要快得多。PowerShell 可以检查是否定义了密钥并使用其值,而不是检查集合中的每个项。

$LookupHash['10.164.22.101' -Replace '(?<=\d+\.\d+\.\d+)\..*'].servername
server3.test.root.local

关于附加问题的更新

在这里学到了一些新东西,但是如果两行具有相同的前 3 个八位字节怎么办。例如:
AUT-NE;server1.test.root.local;10.164.202.0;0-50
AUT-DE;server2.test.root.local;10.164.202.0;50-254

在这种情况下,您可以将字典引用到具有相同子网的对象列表:

$LookupHash = @{}
$List| Foreach-Object {
    $Subnet = $_.'IP Network Address' -Replace '(?<=\d+\.\d+\.\d+)\..*'
    if ($LookupHash.ContainsKey($Subnet)) {
        $LookupHash[$Subnet].Add($_)
    }
    else {
        $LookupHash[$Subnet] = [Collections.Generic.List[Object]]$_
    }
}
$LookupHash['10.164.202.101' -Replace '(?<=\d+\.\d+\.\d+)\..*'].servername
server1.test.root.local
server2.test.root.local

评论

0赞 Dilly B 5/15/2023
在这里学到了一些新东西,但是如果两行具有相同的前 3 个八位字节怎么办。例如:AUT-NE;server1.test.root.local;10.164.202.0;0-50 AUT-DE;server2.test.root.local;10.164.202.0;51-254
0赞 iRon 5/15/2023
我已经在您的评论中更新了答案,并提出了其他问题
0赞 Dilly B 5/15/2023 #2

我只是在尝试,但有点复杂,而且在一大堆清单上不是最快的

$servers = Get-content C:\PSProject\somefile.txt
$ip = "10.164.22.1"

foreach ($server in $servers) {

$range = $server.split(";")[2] #to get ip address from server variable

$numbertoCheck = $server.Split(";")[3]   # to get the range 0-254
[int]$firstNum = $numbertoCheck.Split("-")[0] # 0
[int]$endNum = $numbertoCheck.Split("-")[1]   # 254



$fromRange = $range.Substring(0, $range.LastIndexOf(".")) # to get 10.164.22 from server variable
$fromIP = $ip.Substring(0, $ip.LastIndexOf("."))          # to get 10.164.22 from ip variable


[int]$iplastOctet = $ip.split(".")[3] # to get last octet from ip variable

if ( ($fromIP -eq $fromRange) -and ([int]$firstNum -le [int]$iplastOctet) -and ([int]$endNum -ge [int]$iplastOctet) ) { # if True

        Write-Host "Match found in $($server.Split(";")[1])"

  }
}