问题
I found this script which I modified a bit to take in the hostnames from a file:
http://tompaps.blogspot.com/2015/04/verify-forward-and-reverse-dns-records.html
It pretty much iterates through each name in the file, pings it, converts the returned IP into a string and performs a reverse lookup on the IP. It works, but when I have 600+ machines to go through performance is no bueno. I know with test-connection there's an -asjob parameter I can use to run asynchronous jobs which does the forwardlookup job in seconds but does anyone know a way to mimic this behavior for the reverse lookup?
I found a post on this forum suggesting you can do something similar using the .NET process class but I've just been working with Powershell for a few months and can't seem to decipher the MSDN docs.
回答1:
You can wrap it up in a scriptblock and do Start-Job in a foreach loop to do the following for forward and reverse lookup:
$ComputerName= ‘computername here’
[System.Net.Dns]::GetHostAddresses(“$ComputerName”).IPAddressToString
$ComputerIPAddress = ‘that computer ip here'
[System.Net.Dns]::GetHostEntry($ComputerIPAddress).HostName
For example
$whateverlist = Get-Content .\yourlistofservers.txt
# or you can..
$whateverlist = @"
machine1
machine2
machine3
etc
"@
$Scriptblock = {
param($machine);
$pingOk = Test-Connection -cn $machine -BufferSize 16 -Count 1 -EA silentlyContinue
if ($pingOk)
{
# Do whatever if it responds to pinging
# Maybe store the property in a list, put it out to a file etc.
[System.Net.Dns]::GetHostAddresses(“$machine”).IPAddressToString
# Use whatever method you like to get IP of the computer, even use the above output.
# Me being lazy:
$ip = [System.Net.Dns]::GetHostAddresses(“$machine”).IPAddressToString
[System.Net.Dns]::GetHostEntry($ip).HostName
}
}
# Then you can get the job, do whatever. Do it in a foreach for best results.
foreach ($machine in $whateverlist)
{
Start-Job -ScriptBlock $Scriptblock -ArgumentList $machine
}
# To crack open the eggs and get the goodies:
Receive-Job * -Keep | Out-File ".\whatevermanijustworkhere.txt"
Here's a clean copy:
$whateverlist = Get-Content .\yourlistofservers.txt
$whateverlist = @"
machine1
machine2
machine3
etc
"@
$Scriptblock = {
param($machine);
$pingOk = Test-Connection -cn $machine -BufferSize 16 -Count 1 -EA silentlyContinue
if ($pingOk)
{
$ip = [System.Net.Dns]::GetHostAddresses(“$machine”).IPAddressToString
$ip
[System.Net.Dns]::GetHostEntry($ip).HostName
}
}
foreach ($machine in $whateverlist)
{
Start-Job -ScriptBlock $Scriptblock -ArgumentList $machine
}
Receive-Job * -Keep | Out-File ".\whatevermanijustworkhere.txt"
Source:
https://adsecurity.org/?p=305
回答2:
In case anyone's interested I ended up doing the following:
Import-Module 'C:\Users\Lia Cha\Documents\Windows Powershell\Modules\Invoke-Parallel.psm1'
$machines = Get-Content C:\work\hostnames.txt
Invoke-Parallel -InputObject $machines -RunspaceTimeout 10 -Throttle 10 -ErrorAction SilentlyContinue -ScriptBlock {
$obj = "" | Select ComputerName,Ping,IPNumber,ForwardLookup,ReverseLookup,Result
$obj.ComputerName = $_
# ping each host
if(Test-Connection $_ -quiet -Count 1){
$obj.Ping = "OK"
$obj.Result = "OK"
}
else{
$obj.Ping = "Error"
$obj.Result = "Error"
}
# lookup IP addresses of the given host
[array]$IPAddresses = [System.Net.Dns]::GetHostAddresses($obj.ComputerName) | ?{$_.AddressFamily -eq "InterNetwork"} | %{$_.IPAddressToString}
# caputer count of IPs
$obj.IPNumber = ($IPAddresses | measure).count
# if there were IPs returned from DNS, go through each IP
if($IPAddresses){
$obj.ForwardLookup = "OK"
$IPAddresses | %{
$tmpreverse = $null
# perform reverse lookup on the given IP
$tmpreverse = [System.Net.Dns]::GetHostEntry($_).HostName
if($tmpreverse){
# if the returned host name is the same as the name being processed from the input, the result is OK
if($tmpreverse -ieq $obj.ComputerName){
$obj.ReverseLookup += "$_ : OK `n"
}
else{
$obj.ReverseLookup += "$_ different hostname: $tmpreverse `n"
$obj.Result = "Error"
}
}
else{
$obj.ReverseLookup = "No host found"
$obj.Result = "Error"
}
}
}
else{
$obj.ForwardLookup = "No IP found"
$obj.Result = "Error"
}
# return the output object
$obj | ft -AutoSize | out-string -width 4096 | out-file c:\work\Results.txt -Append}
This ran over 450+ machines in about 4mins.
来源:https://stackoverflow.com/questions/36205922/net-dns-class-powershell-background-job-possible