英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论