VB script or Powershell to ping, access WMI, query SSH port 22 to determine Windows and Linux machines

I would like to have a script that queries our network computers based on a text file of our DNS A records.  It should Ping, if successful, report so to a file then make a simple WMI query.  If successful, report so to a file then make a port query to SSH 22 and report if successful.

The idea is to determine the windows and Linux machines on the network according to DNS records:
- pingable Vs. not pingable
- WMI accessible (Windows machines) Vs. Not WMI accessible
- SSH port 22 accessible (Linux or other device) Vs. Not SSH port 22 accessible

This would be best in Powershell, but VB script will work too.  The VB script below does much of what i would like with a couple exceptions.  First, it queries AD groups.  I would like it to be able to take a text file as input.  It would have a simple format of Name,Tab,IP address . Second it doesn't include the SSH port 22 query.  if the query fails it writes the failure to the output file.  If it's successful it outputs the name of the machine or IP.

Thanks for your help!

-----------------------------------------------------
on error resume next
Const ForAppending = 8

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
    ("D:\Data\Tools\Scripts\WMI-Reports\Reports\AdapterReport3-23-10.csv", ForAppending, True)

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"

Set objCOmmand.ActiveConnection = objConnection
Set objGroup = GetObject _
      ("LDAP://CN=Comp-All,OU=Groups,DC=ourdomain,DC=domain,DC=com")

strName = objGroup.Get("name")
arrMemberOf = objGroup.GetEx("member")

      objTextFile.WriteLine "Date,Time,Hostname,MAC,IP,Adapter,Driver Version"
      objTextFile.WriteLine Date & "," & TIME & VbCrLf


For Each strMember in arrMemberOf
      strMember = Mid(strMember, 4, 330)
      arrGroup = Split(strMember, "," )

      Set objShell = CreateObject("WScript.Shell")
      Set objScriptExec = objShell.Exec( _
          "ping -n 2 -w 500 " & arrgroup(0))
      strPingResults = LCase(objScriptExec.StdOut.ReadAll)
      If InStr(strPingResults, "reply from") Then
          If InStr(strPingResults, "destination net unreachable") Then
            objTextFile.Write vbcrlf & "," & TIME & "," & arrgroup(0) & "," & "NO RESPONSE"
          Else
            'objTextFile.Write vbcrlf & "," & TIME & "," & arrgroup(0) & "," & "RESPONDED"

            Err.Clear
            Set objWMIService = GetObject("winmgmts:" _
             & "{impersonationLevel=impersonate}!\\" & arrgroup(0) & "\root\cimv2")

            If Err.Number <> 0 Then
                        objTextFile.Write  vbcrlf & "," & TIME & "," & arrgroup(0) & "," & "WMI FAILED"
            Else

                  Set colAdapters = objWMIService.ExecQuery _
                   ("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True and DHCPEnabled=False")

                        For Each objAdapter in colAdapters
                            If Not IsNull(objAdapter.IPAddress) Then
                              For i = LBound(objAdapter.IPAddress) To UBound(objAdapter.IPAddress)
                                objTextFile.Write vbcrlf & "," & TIME & "," & arrgroup(0) & "," & objAdapter.MACAddress & "," & objAdapter.IPAddress(i) & "," & objAdapter.Description & "," & GetDriverVersion(objAdapter.Description)
                                'adapter = adapter & objAdapter.Description & vbCrLf & "    MAC address: " & objAdapter.MACAddress & vbCrLf & "    IP Address: " & objAdapter.IPAddress(i) & vbCrLf & "    Driver Version:  " & GetDriverVersion(objAdapter.Description) & vbCrLf & vbCrLf
                              Next
                            End If
                        Next

            End If

          End If
        Else
      objTextFile.Write vbcrlf & "," & TIME & "," & arrgroup(0) & "," & "NO PING RESPONSE"
        End If

Next

objTextFile.WriteLine VBcrlf & Date & "," & TIME
objTextFile.Write VBcrlf


Function GetDriverVersion(myAdapter)

       ON ERROR RESUME NEXT

       Set colDrivers = objWMIService.ExecQuery _
             ("select * from Win32_PnPSignedDriver where DeviceClass='NET'")

       For Each objDriver in colDrivers
             If left(myAdapter,len(objDriver.Description))=objDriver.Description then
                   drv=objDriver.DriverVersion
             End If
       Next

       GetDriverVersion=drv
End Function
-----------------------------------------------------
mbrombAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

merowingerCommented:
Could you please check the script below. I canno test it, so if a error occurs please give feedback.
You need the command line tool portqry to check the ssh port.
You can download it here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=89811747-C74B-4638-A2D5-AC828BDC6983&displaylang=en
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")


Set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("Wscript.Shell")
Set objComputers = objFSO.OpenTextFile("D:\Computers.txt")
Set objTextFile = objFSO.CreateTextFile("D:\Output")

Do While not objComputers.AtEndOfStream
	strComputer = objComputers.Readline
	
	'Check connection
	Set colPingedComputers = objWMIService.ExecQuery ("Select * from Win32_PingStatus Where Address = '" & strComputer &"'")

	For Each objComputer in colPingedComputers
		If objComputer.StatusCode <> 0 Then
			objTextFile.WriteLine strComputer & " - No RESPONSE"
		Else
			objTextFile.WriteLine strComputer & " - RESPONSE"

			'Check WMI
			Err.Clear
			Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
			If Err.Number <> 0 Then
				objTextFile.WriteLine strComputer & " - WMI FAILED"
			Else
				objTextFile.WriteLine strComputer & " - WMI SUCCESS"
			End If

			'Check WMI
			returncode = objShell.Run ("portqry.exe -n " &strComputer &" -e 22",0,true)
			If returncode = 1 Then
				objTextFile.WriteLine strComputer & " Port 22 FAILED"
			Else
				objTextFile.WriteLine strComputer & " Port 22 SUCCESS"
			End if			
			
		End If
	Next
Loop

Open in new window

0
mbrombAuthor Commented:
The script alwasy outputs the same results no matte if the pc name or IP is correct, or if it's accesible via WMI or port 22.

example:
fakeName            10.222.222.200       - RESPONSE
fakeName            10.222.222.200       - WMI FAILED
fakeName            10.222.222.200       Port 22 SUCCESS

The name and IP are no good on our network.  

I would like the script to do an actual ping.  If that fails it can stop further tests and move on to the next and just output PCname filed ping.  this will save a lot of time because the WMI query can take a long time to fail.  Apparently the portqry is always returning 1, maybe because it always successfully runs.  i dn't know why the WMI check always fails.  

Anyway, maybe it would be easier to modify the script I have.  the only adjustments are to use a text file for input and to include the portqry.

Thanks!
0
merowingerCommented:
ok could you please try this one
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") 
 
 
Set objFSO = CreateObject("Scripting.FileSystemObject") 
set objShell = CreateObject("Wscript.Shell") 
Set objComputers = objFSO.OpenTextFile("D:\Computers.txt") 
Set objTextFile = objFSO.CreateTextFile("D:\Output.log") 
 
Do While not objComputers.AtEndOfStream 
        strComputer = objComputers.Readline 
         
        'Check connection 
        Set colPingedComputers = objWMIService.ExecQuery ("Select * from Win32_PingStatus Where Address = '" & strComputer &"'") 
 
        For Each objComputer in colPingedComputers 
                If objComputer.StatusCode <> 0 Then
			bolConnection = false
                Else 
                        bolConnection = true        
                End If 
        Next 

	If bolConnection = true Then
		objTextFile.WriteLine strComputer & " - RESPONSE" 
 
		'Check WMI 
		Err.Clear 
		Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
		If Err.Number <> 0 Then 
				objTextFile.WriteLine strComputer & " - WMI FAILED" 
		Else 
			objTextFile.WriteLine strComputer & " - WMI SUCCESS" 
		End If 
 
		'Check WMI 
		'returncode = objShell.Run ("portqry.exe -n " &strComputer &" -e 22",0,true) 
		If returncode = 1 Then 
			objTextFile.WriteLine strComputer & " Port 22 FAILED" 
		Else 
			objTextFile.WriteLine strComputer & " Port 22 SUCCESS" 
		End if  
	Else
		objTextFile.WriteLine strComputer & " - No RESPONSE" 
	End If
Loop

Open in new window

0
Webinar: What were the top threats in Q2 2018?

Every quarter, the WatchGuard Threat Lab releases an Internet Security Report that describes and analyzes the top threat trends impacting companies around the world. Are you ready to learn more about the top threats of Q2 2018? Register for our Sept. 26th webinar to learn more!

dicconbCommented:
Hi mbromb,

This script will distinguish between Linux hosts Windows hosts and unpingable hosts, however it doesn't use the exact method you asked for.  I hope you find it helpful anyway!

It works by looking at the TTL value of the ping responses (each flavour of OS has a different initial TTL value).  Because it doesn't attempt to connect to WMI or SSH it is a *lot* faster (10 seconds to check 100 computers from my laptop).

It's written in powershell: amend serverlist.txt to include your server names and save it to c:\, or change the path on the first line.  At the moment it just spits the results out to the console, but if you prefer I can adjust it so it outputs individual text files for each OS, or a CSV file with all the results combined.

Cheers,

D
$inputpath = "C:\serverlist.txt"
$pingtimeout = 1200
$maxhops = 10 

$windows_servers = @()
$nix_servers = @()
$down_servers = @()
$unknown_servers = @()

$servers = get-content $inputpath
$ping = New-Object System.Net.NetworkInformation.Ping
foreach ($server in $servers) {
    $osunknown = $true
    $reply = $ping.Send("$server", $pingtimeout)
    $ttl = $reply.options.ttl
    if ($ttl -lt 128) {
        if ($ttl -gt (128 - $maxhops)) {
            $windows_servers += $server
            $osunknown = $false
        }
    }
    if ($ttl -lt 256) {
        if ($ttl -gt (256 - $maxhops)) {
            $nix_servers += $server
            $osunknown = $false
        }   
    }
    if ($ttlunknown -eq $true) {
        $unknown_servers += $server
    }
    if ($reply.status -ne "Success" ) {
        $down_servers += $server
    }
}

Write-Host "Windows Servers:"
Write-Host
$windows_servers
Write-Host
Write-Host "Linux/Unix Servers:"
Write-Host
$nix_servers
Write-Host
Write-Host "Unresponsive Servers:"
Write-Host
$down_servers
Write-Host
Write-Host "Unknown OS Servers:"
Write-Host
$unknown_servers

Open in new window

serverlist.txt
0
mbrombAuthor Commented:
thank you!  this looks promising.


I'm getting an error:

Exception calling "Send" with "2" argument(s): "An exception occurred during a Ping request."
At D:\Data\Tools\Scripts\WMI-Reports\WinVsLinux.ps1:14 char:24
+     $reply = $ping.Send <<<< ("$server", $pingtimeout)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
0
mbrombAuthor Commented:
Wait I think it's because the file is formatted as
pcName    IPAddress

It looks like it works with just a single column.  I'll test further.
0
mbrombAuthor Commented:
I'm going to have to pick this up tomorrow, but it seems the input file needs to be IPs only, and it may be sensitive to extra spaces, tabs, etc.  It does not seem to like Host names, and generally if conditions are not perfeect it spits out the error:

 --------------------------------------------------
Exception calling "Send" with "2" argument(s): "An exception occurred during a Ping request."
At D:\Data\Tools\Scripts\WMI-Reports\WinVsLinux.ps1:14 char:24
+     $reply = $ping.Send <<<< ("$server", $pingtimeout)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
 --------------------------------------------------

How reliable is this?

Thanks!
0
dicconbCommented:
Hi mbromb,

Hostnames shouldn't be a problem, so it's probably tripping over the spaces and tabs.  I'll take a look at it in the morning and see if I can make it a bit less fussy! 

Would you mind sending me a typical snippet of your input file so I can test? No need to include real server names or IP addresses, I just want to get an idea of how it's laid out and what characters are in there.

Cheers,

D
0
mbrombAuthor Commented:
I increased the points.

I'll be doing a dnscmd export of all A records in a zone.

Here's a snippet:

@ [Aging:3587155] 600 A      10.106.1.12
             [Aging:3587188] 600 A      10.106.3.21
             [Aging:3587197] 600 A      10.192.32.21
             [Aging:3587192] 600 A      10.97.1.22
             [Aging:3587195] 600 A      10.97.1.21
             [Aging:3587131] 600 A      10.97.1.24
             [Aging:3587179] 600 A      10.129.1.21
             [Aging:3587184] 600 A      10.138.1.21
             [Aging:3587156] 600 A      10.104.33.11
             [Aging:3586604] 600 A      10.97.1.23
acs01 3600 A      10.97.1.11
acs02 3600 A      10.104.32.160
bwy5-jcrouch4 3600 A      10.133.1.24
cfengine 3600 A      10.100.92.69
chi-prd-bond2 3600 A      192.168.160.247
chi-prd-ds-5 3600 A      10.106.1.131
claudit 3600 A      10.100.92.69
contractdb 3600 A      10.100.50.251
dact-ltc-gpln1 [Aging:3587154] 1200 A      10.106.1.164
dbbrowser 3600 A      10.100.50.251
dchv-crt-lx151 3600 A      10.159.36.151
dchv-crt-lx152 3600 A      10.159.36.152
ddart-ltc-rom1 [Aging:3587190] 1200 A      10.106.160.21
ddart-ltc-rom2 [Aging:3587190] 1200 A      10.106.160.20
ddrt-frb-dev01 3600 A      10.103.103.72
ddrt-frb-dev1 3600 A      10.103.160.20
devdbbrowser 3600 A      10.100.50.251
dfwy-ltc-toc03 [Aging:3587179] 1200 A      10.106.173.63
dhtr-ltc-app02 [Aging:3587183] 1200 A      10.106.76.127
dhtr-ltc-app03 [Aging:3587183] 1200 A      10.106.76.126
0
dicconbCommented:
Hi mbromb,

I've added basic error handling and used a regular expression to parse the DNSCMD output format.  Save the dnscmd output as c:\dns_export.txt and run the script in powershell.  Hopefully this should avoid the errors you had first time round.

The script will now also create a CSV file called c:\query_results.csv which you can open in Excel for further analysis if necessary.

Cheers,

D

PS If you are running Powershell 2.0, uncomment line 36 to display a progress bar while scanning the hosts.
# Parameters
cd c:\
$inputpath = "dns_export.txt"
$outputpath = "query_results.csv"
$pingtimeout = 1200
$maxhops = 10
trap {Write-Host $Error[0].Exception.Message;Continue}

# Variables/Objects
$i = 1
$servers = @()
$records = @()
$ping = New-Object System.Net.NetworkInformation.Ping

#Parse DNSCMD Output
$zoneexport = Get-Content $inputpath
$regex = "(?<hostname>^[A-Za-z0-9-_.@]*).*(\sA\s).*(?<ipaddress>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)$"
foreach ($line in $zoneexport) {
    $obj = New-Object PSObject
    $matches = $null
    $line -match $regex | Out-Null
    if (($matches.hostname -ne $null) -and ($matches.hostname -ne "")) {
        $hostname = $matches.hostname
    }
    $obj | Add-Member Noteproperty -name "IPaddress" -value $matches.ipaddress 
    $obj | Add-Member Noteproperty -name "Hostname" -value $hostname
    if ($matches.ipaddress -ne $null) {
        $records += $obj
    }
}
$numservers = $records.length

#Check each host
foreach ($server in $records) {
    $hostname = $server.hostname
#    Write-Progress -activity "Querying Servers..." -status "Pinging server $hostname ($i/$numservers)" -percentcomplete (($i/$numservers) * 100)
    #if ($i -gt 80) {break}
    $i++
    $result = $null
    $reply = $ping.Send($server.IPaddress, $pingtimeout)
    $ttl = $reply.options.ttl
    if (($ttl -lt 128) -and ($ttl -gt (128 - $maxhops))) {$result = "Windows"}
    if (($ttl -lt 256) -and ($ttl -gt (256 - $maxhops))) {$result = "Linux/Unix"}
    if ($reply.status -ne "Success" ) {$result = "Unresponsive"}
    if ($result -eq $null) {$result = "OS Unknown"}
    $server | Add-Member Noteproperty -name "Result" -value $result     
    $servers += $server
}

#Output results
$servers | sort-object Hostname | ft 
$servers | sort-object Hostname | Export-CSV $outputpath -notypeinformation

Open in new window

0
mbrombAuthor Commented:
I'm not getting any output.  Just a blank file, and a very quick runtime.  My guess is that the regex or parsing is not happening as planned.

This part is confusing to me:

---------------------------
$regex = "(?<hostname>^[A-Za-z0-9-_.@]*).*(\sA\s).*(?<ipaddress>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)$"
foreach ($line in $zoneexport) {
    $obj = New-Object PSObject
    $matches = $null
    $line -match $regex | Out-Null
    if (($matches.hostname -ne $null) -and ($matches.hostname -ne "")) {
        $hostname = $matches.hostname
    }
---------------------------

It seems like $matches is getting set to null and then there's an If statement that seems to set $hostname to null.hostname which would be blank, no? And $matches.ipaddress would be blank too?

Thanks
0
dicconbCommented:
Strange!  I'll try running it again from my end, and get back to you shortly.

$matches is a special object that is created when running "$line -match $regex", and contains the results of all the matches.  I set it to $null during each loop so the previous result isn't repeated if a particular line doesn't have any matches.
0
dicconbCommented:
Incidentally, which version of Powershell are you running?  Type Get-Host at a powershell prompt if you're not sure.

Thanks,

D
0
mbrombAuthor Commented:
version 2
0
dicconbCommented:
The only thing I can think of is that it might not be finding the input file.  Please could you follow these steps?

1) Paste the attached code into a file called "script.ps1" in the root of your My Documents folder
2) Save the attached file "dns_export.txt" in the root of your My Documents folder
3) Open a powershell window from the start menu
4) Type "cd <path to your documents folder>" to change directory into your My Documents folder
5) Type "./script.ps1" to run the script.

You should see something like this:

IPaddress                               Hostname                                Result
---------                               --------                                ------
10.129.1.21                             @                                       Unresponsive
10.97.1.24                              @                                       Unresponsive
10.138.1.21                             @                                       Unresponsive
10.97.1.23                              @                                       Unresponsive
10.104.33.11                            @                                       Unresponsive
10.106.3.21                             @                                       Unresponsive
10.106.1.12                             @                                       Unresponsive
10.192.32.21                            @                                       Unresponsive
10.97.1.21                              @                                       Unresponsive
10.97.1.22                              @                                       Unresponsive
10.97.1.11                              acs01                                   Unresponsive
10.104.32.160                           acs02                                   Unresponsive
10.133.1.24                             bwy5-jcrouch4                           Unresponsive
10.100.92.69                            cfengine                                Unresponsive
192.168.160.247                         chi-prd-bond2                           Unresponsive
10.106.1.131                            chi-prd-ds-5                            Unresponsive
10.100.92.69                            claudit                                 Unresponsive
10.100.50.251                           contractdb                              Unresponsive
10.106.1.164                            dact-ltc-gpln1                          Unresponsive
10.100.50.251                           dbbrowser                               Unresponsive
10.159.36.151                           dchv-crt-lx151                          Unresponsive
10.159.36.152                           dchv-crt-lx152                          Unresponsive
10.106.160.21                           ddart-ltc-rom1                          Unresponsive
10.106.160.20                           ddart-ltc-rom2                          Unresponsive
10.103.103.72                           ddrt-frb-dev01                          Unresponsive
10.103.160.20                           ddrt-frb-dev1                           Unresponsive
10.100.50.251                           devdbbrowser                            Unresponsive
10.106.173.63                           dfwy-ltc-toc03                          Unresponsive
10.106.76.127                           dhtr-ltc-app02                          Unresponsive
10.106.76.126                           dhtr-ltc-app03                          Unresponsive

Cheers,

D


# Parameters
#cd c:\
$inputpath = "dnsexport.txt"
$outputpath = "query_results.csv"
$pingtimeout = 1200
$maxhops = 10
trap {Write-Host $Error[0].Exception.Message;Continue}

# Variables/Objects
$i = 1
$servers = @()
$records = @()
$ping = New-Object System.Net.NetworkInformation.Ping

#Parse DNSCMD Output
$zoneexport = Get-Content $inputpath
$regex = "(?<hostname>^[A-Za-z0-9-_.@]*).*(\sA\s).*(?<ipaddress>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)$"
foreach ($line in $zoneexport) {
    $obj = New-Object PSObject
    $matches = $null
    $line -match $regex | Out-Null
    if (($matches.hostname -ne $null) -and ($matches.hostname -ne "")) {
        $hostname = $matches.hostname
    }
    $obj | Add-Member Noteproperty -name "IPaddress" -value $matches.ipaddress 
    $obj | Add-Member Noteproperty -name "Hostname" -value $hostname
    if ($matches.ipaddress -ne $null) {
        $records += $obj
    }
}
$numservers = $records.length

#Check each host
foreach ($server in $records) {
    $hostname = $server.hostname
    Write-Progress -activity "Querying Servers..." -status "Pinging server $hostname ($i/$numservers)" -percentcomplete (($i/$numservers) * 100)
    #if ($i -gt 80) {break}
    $i++
    $result = $null
    $reply = $ping.Send($server.IPaddress, $pingtimeout)
    $ttl = $reply.options.ttl
    if (($ttl -lt 128) -and ($ttl -gt (128 - $maxhops))) {$result = "Windows"}
    if (($ttl -lt 256) -and ($ttl -gt (256 - $maxhops))) {$result = "Linux/Unix"}
    if ($reply.status -ne "Success" ) {$result = "Unresponsive"}
    if ($result -eq $null) {$result = "OS Unknown"}
    $server | Add-Member Noteproperty -name "Result" -value $result     
    $servers += $server
}

#Output results
$servers | sort-object Hostname | ft 
$servers | sort-object Hostname | Export-CSV $outputpath -notypeinformation

Open in new window

dns-export.txt
0
dicconbCommented:
EE seems to be messing with the underscore in the file name.  I have attached it again as "dnsexport.txt".  Please could you save it with this filename before running the script?

Cheers,

D
dnsexport.txt
0
mbrombAuthor Commented:
EE?

So, when I copied your file down it worked.  Not with mine though.  Permissions/owner, location and file names are the same, so I don't know what the problem is.  I created another and it worked, so whatever.  Thanks for the direction.  This is really great!  Thank You!

Can we put a column in for the TTL?  There are devices on the network that I want to recognize as such.  One of the main points is to recognize the Windows and Linux/Unix machines, and that means separating out the other devices if possible.  Maybe the TTLs will give an indication?

0
dicconbCommented:
Hi mbromb,

I meant Experts Exchange (EE).  It's weird that it didn't work with the old file, but I'm glad it's working with the new ones you generate at least!  This new version adds a TTL column.

Cheers,

D
# Parameters
$inputpath = "dnsexport.txt"
$outputpath = "query_results.csv"
$pingtimeout = 1200
$maxhops = 10
trap {Write-Host $Error[0].Exception.Message;Continue}

# Variables/Objects
$i = 1
$servers = @()
$records = @()
$ping = New-Object System.Net.NetworkInformation.Ping

#Parse DNSCMD Output
$zoneexport = Get-Content $inputpath
$regex = "(?<hostname>^[A-Za-z0-9-_.@]*).*(\sA\s).*(?<ipaddress>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)$"
foreach ($line in $zoneexport) {
    $obj = New-Object PSObject
    $matches = $null
    $line -match $regex | Out-Null
    if (($matches.hostname -ne $null) -and ($matches.hostname -ne "")) {
        $hostname = $matches.hostname
    }
    $obj | Add-Member Noteproperty -name "IPaddress" -value $matches.ipaddress 
    $obj | Add-Member Noteproperty -name "Hostname" -value $hostname
    if ($matches.ipaddress -ne $null) {
        $records += $obj
    }
}
$numservers = $records.length

#Check each host
foreach ($server in $records) {
    $hostname = $server.hostname
    Write-Progress -activity "Querying Servers..." -status "Pinging server $hostname ($i/$numservers)" -percentcomplete (($i/$numservers) * 100)
    #if ($i -gt 80) {break}
    $i++
    $result = $null
    $reply = $ping.Send($server.IPaddress, $pingtimeout)
    $ttl = $reply.options.ttl
    if (($ttl -lt 128) -and ($ttl -gt (128 - $maxhops))) {$result = "Windows"}
    if (($ttl -lt 256) -and ($ttl -gt (256 - $maxhops))) {$result = "Linux/Unix"}
    if ($reply.status -ne "Success" ) {$result = "Unresponsive"}
    if ($result -eq $null) {$result = "OS Unknown"}
    $server | Add-Member Noteproperty -name "Result" -value $result
    $server | Add-Member Noteproperty -name "TTL" -value $reply.options.ttl
    $servers += $server
}

#Output results
$servers | sort-object Hostname | ft 
$servers | sort-object Hostname | Export-CSV $outputpath -notypeinformation

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dicconbCommented:
Let me know if you have any problems with it - hope it helps.

D
0
mbrombAuthor Commented:
Great script, very efficient and useful!  Thanks!
0
dicconbCommented:
Thanks for the points,

D
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.