我有一个包含数百个条目的大型 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;服务器名称; 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.
但是我怎样才能进行正确的节点比较并找到匹配的服务器呢?
谢谢!
通常需要使用共享属性来标识不同集合中的相同记录,例如使用名称从一个列表中检索 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.Contains($Subnet)) {
$LookupHash[$SubNet].Add($_)
}
else {
$LookupHash[$SubNet] = [Collections.Generic.List[Object]]$_
}
}
我只是在尝试,但有点复杂,而且对一个巨大的列表来说不是最快的
$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])"
}
}