PowerShell Script Issues Hostname >> IPAddress Port Status Up

This topic contains 8 replies, has 2 voices, and was last updated by Profile photo of Lauras Juozulynas Lauras Juozulynas 1 year, 3 months ago.

  • Author
    Posts
  • #32831
    Profile photo of Daniel Joyner
    Daniel Joyner
    Participant

    Writing a power shell script to take in a text file of host names; then grab the IP Address that is associated with each individual host name. Then run a check to see if a specific port is open on that IP Address. As well as a connection Status to let me know if the device is online or not. All of this information will be written out to a csv file. The csv file will have columns such as:

    | Host Name | | IP Address | | Port Status | | Connection Status |

    My current problem is, the csv file is only returning one Host and not the rest that reside in the host names.txt file I have validated that the rest of the machines are online and are in the same domain. I am still learning my way around power shell. Hopefully this makes sense and if it doesn't I can clarify anything.

    $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
    
    $colComputers = get-content $scriptPath\servers.txt
    
    If (Test-Path("$scriptPath\Server_NotFound.txt")) {
      Remove-Item "$scriptPath\Server_NotFound.txt"
    }
    $Report = @()
    
    ForEach ($strComputer in $colComputers) {
      Try{
        $colItems = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $strComputer -ErrorAction Stop | Where{$_.IpEnabled -Match "True"}
        ForEach ($objItem in $colItems) {
          # Build a new object to contain system information 
          $IPInfo = New-Object psobject
          $IPInfo | Add-Member -MemberType NoteProperty -Name "HostName" -Value $strComputer
          $IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $objItem.IPAddress.trim("{}")
          $IPInfo | Add-Member -MemberType NoteProperty -Name "PortStatus" -Value "Port $port is operational"
          $IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Up"
    
          
          }
          $Report += $IPInfo
        
      }
      
      Catch{
        $strComputer | Out-File "$scriptPath\Server_NotFound.txt" -Append
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
         }
    }
    
    $port = 4445
    
        $sweep = New-Object Net.Sockets.TcpClient
         #We use Try\Catch to remove exception info from console if we can't connect
            try
            {
                $sweep.Connect($ip,$port)
            } catch {}
    
            if($sweep.Connected)
            {
                $sweep.Close()
                $msg = "Port $port is operational"
            }
            else
           {
                $msg = "Port $port on $ip is closed, "
                $msg += "You may need to contact your IT team to open it. "                                 
            }
    
    
    $Report | Export-csv $scriptPath\Knock_Knock_Info.csv -NoTypeInformation -Encoding ASCII
    
  • #32834
    Profile photo of Lauras Juozulynas
    Lauras Juozulynas
    Participant

    Hi,

    Here is fixed script. Tested with one computer but should work with many.

    $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
    
    $colComputers = get-content $scriptPath\servers.txt
    
    If (Test-Path("$scriptPath\Server_NotFound.txt")) {
      Remove-Item "$scriptPath\Server_NotFound.txt"
    }
    $Report = @()
    $port = 4445
    ForEach ($strComputer in $colComputers) {
      Try{
        $colItems = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $strComputer -ErrorAction Stop | Where{$_.IpEnabled -Match "True"}
        $ip = $colItems.IPAddress.trim("{}")
          # Build a new object to contain system information 
          
    	  If (Test-Port $strComputer $port)
    	    {
    	 	  $IPInfo = New-Object psobject
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "HostName" -Value $strComputer
          	  $IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $ip
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "PortStatus" -Value "Port $port is operational"
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Up"
    		}
    		else
    		  {
    		    $IPInfo = New-Object psobject
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "HostName" -Value $strComputer
          	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $ip
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "PortStatus" -Value "Port $port is NOT operational"
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
    		  }
    
          
          
          $Report += $IPInfo
        }
      
      
      Catch{
        $strComputer | Out-File "$scriptPath\Server_NotFound.txt" -Append
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
         }
    }
    
    Function Test-port ($ip,$port)
      {
        $sweep = New-Object Net.Sockets.TcpClient
         #We use Try\Catch to remove exception info from console if we can't connect
            try
            {
                $sweep.Connect($ip,$port)
            } catch {}
    
            if($sweep.Connected)
            {
                $sweep.Close()
                $msg = "Port $port is operational"
    			Return $true
            }
            else
           {
                $msg = "Port $port on $ip is closed, "
                $msg += "You may need to contact your IT team to open it. " 
    			Return $false
            }
      }
    
    $Report | Export-csv $scriptPath\Knock_Knock_Info.csv -NoTypeInformation -Encoding ASCII
    
  • #32836
    Profile photo of Lauras Juozulynas
    Lauras Juozulynas
    Participant

    Things that were wrong or added:

    *Removed "ForEach ($objItem in $colItems)". This would have cycled through 1 servers network adapters lines.
    * Added $ip = $colItems.IPAddress.trim("{}") to have servers IP
    * Added call to function Test-Port and based on results (true/false) form report object
    * moved variable $port before function
    * Created Test-Port function which returns $true or $false after testing connectivity to specified port.

    Didn't change too much in your script and layout, so that you can compare and take a closer look what was done differently.

    Lauras

  • #32839
    Profile photo of Daniel Joyner
    Daniel Joyner
    Participant

    Lauras, Thank you for the help. However when I run the script it now does not populate anything. Instead it lists all host names to Server_NotFound. Which is odd because the machines are online in fact the machine I am running the script on is in the list and its not reporting back the below when it was returning it with the previous script:
    | Host Name | | IP Address | | Port Status | | Connection Status |

    Any idea, what could be the problem?

  • #32842
    Profile photo of Lauras Juozulynas
    Lauras Juozulynas
    Participant

    Hi,

    Did some testing in larger environment and got some ideas.
    In your servers.txt file you have only servers names. in order to get IP, you are making a RPC call to server (command Get-wmiobject). And only if IP is returned, then you check if specified port is opened.
    The problem I encountered on my environment was that RPC calls are blocked by firewall. Servers in same subnet were responding, but in other subnet were marked as not available even if tested port is opened (but RPC is closed).

    Try comenting out these lines. This should remove RPC calls and try connecting to required port only by servername. If you get any errors, please post them to make troubleshooting easier.

    #$colItems = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $strComputer -ErrorAction Stop | Where{$_.IpEnabled -Match "True"}
    #    $ip = $colItems.IPAddress.trim("{}")
    #$IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $ip
    
  • #32844
    Profile photo of Daniel Joyner
    Daniel Joyner
    Participant

    Hey,

    Thanks again, This appears to display the host names again, however the IP Address is only being grabbed for the first host name and then copied for the rest.

    As an Example,

    HostName	         IPAddress	                  PortStatus	                      Connection Status
    mxl20111gt	 102.99.261.71		Port 4445 is NOT operational	Down
    6NX41R1	         102.99.261.71		Port 4445 is NOT operational	Down
    FWW08y1	         102.99.261.71		Port 4445 is NOT operational	Down
    MJ02XF48	         102.99.261.71		Port 4445 is NOT operational	Down
    
    

    Edit#2
    Could I just use System.Net.NetworkInformation.Ping instead of Get-wmiobject -class "Win32_NetworkAdapterConfiguration"

  • #32847
    Profile photo of Lauras Juozulynas
    Lauras Juozulynas
    Participant

    Hi,

    This one should remove IP from CSV at all. Problem is that IP is taken through RPC which is not always opened (in my case) if server is behind firewall. You should get only fields: hostname, PortStatus and Connection Status. Does it at least identify port 4445 correctly? As far as I have tried it works on mine. Except for IP.

    $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
    
    $colComputers = get-content $scriptPath\servers.txt
    
    If (Test-Path("$scriptPath\Server_NotFound.txt")) {
      Remove-Item "$scriptPath\Server_NotFound.txt"
    }
    $Report = @()
    $port = 4445
    ForEach ($strComputer in $colComputers) {
      Try{
        #$colItems = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $strComputer -ErrorAction Stop | Where{$_.IpEnabled -Match "True"}
        #$ip = $colItems.IPAddress.trim("{}")
          # Build a new object to contain system information 
          
    	  If (Test-Port $strComputer $port)
    	    {
    	 	  $IPInfo = New-Object psobject
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "HostName" -Value $strComputer
          	  #$IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $ip
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "PortStatus" -Value "Port $port is operational"
         	  $IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Up"
    		}
    		else
    		  {
    		    $IPInfo = New-Object psobject
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "HostName" -Value $strComputer
          	  	#$IPInfo | Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $ip
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "PortStatus" -Value "Port $port is NOT operational"
         	  	$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
    		  }
    
          
          
          $Report += $IPInfo
        }
      
      
      Catch{
        $strComputer | Out-File "$scriptPath\Server_NotFound.txt" -Append
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
        #$IPInfo | Add-Member -MemberType NoteProperty -Name "Connection Status" -Value "Down"
         }
    }
    
    Function Test-port ($ip,$port)
      {
        $sweep = New-Object Net.Sockets.TcpClient
         #We use Try\Catch to remove exception info from console if we can't connect
            try
            {
                $sweep.Connect($ip,$port)
            } catch {}
    
            if($sweep.Connected)
            {
                $sweep.Close()
                $msg = "Port $port is operational"
    			Return $true
            }
            else
           {
                $msg = "Port $port on $ip is closed, "
                $msg += "You may need to contact your IT team to open it. " 
    			Return $false
            }
      }
    
    $Report | Export-csv $scriptPath\Knock_Knock_Info.csv -NoTypeInformation -Encoding ASCII
    
  • #32871
    Profile photo of Daniel Joyner
    Daniel Joyner
    Participant

    Hey,

    The above does only list the fields Hostname Port Status and Connection Status; however the port status is indeed incorrect. I have set port 4445 to open and it is showing as "Port 4445 is NOT operational" to check this again I set the port to port 80 as well and its still stating "Port 80 is NOT operational". Is there a way I can just have it check against a csv file of subnets on my network and then run Win32_NetworkAdapterConfiguration from that subnet?

  • #32874
    Profile photo of Lauras Juozulynas
    Lauras Juozulynas
    Participant

    If you are still getting port not open, then check your firewall (on PC/server) or physical firewall. Can you do telnet to that port from machine you are running your script from? I tested it on my environment and all results were as suspected.

    Just test telnet IP.xx.xx.xx 4445 and see if it can be reached. Is that a TCP port?

You must be logged in to reply to this topic.