4 Replies Latest reply: May 19, 2016 6:46 AM by Paul Sabin RSS

    Use PowerCLI and Nimble's RESTful API's to auto-create Initiator Groups for all ESXi hosts in vCenter

    Paul Sabin Newbie

      We just purchased our first set of Nimble arrays (AF9000 and CS700) and have begun configuring them. I will be using the REST API's for most of the configurations and thought I would post my progress here. My first Powershell script for the arrays scans the vCenter server for all ESXi hosts and ensures that the relevant Initiator Groups exist on the Nimble array. If it does not exist, the script will create the Initiator Group and populate it with the initiators found on the host. Note, this particular script does not remove any non-existent hosts or WWPN's. You can run the script multiple times without issue, if the IG's and the WWPN's already exist, the script will move onto the next host to check without attempting any changes. I will probably add a couple of whatif statements to allow for dry runs, but it is the end of the day so I thought I'd post as is.




      The latest copies can always be found on the github repo GitHub - justpowershell/nimblestorage_powershell







          The script scans your vCenter ESXi hosts and compares determines if the WWPN's exist in similar named Nimble Initiator groups.

          If the IG or the WWPN does not exist, the script will create them using Nimble's RESTful API.




          Example- Add-NSInitiators.ps1



          Name            : Add-NSInitiators.ps1

          Author          : Paul Sabin @justpaul

          Lastedit        : 05/18/2016



          vCenter name and credentials

          Nimble storage name and credentials






      $nimblearray = read-host "Enter Nimble array DNS name"

      $nimblecred = Get-Credential -Message "Enter credentials for Nimble Array" -UserName "admin"

      $vcenter = read-host "Enter vCenter server name"

      $vcentercred = Get-Credential -Message "Enter credentials for vCenter server"


      [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}


      function get-vmhba {

          param ($esx)

          Write-Verbose "Host: $esx"

          $hbas = Get-VMHostHba -VMHost $esx -Type FibreChannel

          $results = @()

          foreach ($hba in $hbas){

              $result = "" | select Device,Model,WWPN

              $result.Device = $hba.Device

              $result.Model = $hba.model

              $result.WWPN = "{0:x}" -f $hba.PortWorldWideName

              $results += $result


          return $results



      function get-nimbletoken {

          param ([string]$array=$nimblearray,[string]$user=$nimbleusername,[string]$password=$nimblepassword)

          $data = @{

              username = $nimblecred.UserName

           password = $nimblecred.GetNetworkCredential().password



          $body = convertto-json (@{ data = $data })


          $uri = "https://" + $array + ":5392/v1/tokens"

          $token = Invoke-RestMethod -Uri $uri -Method Post -Body $body

          $token = $token.data.session_token

          return $token



      function get-nimbleinitiatorgroups {

          param (




          $uri = "https://" + $array + ":5392/v1/initiator_groups/detail"

          $header = @{ "X-Auth-Token" = $token }

          $igs = Invoke-RestMethod -Uri $uri -Method Get -Headers $header

          $igs = $igs.data

          return $igs



      function format-wwpn {


          ForEach ($position in 14,12,10,8,6,4,2) {$wwpn = $wwpn.Insert($position,":")}

          return $wwpn



      function update-nimbleigs {

          Write-Verbose "update-nimbleigs"

          $global:igs = get-nimbleinitiatorgroups

          $global:ignames = @($igs.name)



      function new-nimbleinitiatorgroup {


          param (






          Write-Verbose "new-nimbleinitiatorgroup $array $token $igname $description"

          $data = "" | select name,description,access_protocol

          $data.name = $igname

          $data.access_protocol = "fc"

          $data.description = $description


          $body = convertto-json (@{ data = $data })

          Write-Verbose $body

          $header = @{ "X-Auth-Token" = $token }

          $uri = "https://" + $array + ":5392/v1/initiator_groups"

          $result = Invoke-RestMethod -Uri $uri -Method Post -Body $body -Header $header


          return $result.data



      function add-nimbleinitiator{


          param (







          Write-Verbose "add-nimbleinitiator $array $token $igname $vmhostname"


          $ig = $igs | where {$_.name -eq $igname}

          $igid = $ig.id

          if (!($ig.id)){

              Write-Error "Could not determine initiator group ID"



          $igfcinitiators = @($ig.fc_initiators)


          $vmhbas = get-vmhba -esx $vmhostname


          $results = @()


          foreach ($vmhba in $vmhbas){

              if ($igfcinitiators.wwpn -notcontains $(format-wwpn $vmhba.WWPN)){

                  $data = "" | select initiator_group_id,access_protocol,wwpn

                  $data.initiator_group_id= $igid

                  $data.access_protocol = "fc"

                  # $data.alias = ("$($vmhostname.split(".")[0])-$($vmhba.Device)").ToUpper()

                  $data.wwpn = format-wwpn $vmhba.WWPN


                  $body = convertto-json (@{ data = $data })

                  Write-Verbose $body

                  $header = @{ "X-Auth-Token" = $token }

                  $uri = "https://" + $array + ":5392/v1/initiators"

                  $results += Invoke-RestMethod -Uri $uri -Method Post -Body $body -Header $header




          return $results.data



      if (!(connect-viserver $vcenter -Credential $vcentercred)){

          Write-Host "There was an error connecting to the vCenter server `"$vcenter`""

          Exit 99



      if (!(get-nimbletoken)){

          Write-Host "There was an error connecting to the Nimble array`"$nimblearray`""

          Exit 99





      $vmclusters = @(Get-Cluster | sort Name)


      Foreach ($vmcluster in $vmclusters){

          $clustername = $vmcluster.Name

          write-host $clustername -ForegroundColor "Green"

          $igclustername = $("IG-$($clustername)").ToUpper()

          if ($ignames -notcontains $igclustername){

              new-nimbleinitiatorgroup -igname $igclustername


          $vmhosts = @($vmcluster | Get-VMHost | sort Name)

          foreach ($vmhost in $vmhosts){

              $vmhostname = $vmhost.Name

              Write-Host "* $vmhostname"

              add-nimbleinitiator -igname $igclustername -vmhostname $vmhostname

              $ighostname = $("IG-$($vmhostname.split(".")[0])").ToUpper()

              if ($ignames -notcontains $ighostname){

                  new-nimbleinitiatorgroup -igname $ighostname


              add-nimbleinitiator -igname $ighostname -vmhostname $vmhostname