Testing a remote computer is online better test-connection

This topic contains 3 replies, has 3 voices, and was last updated by  js 1 week, 6 days ago.

  • Author
    Posts
  • #92934

    Nomad Deamons
    Participant

    My sys admin experience is limited to a small enterprise and therefore there were no senior admins to learn from.
    So I may have learned to do things wrongly, even though they work.
    With that said,

    – Scenario and Question below –

    Recently I had to change the contents of a certain html file on each desktop about 500 give or take. I did it with powershell. It worked out and the deed is done. But doesn't hurt to ask how can i do things better.
    In order to test for all the online desktops vs all records in AD I used a test-connection.
    Is there a better way to test if the computer is online / exists? Because in AD we have more records desktops than we actually have.

    Test-connection is a little slow.
    In addition I used hard coded paths,
    if the path existed,
    and if the file existed within the path,
    and if the string existed within the file,
    modify it and write the changes.

    I ran the script a few times to make sure I do not miss the people who turn off their desktops when they take off.
    I am repeating the question here: Is there a better way to test if the computer is online / exists, than test-connection?
    Thank you.

  • #92943

    Don Jones
    Keymaster

    Any kind of live check is going to be slow, because you have to allow for a decent timeout. Test-Connection is just a ping; if you're fairly confident of your network, you can limit it to one ping instead of the default four, to speed it up a bit – but you risk "missing" systems that are online and just a bit slow.

    The most you can practically do to speed things up is to parallelize things a bit, using something like Worfklow or Remoting, or Invoke-Parallel (which is an open source project) or something.

  • #92949

    js
    Participant

    Actually, I don't think test-connection and test-netconnection are very useful for admins with their long timeouts, and they don't work in powershell 6 anyway. But it's very easy to roll your own with a little .net.

    Function Get-Ping  {
      Param (
        [parameter(ValueFromPipeline)]
        [string[]]$Hostname='yahoo.com'
      )
      Begin {
        $Ping = New-Object System.Net.Networkinformation.ping
        $Timeout = 250 # ms                                                                                                                                    
      }
      Process {
        $hostname | foreach {
          $Ping.Send($_, $timeout) |
          Add-Member -passthru hostname $_ |
          select hostname,address,status,roundtriptime
        }
      }
    }
    
    PS /Users/js> get-ping yahoo.com,microsoft.com                                                                                                         
    
    hostname      Address         Status RoundtripTime
    --------      -------         ------ -------------
    yahoo.com     206.190.39.42  Success            95
    microsoft.com 0.0.0.0       TimedOut             0
    
  • #93013

    js
    Participant

    Actually I usually use something like this. If it's in osx port 22 will be live, in windows the rdp port 3389 is live.

    function Get-Port {
    
      Param (
        [parameter(ValueFromPipeline)]
        [string[]]$Hostname='yahoo.com',
        [int[]]$ports=@(22,3389),
        [int]$timeout = 100 # ms
      )
      
      begin {   
        $ping = New-Object System.Net.Networkinformation.ping
      }
    
      process {
        $hostname | foreach {
          $openPorts = @()
      
          foreach ($port in $ports) {
            $client = New-Object System.Net.Sockets.TcpClient
            $beginConnect = $client.BeginConnect($_,$port,$null,$null)
            Start-Sleep -Milli $TimeOut
            if($client.Connected) { $openPorts += $port }
            $client.Close()
          }
      
          $result = $Ping.Send($_, $timeout) 
          $pingstatus = ($result.status -eq 'Success')
    
          New-Object -typename PSObject -Property @{
            HostName = $_
            Address = $result.address
            Port = $openPorts
            Ping = $pingstatus 
          } | select hostname,address,port,ping
        } # end foreach
      } # end process
    
    }
    
    PS C:\Windows\system32> get-port a001,a002
    
    HostName Address     Port    Ping
    -------- -------     ----    ----
    arc001               {3389} False
    arc002   1.1.1.1     {3389}  True
    
    
    

You must be logged in to reply to this topic.