Powershell – 从文件中获取主机名的IP地址(超过150,000个主机名)

huangapple go评论72阅读模式
英文:

Powershell - Get IP Addresses for hostnames from File (more than 150K hostnames)

问题

我的代码:

$Servers = Get-Content -Path "./FULl_List_hosts_all_CSV_V2.txt"
$Array = foreach($Server in $Servers) {
    $Server = $Server.Trim()
    try {
        $DNSCheck = [System.Net.Dns]::GetHostEntry($Server)
        # 只输出一个对象以便在变量 $Array 中收集
        [PsCustomObject]@{ 
            '服务器名称' = $Server  # 或 $DNSCheck.HostName
            'IP地址'  = ($DNSCheck.AddressList | Where-Object {$_.AddressFamily -eq 'InterNetwork'})[0].IPAddressToString
        }
    }
    catch {
        # 要么在此处什么都不做以跳过此服务器,要么输出一个 'n/a' 对象
        [PsCustomObject]@{ 
            '服务器名称' = $Server
            'IP地址'  = 'n/a'
        }
    }
}

# 在屏幕上输出
$Array | Format-Table -AutoSize

# 写入 CSV
$Array | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation 

Full_List_Hosts 中有超过 150,000 个主机名。当我运行脚本时,它会一直运行。毫无疑问,它正在加载所有内容,但是否有办法让它计数到大约 200,然后暂停,写入 CSV 文件,然后继续?如果我使用较短的文件,脚本会在几秒内完成。只是想确保它确实在运行。欢迎推荐。谢谢。

我尝试使用较短的主机列表文件,运行正常。我想要一些指示,表明它正在运行,而不仅仅是坐在那里呈现出 "愚蠢的表情",然后在运行数小时后什么都没有找到。

英文:

My code:

$Servers = Get-Content -Path "./FULl_List_hosts_all_CSV_V2.txt"
$Array = foreach($Server in $Servers) {
    $Server = $Server.Trim()
    try {
        $DNSCheck = [System.Net.Dns]::GetHostEntry($Server)
        # just output an object so it gets collected in variable $Array
        [PsCustomObject]@{ 
            'Server name' = $Server  # or $DNSCheck.HostName
            'IP Address'  = ($DNSCheck.AddressList | Where-Object {$_.AddressFamily -eq 'InterNetwork'})[0].IPAddressToString
        }
    }
    catch {
        # either do nothing here to skip this server of output a 'n/a' object
        [PsCustomObject]@{ 
            'Server name' = $Server
            'IP Address'  = 'n/a'
        }
    }
}

# output on screen
$Array | Format-Table -AutoSize

# write to csv
$Array | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation 

The Full_List_Hosts has more than 150K hostnames. When I run the shell script it sits there. No doubt loading it all - but is there a way I can make it count up to maybe 200 then pause, write to the csv file then continue?
If I do a shorter file - the script takes seconds to complete.
Just want to make sure it is truly running.
OPen to recomendations.
thanks

I tried using a shorter list of hosts in a file. worked fine.
I want some indicaton that it is running and not just sitting there with a "dumb look" only to come after HOURS of running and find nothing.

答案1

得分: 1

只需按照其设计使用PowerShell管道

Get-Content -Path "./FULl_List_hosts_all_CSV_V2.txt" | Foreach-Object {
    $Server = $_.Trim()
    $Output = try {
        $DNSCheck = [System.Net.Dns]::GetHostEntry($Server)
        # 只输出一个对象以便在变量$Array中收集
        [PsCustomObject]@{ 
            '服务器名称' = $Server  # 或者$DNSCheck.HostName
            'IP地址'  = ($DNSCheck.AddressList | Where-Object {$_.AddressFamily -eq 'InterNetwork'})[0].IPAddressToString
        }
    }
    catch {
        # 要么在这里什么都不做以跳过此服务器,要么输出一个'n/a'对象
        [PsCustomObject]@{ 
            '服务器名称' = $Server
            'IP地址'  = 'n/a'
        }
    }
    $Output | Format-Table -AutoSize | Out-Host
    $Output
} | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation

一个更高级的解决方案也支持批处理是使用可逐步处理的管道例如[通过PowerShell拆分9 GB csv文件时出现问题](https://stackoverflow.com/a/75382747/1701026)
英文:

Just use the PowerShell pipeline the way it is designed:

Get-Content -Path "./FULl_List_hosts_all_CSV_V2.txt" | Foreach-Object {
    $Server = $_.Trim()
    $Output = try {
        $DNSCheck = [System.Net.Dns]::GetHostEntry($Server)
        # just output an object so it gets collected in variable $Array
        [PsCustomObject]@{ 
            'Server name' = $Server  # or $DNSCheck.HostName
            'IP Address'  = ($DNSCheck.AddressList | Where-Object {$_.AddressFamily -eq 'InterNetwork'})[0].IPAddressToString
        }
    }
    catch {
        # either do nothing here to skip this server of output a 'n/a' object
        [PsCustomObject]@{ 
            'Server name' = $Server
            'IP Address'  = 'n/a'
        }
    }
    $Output | Format-Table -AutoSize | Out-Host
    $Output
} | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation 

A more advanced solution (that also supports batches) would be using the steppable pipeline, see e.g.: Trouble Splitting a 9 GB csv file via Powershell

答案2

得分: -1

你可以逐行处理文件。这样会更快。每次服务器检查的结果都会立即可见。

foreach ($server in [System.IO.File]::ReadLines("C:\path\to\FULl_List_hosts_all_CSV_V2.txt"))
{
   ...
   $result = [PsCustomObject]@{ ... }
   Write-Output $result
   $result | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation -Append
}
英文:

You can process the file line by line. It will be much faster. And the result of each server check will be visible immediately.

foreach($server in [System.IO.File]::ReadLines("C:\path\to\FULl_List_hosts_all_CSV_V2.txt"))
{
   ...
   $result = [PsCustomObject]@{ ... }
   Write-Output $result
   $result | Export-Csv -Path "./pingstatus.csv" -NoTypeInformation -Append
}

huangapple
  • 本文由 发表于 2023年7月17日 16:28:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702673.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定