Thursday, 22 October 2015

Comparing 7-Mode Options - Compare-NaOption.ps1

Compare-NaOption is a tool to compare options from various 7-Mode systems to check for mismatches.

Features:

- Can compare the options from a “golden” 7-Mode pFiler/vFiler config against other 7-Mode pFiler/vFilers
- Can compare the options from any two 7-Mode pFilers/vFilers
- Works online and offline
- Online mode uses Get-NaOption
- Offline mode reads the options file from a folder named PFILER.vFiler0 or PFILER.VFILER
- For offline mode you can collect the options from MyAutosupport or get a storage admin to run options from the 7-Mode system and copy and paste this into a text file

Use Cases:

Lots... for instance...

- Compare the options of 7-Mode systems planned for consolidation to a production cDOT SVM against already transitioned 7-Mode systems, as a simple pre-check before doing the 7 to C transition.

Switches:

-JustMismatches : Only display the mismatches
-SkipPfilerOnlyOptions : A very basic exclusion of certain options that don’t exist for vFilers

An example:

Comparing a pFiler with one of its vFilers from a SIM on my laptop:

PS C:\ > .\Compare-NaOption.ps1 -SystemA 192.168.168.70 -VfilerA vFiler0 -SystemB 192.168.168.70 -VFilerB FAS01v1 -JustMismatches -SkipPfilerOnlyOptions

Image: Compare-NaOption.ps1 in action

The Script

Note: Formatted for Blogger with tabs replaced by two spaces.

Copy and paste into a text editor and save as say Compare-NaOption.ps1 and run!

Param(
  [String]$SystemA,[String]$VfilerA,
  [String]$SystemB,[String]$VfilerB,
  [Switch]$JustMismatches,
  [Switch]$SkipPfilerOnlyOptions
)

FUNCTION Wr {
  Param([String]$ToDisplay,[String]$Color = "WHITE")
  If($ToDisplay){ Write-Host $ToDisplay -ForegroundColor $Color -NoNewLine }
  else { Write-Host }
}; Wr

FUNCTION Prompt-Setting{
  Param([String]$Prompt,[String]$Setting)
  Wr $Prompt CYAN
  If($Setting){ Wr $Setting; Wr }
  ELSE { $Setting = Read-Host}
  $Setting
}

$SystemA = Prompt-Setting "System A: " $SystemA
$VfilerA = Prompt-Setting "System A: " $VfilerA
$SystemB = Prompt-Setting "System A: " $SystemB
$VfilerB = Prompt-Setting "System A: " $VfilerB; Wr

If(!$VfilerA){ $VfilerA = "vFiler0"}
If(!$VfilerB){ $VfilerB = "vFiler0"}

[System.Array]$Systems = $SystemA,$SystemB
[System.Array]$Vfilers = $VfilerA,$VfilerB

FUNCTION Load-DataOntapPSTK {
  If(Get-Module DataONTAP){ RETURN }
  [Void](Import-Module DataONTAP -ErrorAction SilentlyContinue)
  If(!(Get-Module DataONTAP)){ Wr "Unable to load the DataONTAP PowerShell Toolkit - exiting!" RED; Wr; Wr; EXIT }
  Wr "Loaded the Data ONTAP PowerShell Toolkit!" GREEN; Wr; Wr
}

FUNCTION Get-Credentials {
  Wr ("Username to connect to " + $System + ": ") CYAN; $UserName = Read-Host
  Wr ("Password to connect to " + $System + ": ") CYAN; $Password = Read-Host -AsSecureString
  New-Object System.Management.Automation.PsCredential($UserName,$Password)
}

FUNCTION Connect-ToNetApp {
  [Void](Load-DataOntapPSTK)
  If(!$Global:Credential){ $Global:Credential = Get-Credentials }
  Wr "Checking connection to $System ..." CYAN; Wr
  $Connected = Connect-NaController -Name $System -Credential $Global:Credential -Timeout 20000 -ErrorAction SilentlyContinue
  If($Connected){ Wr "Successfully connected to $System" GREEN; Wr; Wr }
  else {
    Wr "Unable to connect to $System with provided credentials!"; Wr; Wr
    $Global:Credential = ""
    [Void](Connect-ToNetApp)
  }
}

FUNCTION Get-Options{
  [Void](Connect-ToNetApp)
  $global:CurrentNaController.vfiler = ""
  If($vFiler -ne "vFiler0"){
    [System.Array]$VfilerList = (Get-NaVfiler).Name
    If( !($VfilerList -contains $vFiler) ){ Wr "Vfiler $vFiler does not exist - Vfilers are $Vfilerlist - exiting!" RED; Wr; Wr; EXIT }
    $global:CurrentNaController.vfiler = $vFiler
  }
  $Options = Get-NaOption
  If($Options){ Wr "Acquired options for $System $vFiler" GREEN; Wr; Wr }
  [System.Array]$OptionsArray = @()
  $Options | Foreach{ $OptionsArray += ([String]$_.name + " " + [String]$_.value) }
  $OptionsArray | Set-Content ($ConfigDirectory + "/OPTIONS")
}     

[System.Object]$Global:NaOptions   = @{}
[System.Array ]$Global:OptionsList = @()
$Systems | Foreach { [System.Object]$Global:NaOptions.$_ = @{} }

0,1 | Foreach {
  $System = $Systems[$_]
  $Vfiler = $Vfilers[$_]
  [String]$ConfigDirectory = ($System + "." + $Vfiler)
  [Void](New-Item -Path $ConfigDirectory -ItemType Directory -Force)
  If(! (Test-Path ($ConfigDirectory + "/OPTIONS")) ){
    Wr ("Path test to " + ($ConfigDirectory + "/OPTIONS") + " failed. Switching to online acquisition.") YELLOW; Wr; Wr
    [Void](Get-Options)
  }
  [System.Object]$Global:NaOptions.$System.$vFiler = @{}
  [System.Array ]$GetOptions = Get-Content ($ConfigDirectory + "/OPTIONS")
  Foreach($Line in $GetOptions){
    $Option  = [String]($Line.Split(" ")[0].Trim(" ","`t"))
    $Setting = [String]($Line.Substring($Option.Length).Trim(" ","`t").Split(" ")[0])
    $Global:NaOptions.$System.$vFiler.$Option = $Setting
    If(  !($Global:OptionsList -Contains $Option) ){ $Global:OptionsList += $Option }
  }
}

[System.Array]$pFilerOnlyOptions = "acp,auditlog,autologout,autosupport,backup,cdpd,cf,cksum_offload,console,coredump,disk,ems,fcp,flexscale,ic,ifgrp,interface,licensed_feature,locking,qos,ra.path_switch,raid,replication,rpc,shelf,sis,snaplock,snapvalidator,snmp,ssl,tape,telnet,tftpd,timed,tls,trusted,vfiler,vol,vsm.smtape".Split(",")
FUNCTION Check-ForPfilerOnlyOptions{
  Param([String]$OptionToCheck)
  Foreach($pFilerOption in $pFilerOnlyOptions){
    If($OptionToCheck.startswith($pFilerOption)){ RETURN $TRUE }
  }
  RETURN $FALSE
}

[Boolean]$pFilerOnlyOption = $FALSE
$Global:OptionsList | Foreach {
  If($SkipPfilerOnlyOptions){
    $pFilerOnlyOption = Check-ForPfilerOnlyOptions $_
  }
  If( !($SkipPfilerOnlyOptions -and $pFilerOnlyOption) ){
    $OptionA = [String]($Global:NaOptions.$SystemA.$VfilerA.$_)
    $OptionB = [String]($Global:NaOptions.$SystemB.$VfilerB.$_)
    [String]$Color = "GREEN"
    If($OptionA -ne $OptionB){ $Color = "RED" }
    If(!$JustMismatches -or ($Color -eq "RED")){
      Wr ($_.padright(35," ").Substring(0,35)) $Color; Wr " <=> "
      If($OptionA){ Wr $OptionA.padright(18," ").Substring(0,18) GREEN }else{ Wr "".padright(18," ") }; Wr " : "
      If($OptionB){ Wr $OptionB.padright(18," ").Substring(0,18) $Color }else{ Wr "".padright(18," ") }; Wr
    }
  }
}; Wr


No comments:

Post a Comment