There is one more useful application of script from the “Explore local network with F# Async Workflows” post. During the check of the machine availability we can collect IP addresses of all machines. After that we can compare IPs of different host names for collision. It is a good way to understand what is going on in your network.
#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=10000)
(searcher.FindAll() :> IEnumerable)
|> Seq.cast<SearchResult>
|> Seq.map (fun x -> x.GetDirectoryEntry().Name)
|> Seq.map (fun n -> n.Substring(n.IndexOf("=")+1))
|> Seq.toList
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 None
| Choice1Of2 reply when reply.Status = IPStatus.Success ->
return Some(reply.Address.MapToIPv4().ToString())
| _ when attempts > 0 -> return! ping (attempts-1) host
| _ -> return None
}
let results =
hosts
|> Seq.map (ping 4)
|> Async.Parallel
|> Async.RunSynchronously
|> Seq.toList
List.zip results hosts
let dnsConflicts =
hosts
|> checkHosts
|> List.filter (fst >> Option.isSome)
|> Seq.groupBy fst
|> Seq.filter (fun (_, seq) -> Seq.length seq > 1)
|> Seq.map (fun (k, seq) ->
(Option.get k, seq |> Seq.map snd |> Seq.toList) )
|> Seq.toList
One more interesting task is to explore local network and check which computers are alive.
I have faced with an interesting F# behaviour on the null check. I tried to make a
Detailed pretty printed exception is a key to understand the real cause of the problem. We have a piece of code in C# that was reused for many projects, which formats exceptions sequence into human readable form with all exception details.




