SANKit - Code written Specifically to meet a customers needs to Automate Host Based Software

by New Contributor on ‎2011-04-12 09:48 AM

The following code is written for a specific customer to enable them to install SAN enabling Host code on thousands of machines taking very little effort from a small SAN team.

See http://blogs.netapp.com/msenviro/ and the SANKit blog post dated March 8th for more details.

#############################################################################################
# SANKit 1.0 Release
# Written by Chris Lionetti and B Sadhana
# (C) Jan 2011 NetApp
#
# This Powershell script is intended to install the following applications
#   Emulex FC   HBA Driver/BIOS
#   Emulex FCoE HBA Driver/BIOS
#   Microsoft FCInfo Tool (MSDN)
#   Netapp Windows Host Utilities
#   Netapp MPIO DSM Module
#
# This Powershell script is intended to run on the following OS
#   Microsoft Windows 2008r2
#   Microsoft Windows 2008r2sp1
#
# This Powershell script will store a text version of the LOG in the C:\SANKIT\LOG directory
#
# Only Available Options during Runtime are
#
# -whatif  This option will show you what actions need to be taken. Will change NOTHING
# -force  This option will ignore results of the three saftey checks.
# -Verbose This option will put all informational messages into the Event log/log/screen
#    Normally Info Type messages are Supressed
#
# Safety Checks
# 1). The script will abort if it finds EMC PowerPath, Navi CLI or Navi Agent installed
# 2). The script will not update drivers/BIOS on HBAs with LIVE LUNs attached
# 3). The script will not install NetApp DSM or WHUK if a NetApp WWN is not discovered on SAN
#
# Valid Exit Codes
# 0 SANKit Successfully completed.
# 1 SANKit Aborted due to a fault or missing pre-requisite such as No HBAs detected
# 2 SANKit Completed, but needing a reboot that it could not do. Please reboot and rerun
#############################################################################################
param(
[Switch]$whatif,
[switch]$force,
[switch]$verbose
)
 
$RebootRequired = $SuppressReboot = $False

function PostEvent([String]$TextField, [string]$EventType)
{ # Subroutine to Post Events to Log/Screen/EventLog
  $outfile = "C:\sankit\logs\netapp.log"
  if (! (test-path $OUTFILE))
  { $suppress = mkdir c:\SANKit\Logs
  }
 
  if (! (test-path HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\application\SanKit) )
  { New-Eventlog -LogName Application -source SANKit
   PostEvent "Creating Eventlog\Application\SANKit Eventlog Source" "Warning"
  }
  else
  { switch -wildcard ($Eventtype)
   { "Info*"  { $color="gray" }
    "Warn*"  { $color="green" }
    "Err*"  { $color="yellow" }
    "Cri*"  { $color="red"
         $EventType="Error" }
    default  { $color="gray" }
   }
   if (!(!($verbose) -and ($EventType -eq "Information")))
   { write-host "- "$textfield -foregroundcolor $color
    Write-Eventlog -LogName Application -Source SANKit -EventID 1 -Message $TextField -EntryType $EventType -Computername "." -category 0
    $testfield | out-file -filepath $outfile -append
   }
  }
}

function FindApp([String]$AppName)
{ # Subroutine to Look for a Specific Application Installation
  $TestResult=[boolean](get-itemproperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' | where {$_.displayname -like $Appname})
  if ($TestResult)
  { PostEvent "Found the $AppName Tool installed" "Warning"
  }
  Return $TestResult 
}

function WaitForInstallComplete([String]$AppName)
{ # Subroutine to Loop over an Installation until it completes, or err out in 30 Seconds
  $TestResult=$False
  $StartCount=1
  While ($StartCount -lt 5)
   { Write-host "- Waiting until Installation Completes"
    start-sleep(15)
    $installedApps=get-itemproperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    foreach ($app in $installedApps)
    { if ($app.displayname -like $AppName)
     { PostEvent "Detected $AppName Installed Correctly" "warning"
      $TestResult=$True
      $StartCount = 5
     }
    }
    $StartCount=$StartCount+1
   }
  if ($TestResult)
   { Return
   }
   Else
   { $ErrText=$Appname+"FAILED Installation. Timed Out during installation"
    PostEvent $ErrText "Critical"
    Exit 1 # Exit Code for Failure of SANKIT to Install
   }
}

function PrintStartBanner
{ # SANKit Banner
  cls
  Write-host "-----------------------------------------------------------"
  Write-host "- SANKit 1.0 NetApp Starting Execution                    -"
  Write-host "-----------------------------------------------------------"
  if ($verbose)
  { Write-host "- All Relevent Logs posted to NT Event Viewer - Source = SANKIT"
   Write-host "-     All White Text is Screen Output Only for interactive users"
   Write-host "-     All Gray Text is Informational (suppressed unless -verbose is used)"
   Write-host "-     All Green Text is Successfuly Action (Warning)"
   Write-host "-     All Yellow Text is Incomplete Action (Error)"
   Write-host "-     All Red Text is Failure - Abort Action (Critical)"
  }
  PostEvent "Posting Event that SANKit is starting " "Warning"
  PostEvent "Runtime Switches; Whatif =$whatif, The Force =$force, Verbose = $verbose " "Information"
  PostEvent "Supported HBAs = Emulex LP1050  - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP10000 - Driver 7.2.32.002 Bios 1.92a1" "Information"
  PostEvent "Supported HBAs = Emulex LP111   - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LPe111  - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP1150  - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LPe1150 - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP11002 - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP1250  - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP12000 - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex LP12002 - Driver 7.2.32.002 Bios 2.82a4" "Information"
  PostEvent "Supported HBAs = Emulex OCe10102-F Driver 7.2.32.002 Bios 2.102.200.17" "Information"
  PostEvent "Supported Version of Windows Host Utility Kit = 5.3" "information"
  PostEvent "Supported Version of NetApp MPIO DSM = 3.4.1" "information"
}

 
PrintStartBanner
# Copy SANKIT code to the C:\SANKIT\Netapp Directory
if (test-path "C:\SANKit\NetApp")
{ PostEvent "SANKIT Detected at C:\SANKIT\NETAPP. No Need to Copy" "Warning"
}
else
{ if ($whatif)
{  PostEvent "WHATIF : Copying SANKit from X:\SANKIT\NETAPP to Local C:\SANKIT\NETAPP" "Warning"
}
Else
{ PostEvent "Copying SANKit from X:\SANKIT\NETAPP to Local C:\SANKIT\NETAPP" "Warning"
  if (test-path "X:\SANKIT\NetApp")
   { xcopy x:\sankit\* c:\sankit\ /s /e /c /q /g /h /r /k /y
   }
  else
   { PostEvent "Either Copy the SANKIt to C:\SANKIT\NETAPP and run locally or mount GMAS server such that X:\SANKit\NetApp exists and re-run SANKIT" "Critical"
    Exit 1 # Exit Code for Failure of SANKIT to Install
   }
}
}
#
# Looking for EMC Software
if ((findapp "EMC Power*") -or (findapp "Navisphere Agent*") -or (findapp "Navisphere CLI*"))
{  if ($force)
{ PostEvent "EMC Software Detected, but FORCE Argument Detected. Continuing Installation" "Error"
}
Else
{ postEvent "EMC Software Detected. Aborting Installation of SANKit" "Critical"
  Exit 1 # Exit Code for Failure of SANKIT to Install
}
}
else
{ PostEvent "EMC Software Not Detected. SANKit may continue." "Warning"
}
#
# FCTOOL Installation Loop - No Reboot Needed
if (!(findApp "FcInfo*"))
{ if (!($Whatif))
{ $INSTALLCOMMAND = "msiexec /package c:\SANKit\NetApp\FCInfo\fcinfo_amd64.msi /quiet /norestart"
  Invoke-expression $InstallCommand
  WaitForInstallComplete "FcInfo*"
}
Else
{ PostEvent "WHATIF : Installation of FCInfo Tool would Occur Here" "Error"
}
}
#
# HBA Installation Loop
if (!(get-module ServerManager))
{ Import-Module ServerManager
PostEvent "Loading PowerShell Server Manager Module is loaded" "Information"
}
Else
{ PostEvent "PowerShell Server Manager Module is already loaded" "Information"
}
$driverupdate = $fwupdate = $EmulexPresent = $EmulexSupportedCardPresent = $False
if (!(Test-path("C:\windows\system32\fcinfo.exe")))
{
  if ($WhatIF)
   { PostEvent "WHATIF : Cannot Detech HBAs without FCInfo Installed, Continuing with Installation Whatif Scenerio" "Error" 
   }
  else
   { PostEvent "Cannot Detect HBAs without FCInfo Installed. Exiting Installation" "Critical"
    Exit 1
   }
}
Else
{
[System.Object[]]$fcadap = Get-WmiObject -class MSFC_FCAdapterHBAAttributes -computername "LocalHost" -namespace "root\WMI" -ErrorVariable a -ErrorAction silentlycontinue
if ($FCADAP.count -eq 0)
{ PostEvent "No HBAs found, Exiting Script" "Critical"
  exit 1 # Exit Code for Failure of SANKIT to Install
}
$ai=0
foreach ($HBA in $FCADAP)
{ $fctoolcmd = "c:\windows\system32\fcinfo /fcpmap /ai:"+$ai  
  $parse = Invoke-Expression $fctoolcmd | where {$_ -match "PhyscialDrive"}
$LunsOnThisHBA = [boolean]$parse # Since I found LUNs,
if (!($SuppressReboot))
{ $SuppressReboot = [boolean]$parse # Since I found LUNs, I want Customer to direct Reboot
} #but I don't want this trigger to go back to false if the next HBA doesnt have luns
Switch -wildcard ($HBA.Model)
{ # Supported Cards are listing here
   "111-00455*"{ # Card name = LPe1150
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "wf282a4.all" }
   "111-00454*"{ # Card name = LPe11002
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "zf282a4.all" }
   "111-00453*"{ # Card name = LPe11000
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "zd282a4.all" }
   "111-00294*"{ # Card name = LP11000e
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "zd282a4.all" }
   "111-003D8*"{ # Card name = LP11002
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "zd282a4.all" }
   "111-000D161*"{ # Card name = LP10000
       $HBADrv = "7.2.32.002"
       $HBAFw = "1.92a1"
       $FWDriver = "td192a1.all" }
   "111-000D778*"{ # Card name = OCe10102-FX
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.102.200.17"
       $FWDriver = "S2200017.ufi" }
   "111-000D777*"{ # Card name = OCe10102-FM
       $HBADrv = "7.2.32.002"
       $HBAFw = "2.102.200.17"
       $FWDriver = "S2200017.ufi" }
   "LPe111*" { $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "ym282a4.all" }
   "1050*"  { $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "mb282a4.all" }
   "1150*"  { $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "wf282a4.all" }
   "1250*"  { $HBADrv = "7.2.32.002"
       $HBAFw = "2.82A4"
       $FWDriver = "ob282a4.all" }
   Default  { $HBADrv = $HBAFw = $FWDriver = "" }
}
if (!($EmulexSupportedCardPresent)) # if the value is true, dont want it flipping back if later card is false
{ $EmulexSupportedCardPresent = [Boolean](!($FWDriver -eq ""))
}
if (!($FWDriver -eq ""))
  { $text= "Found HBA"+$HBA.Manufacturer+" : "+$HBA.Model+", Driver "+$HBA.DriverVersion+", Firmware "+$HBA.FirmwareVersion+", Serial"+$HBA.SerialNumber
   PostEvent $text "warning"
   if ($HBA.DriverVersion -ne $hbadrv)
   { $text = "HBA with WWN"+$HBA.Serial+$HBA.SerialNumber+" Running Driver "+$HBA.DriverVersion+" Will be updated to Driver Version "+$HBADRV
    PostEvent $Text "Error"
    if ($LunsOnThisHBA -and !($Force))
    { PostEvent "LIVE LUNs Detected on this HBA. Cannot Update Driver" "Critical"}
    else
    { if ($WhatIF)
     { PostEvent "WHATIF -  Updating Emulex Driver on the HBA" "Warning"
     }
     else
     { PostEvent "Updating Emulex Driver on the HBA" "Warning"
      $INSTALLCOMMAND = [System.Diagnostics.Process]::Start("cmd.exe", "/c start /wait C:\SANKit\NetApp\Emulex\Driver\elxocm-windows-5.00.52.03-2 /q")
      $INSTALLCOMMAND.WaitForExit()
      $RebootRequired=$True #Driver Update requires a Reboot
     }
    }
   }
   if ($HBA.FirmwareVersion -ne $hbafw)
   { $text = "HBA with Serial #"+$HBA.SerialNumber+" Running Firmware "+$HBA.FirmwareVersion+" Will be updated to Firmware Version "+$HBAFW
    PostEvent $Text "Error"
    if ($LunsOnThisHBA)
    { PostEvent "LIVE LUNs Detected on this HBA. Cannot Update Firmware" "Critical"
    }
    else
    { $INSTALLCOMMAND = [System.Diagnostics.Process]::Start("cmd.exe", "/c start /wait C:\SANKit\NetApp\Emulex\Driver\elxocm-windows-5.00.52.03-2 /q")
    #Invoke-expression $INSTALLCOMMAND | out-null
     $INSTALLCOMMAND.WaitForExit()
     PostEvent "Sleeping for 60 seconds to let the fwupgrade complete" "Information"
     Start-Sleep -s 60
     $findWWN=C:\sankit\netapp\Emulex\driver\hbacmd.exe listhbas | Where {$_ -match "Port WWB"}
     $theWWN=$findwwn[$ai].trimstart('Port WWN :')
     $INSTALLCOMMAND = "c:\sankit\Netapp\Emulex\driver\Hbacmd.exe download "+$thewwn+" c:\sankit\netapp\emulex\bios\"+$FWDriver
                    postevent $InstallCommand "Information"
     Invoke-Expression $INSTALLCOMMAND
                    PostEvent "Sleeping for 60 seconds to let the fwupgrade complete" "Information"
                    Start-Sleep -s 60
                    $RebootRequired = $True
    }
   }
  }
  else
  { $text = "Non-Supported HBA Model "+$HBA.Model+" Running Driver "+$HBA.DriverVersion+" BIOS "+$HBA.FirmwareVersion
   PostEvent $text "Error"
  }
}
$ai=$ai+1
}
if (!($EmulexSupportedCardPresent))
{ PostEvent "Exiting SANKit! No Supported Emulex HBA found" "Critical"
    exit 1 # Exit Code for Failure of SANKIT to Install
}
#
# Find the NetApp WWNs.
if (test-path C:\sankit\netapp\Emulex\driver\hbacmd.exe)
{ $MissingHBACMD=$NetAppTargetPresent=$False
$findWWN=C:\sankit\netapp\Emulex\driver\hbacmd.exe listhbas | where {$_ -match "Port WWN"}
foreach ($line in $findwwn)
{ $wwn=$line.trimstart('Port WWN :')
  $Targetlist = C:\sankit\netapp\Emulex\driver\hbacmd.exe allnodeinfo $wwn | where {$_ -match "50:0A:09"}
  if ($Targetlist)
  { $NetAppTargetPresent=[boolean]$Targetlist
   $text="Found Valid NetApp Target on Host WWN "+$wwn
   postevent $text "Warning"
  }
  else
  { $text="No Valid NetApp Target on Host WWN "+$wwn+" Check Cable and Zoning"
   postevent $text "Error"
  }
 
}
}
else
{ $MissingHBACMD=$True
PostEvent "WHATIF : HBACMD not present, cannot detect NetApp WWNs" "Error"
}
if ($NetAppTargetPresent -or $Force -or ($MissingHBACMD -and $WhatIf))
{ if (!(findapp "NetApp Windows Host U*"))
{ $RebootRequired=$false
  if (!($whatif))
  { PostEvent "App named Netapp Windows Host U* Not Found. Starting Installation" "Error"
   $INSTALLCOMMAND = "msiexec /package c:\SANKit\Netapp\WHUK\netapp_windows_host_utilities_5.3_x64.msi /log C:\sankit\netapp\WHUK\WhukInstall.log /quiet /norestart MULTIPATHING=1"
   Invoke-expression $InstallCommand
   WaitForInstallComplete "NetApp Windows Host U*"
  }
  else
  { PostEvent "WHATIF : App Named NetApp Windows Host U* Not Found. Starting Installation" "Error"
  }
}
# Netapp DSM Installation Kit Loop
if (!(findApp "Data ONTAP DSM*"))
{ $RebootRequired=$True
  if (!($WhatIF))
  { PostEvent "App named $AppName Not Found. Starting Installation" "Error"
   $INSTALLCOMMAND = "msiexec /package c:\sankit\netapp\dsm\ntap_win_mpio_3.4_setup_x64.msi /quiet /log c:\sankit\netapp\logs\DSMlogfile.txt LICESNCECODE=VUDPMTKYAUDCMA USESYSTEMACCOUNT=1"
   Invoke-expression $InstallCommand
   WaitForInstallComplete "DATA ONTAP DSM*"
   $RebootRequired=$True
  }
  else
  { PostEvent "WHATIF : App named $AppName Not Found. Starting Installation" "Error"
  }
}  
}
Else
{ PostEvent "No NetApp Target Discovered, Skipping DSM and WHUK Install" "Error"
}
if ($SuppressReboot -and $RebootRequired -and !($force))
{ PostEvent "A Reboot is required to complete the installation, but LUNs are online, and Reboot has been supressed" "Error"
exit 2 # Exit Code 2 means REBOOT REQUIRED, but otherwise success
}
if ($rebootrequired)
{ PostEvent "Forcing a reboot. Rerun the SANKit after the reboot to ensure all packages installed correctly" "Error"
$INSTALLCOMMAND = "shutdown -r -t 90"
if (!($whatif))
{ Invoke-Expression $INSTALLCOMMAND
}
Else
{ PostEvent "WHATIF : Intercepting Reboot Command - Not Rebooting" "Error"
}
}
PostEvent "SANKit is Ending - Complete" "Warning"
exit 0 # Exit code Success

Comments
bedelen

excellent!

Thank you for this.

I have a need to adapt this a bit, but this will catapault my starting position.

I also need to add snapdrive and snapmanager choices (I see that you are adding that to the next ver).

Warning!

This NetApp Community is public and open website that is indexed by search engines such as Google. Participation in the NetApp Community is voluntary. All content posted on the NetApp Community is publicly viewable and available. This includes the rich text editor which is not encrypted for https.

In accordance to our Code of Conduct and Community Terms of Use DO NOT post or attach the following:

  • Software files (compressed or uncompressed)
  • Files that require an End User License Agreement (EULA)
  • Confidential information
  • Personal data you do not want publicly available
  • Another’s personally identifiable information
  • Copyrighted materials without the permission of the copyright owner

Files and content that do not abide by the Community Terms of Use or Code of Conduct will be removed. Continued non-compliance may result in NetApp Community account restrictions or termination.