NaPTaC Tool: Nslookup and Ping-Test a Cluster(s) (and Report)

Another PowerShell tool I’ve been playing around with. This one does a few things:

1) Performs NSLookup on your cluster logical interface names as they should be in DNS, and records the IP (DNR = Did Not Resolve)
2) Ping tests the IP Addresses and records whether they are up or down
3) Outputs the data to the command prompt in a DOS table
4) Outputs the data to a CSV (you can apply conditional formatting in Excel to have UP as green and DOWN as red)
5) And will repeat as many times as you like (so you can easily build a spreadsheet with all the clusters you’re interested in)

Note: This doesn’t use the NetApp DataONTAP PowerShell Toolkit. On whatever desktop you can run powershell, you’ll be able to run this!
Note: Of course this was written with NetApp ONTAP clusters in mind, but it could be applied to pretty much any cluster that has nodes and interfaces.
Note: If - like in most places - you need network assignments first before kit goes in, reporting the nslookups of nodes that haven’t yet been physically installed is very useful!

A few notes which might help if you’re thinking of customizing it for your environment:

i: I’ve made it more generic that the one I was using (for obvious reasons), and I’ve not tested it in this form
ii: $LUps is the hashtable for LookUps, and we get the CLUSTER-mgmt IP first, then all the other LIFs
iii: Here we have LIFs: "-n$DD-sp","-n$DD-mgmt","-n$DD-ic","-svm1-$i","-svm2-$i" where $i is the node number, and $DD is the node number in 2 digits (i.e. node 5 is 05)
iv: The Vserver lookups are in case the SVM LIFs are in a DNS load-balancer and not explicit in DNS, so we get all the IPs in the DNS load-balancer
v: The $Output has to be sorted to get the columns in the correct order
vi: Output is to a file called Output.CSV

Image: naptac.ps1 user input (can paste in a list if you want)

The Script


######################################
## NSLOOKUP AND PING TEST A CLUSTER ##
######################################

Function Wr{ ## Write function ...
  Param([String]$Text,[String]$FColor,[String]$BColor,[Int]$Pad)
  If(!$Text){Write-Host;RETURN}
  If(!$FColor){Write-Host $Text -NoNewLine -ForegroundColor White;RETURN}
  If(!$BColor){Write-Host $Text -NoNewLine -ForegroundColor $FColor;RETURN}
  If(!$Pad){Write-Host $Text -NoNewLine -ForegroundColor $FColor -BackgroundColor $BColor;RETURN}
  Write-Host ($Text.PadRight($Pad," ")) -NoNewLine -ForegroundColor $FColor -BackgroundColor $BColor
}

Function WP{ ## Pad Function ...
  Param([String]$BColor = "Black",[Int]$Pad = 1)
  Write-Host " ".PadRight($Pad," ") -NoNewLine -BackgroundColor $BColor
}

Function VC-Nslookup{
  Param([String]$lookThisUp)
  [System.Array]$nslookup = (nslookup $LookThisUp)
  [Boolean]$Record = $False
  [String]$Result = ""
  Foreach($line in $nslookup){
    If($Record -and ($line.trim() -ne "")){
      If(!$Result){ $Result = $line.Split(" ")[2]}
      else{ $Result += ("," + $line.trim()) }
    }
  If($line.StartsWith("Name")){$Record = $TRUE}
  }
  Return $Result
}

Function TC{Test-Connection -ComputerName $Args[0] -Count 1 -Quiet}

################################
## RESIZE THE WINDOW'S BUFFER ##
################################

$Window = (Get-Host).UI.RawUI
$resize = $Window.BufferSize
$resize.Height = 9999
$resize.Width = 999
$Window.BufferSize = $resize

###########
## START ##
###########

[Boolean]$Do = $TRUE
[System.Array]$ClustersAndNodes = @()
Wr "Enter lines of - " CYAN; Wr "cluster,number-of-nodes" YELLOW; Wr " - then press ENTER on empty line to end list:" CYAN; Wr
While($do){
  $ReadIn = Read-Host
  If(!$ReadIn){$do = $FALSE}else{$ClustersAndNodes += $ReadIn}
}

[System.Array]$Output = @()
Foreach($CandN in $ClustersAndNodes){
 
  [String]$C = $CandN.Split(",")[0]
  [Int16]$Nodes = $CandN.Split(",")[1]
 
  ###########################
  ## GETTING LIF NSLOOKUPS ##
  ###########################
 
  Wr "Starting nslookup:" CYAN;Wr
  [System.Object]$LUps = @{}
  $LUps.($C + "-mgmt") = VC-Nslookup ($C + "-mgmt")
  For($i=1; $i -le $Nodes; $i++){
    $DD = "$i".PadLeft(2,"0")
    [System.Array]$LIFs = "-n$DD-sp","-n$DD-mgmt","-n$DD-ic","-svm1-$i","-svm2-$i"
    $LIFs | Foreach{ $LUps.($C + $_) = VC-Nslookup ($C + $_) }
  }
 
  Wr "Vserver nslokups:" CYAN;Wr ## SVM NSlookups ...
  "-svm1","-svm2" | Foreach{$LUps.($C + $_) = VC-Nslookup ($C + $_)};Wr
 
  ############
  ## OUTPUT ##
  ############
 
  ## COMMAND PROMPT: Heading ...
  Wr "Cluster" BLACK GRAY 20; WP
  Wr "Node ({cluster}-nX/n0X)" BLACK GRAY 30; WP
  "{cluster}-mgmt","{node}-sp","{node}-mgmt","{node}-ic","SVM1-lif-X","SVM2-lif-X" | Foreach{Wr $_ BLACK GRAY 20;WP};Wr      
 
  ## Data output ...
  For($i=1; $i -le $Nodes; $i++){
   
    $DD = "$i".PadLeft(2,"0")
    Wr $C BLACK CYAN 20; WP
    Wr "$C-n$DD" BLACK CYAN 30; WP
   
    [System.Array]$LIFs = "-mgmt","-n$DD-sp","-n$DD-mgmt","-n$DD-ic","-svm1-lif-$i","-svm2-lif-$i"
    [System.Object]$NsLRec = @{}
    [System.Object]$PngRec = @{}
    [Int]$x = 1
   
    Foreach($LIF in $LIFs){

      [String]$TempTC  = ($C + $LIF)
      [String]$TempNSL = $LUps.($C + $LIF)
     
      ## START: Handling SVM LIFs ...
      "-svm1","-svm2" | Foreach{
        If($LIF.Startswith($_+"-lif")){
          [System.Array]$SVM_LIFs = ($LUps.($C + $_)).Split(",")
          If($i -le $SVM_LIFs.count){$TempTC = $TempNSL = $SVM_LIFs[$i-1]}                          
        }
      } ## END: ... handled SVM LIFs
     
      If($TempNSL -eq ""){$TempNSL = "DNR"}
      If(TC $TempTC){Wr $TempNSL BLACK GREEN 20; WP; [String]$IsUp = "YES"}
      else{Wr $TempNSL WHITE RED 20; WP; [String]$IsUp = "NO"}
     
      ## Recording for CSV output ...
      [String]$NsLRec."$x" = $TempNSL
      [String]$PngRec."$x" = $IsUp
      $x++
    }

    ## Filling the CSV columns ...   
    $Output += New-Object PSObject -Property @{
      "CLUSTER"               = "$C"
      "NODE (CLUSTER-n0X/nX)" = "$C-n$DD"
      "1:CLUSTER-mgmt"        = $NsLRec."1"
      "1:Ping?"               = $PngRec."1"
      "2:NODE-sp"             = $NsLRec."2"
      "2:Ping?"               = $PngRec."2"
      "3:NODE-mgmt"           = $NsLRec."3"
      "3:Ping?"               = $PngRec."3"
      "4:NODE-ic"             = $NsLRec."4"
      "4:Ping?"               = $PngRec."4"
      "5:SVM1-lif-X"          = $NsLRec."5"
      "5:Ping?"               = $PngRec."5"
      "6:SVM2-lif-X"          = $NsLRec."6"
      "6:Ping?"               = $PngRec."6"
    }        
    Wr
  }
  $Output | Select-Object "CLUSTER","NODE (CLUSTER-n0X/nX)","1:CLUSTER-mgmt","1:Ping?","2:NODE-sp","2:Ping?","3:NODE-mgmt","3:Ping?","4:NODE-ic","4:Ping?","5:SVM1-lif-X","5:Ping?","6:SVM2-lif-X","6:Ping?" | Export-CSV "Output.CSV" -NoTypeInformation
}


Comments