Explore local network with F# Async Workflows

network_localOne more interesting task is to explore local network and check which computers are alive.

As a first step we need to get a list of computers which registered in Active Directory (as you understand, this approach works only for networks with Active Directory). Here we can use DirectorySearcher from System.DirectoryServices namespace. We create DirectoryEntry that by default points to the current domain and makes search over computers in this domain.

#r <System.DirectoryServices.dll>
open System
open System.Collections
open System.DirectoryServices
open System.Net.NetworkInformation
open System.Threading.Tasks

let hosts =
    use searcher =
        new DirectorySearcher(new DirectoryEntry(),
            Filter="(objectClass=computer)", PageSize=50000)
    (searcher.FindAll() :> IEnumerable)
    |> Seq.cast<SearchResult>
    |> Seq.map (fun x -> x.GetDirectoryEntry().Name)
    |> Seq.map (fun n -> n.Substring(n.IndexOf("=")+1))
    |> Seq.toList

The next step is to check the availability of computers. F# Asynchronous Workflows help us here. We make a sequence of ping-calls(up to 4) to each computer  which allows us to understand if computer is available or not. We are expecting to get a valid response with IPStatus.Success status. If we get an exception instead of response or run out of attempts, we will mark this computer as unavailable.

let checkHosts hosts =
    let rec ping attempts (host:string) =
        async {
            let! pingResult =
                (new Ping()).SendPingAsync(host)
                |> Async.AwaitTask |> Async.Catch
            match pingResult with
            | Choice2Of2 e -> return false
            | Choice1Of2 reply when reply.Status=IPStatus.Success -> return true
            | _ when attempts > 0 -> return! ping (attempts-1) host
            | _ -> return false
        }
    let results =
        hosts
        |> Seq.map (ping 4)
        |> Async.Parallel
        |> Async.RunSynchronously
        |> Seq.toList
    List.zip results hosts

Now we are ready to get a list of available computers.

let availableHosts =
    hosts
    |> checkHosts
    |> List.filter fst
    |> List.map snd

Play with your network and find something interesting :).

6 thoughts on “Explore local network with F# Async Workflows

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s