With the latest release of the ONTAP PowerShell Toolkit, a new set of cluster cmdlets are now available that support cluster setup.
The following cmdlets can be used for cluster setup:

  • Add-NcCluster
  • Add-NcClusterNode
  • Get-NcClusterCreateProgress
  • New-NcCluster

Let’s walk through the process of using these cmdlets. A FAS2552 two-node switchless cluster will be the example system. The prerequisites for this example are:

  1. The latest NetApp PowerShell Toolkit (4.3) has been installed
  2. Node setup has been run on each node
  3. The same admin password has been assigned to each node (security login password)
  4. ONTAP 9.1 GA release (but this should work with 8.3 and higher)
  5. A cluster base license is required

Let’s get started!

Step 1 – Import the DataONTAP module

Open a PowerShell console with “Run as Administrator” and go to your desired script directory (for this example I’ll use c:\Scripts) and import the toolkit:

Import-Module DataONTAP

For our example use the following variables/values:

$cluster_Name = ”FASCLUSTER”
$cluster_IP = “10.0.10.13”
$nodeA_IP = “10.0.10.14”
$nodeB_IP = “10.0.10.15”
$netMask = “255.255.255.0”
$lif = $cluster_Name + “-mgmt”
$nodeA_Name = $cluster_Name + “-01”
$nodeB_Name = $cluster_Name + “-02”

Step 2 – Connect to Node A

Use the IP Address you assigned to the first node. Provide credentials at the prompt.

Connect-NcController $nodeA_IP

Step 3 – Create the cluster

Start the creation process on the first node. Provide your own base license key (below is an example only)

New-NcCluster –ClusterName $cluster_Name –License AAAAAAAAAAAAAAAAAAAAAAAAAAAA

Step 4 – Monitor the creation process

We’ll need to check on the status periodically until it completes successfully. Watch the Status and IsComplete fields.

Get-NcClusterCreateProgress

Step 5 – Switchless cluster mode

Set-NcNetOption –SwitchlessCluster $true

Step 6 – Create Cluster Management Interface

This will create a new management interface using the cluster IP address defined earlier. The –Role setting is critical since it impacts the default failover policy.

New-NcNetInterface –Name $lif –Vserver $cluster_Name –Role cluster_mgmt –Node $nodeA_Name –Port e0M –Address $cluster_IP –Netmask $netMask

Step 7 – Connect to the second node

Connect-NcController $nodeB_IP

Step 8 – Join the second node to the cluster

As before, use the Get-NcClusterCreateProgress to monitor the status of the join.

Add-NcCluster –ClusterName $cluster_Name
Get-NcClusterCreateProgress

Step 9 – Connect to the Cluster

Connect-NcController $cluster_IP

Step 10 – Enable Cluster HA Mode on each node

Respond “Y” to each prompt to confirm the change. There’s a warning to re-boot the node for the change to take effect.

Set-NcClusterHaMode –Node $nodeA_Name –Enable
Set-NcClusterHaMode –Node $nodeB_Name –Enable

Step 11 – Reboot the Cluster

Now let’s restart each node to satisfy the HA mode changes. Reboot the currently connected node LAST or the connection will drop before the other node is restarted. Since we just connected to the cluster, the home node is Node A. Enter “Y” at each prompt to confirm the restart.

Restart-NcNode –IgnoreQuorumWarnings –Node $nodeB_Name
Restart-NcNode –IgnoreQuorumWarnings –Node $nodeA_Name

To verify the cluster has rebooted try the test-connection cmdlet or open a serial console.

Step 12 – Enable Cluster HA

Currently there is no cmdlet to do this so let’s use the Invoke-NcSsh cmdlet to send the CLI command. By default, on 9.1, ssh is NOT enabled for the admin account so we’ll need to add that application first. Connect to the cluster, enable ssh for admin, and enable cluster HA.

Connect-NcController $cluster_IP
New-NcUser –UserName admin –Vserver $cluster_Name –Application ssh –AuthMethod password –Role admin
Invoke-NcSSH –Command “cluster ha modify –configured true”

To disable ssh for admin use the Remove-NcUser cmdlet.

That’s it! The cluster is setup and ready for use. Go to System Manager to verify the cluster is functional.

BONUS CODE

Here’s a full script utilizing the same commands plus some interaction, looping, colorful output, error handling, and lots of re-usability. The required variables are passed on the command line. Add additional cmdlets to create aggregates, SVMS, LIFs, etc and you’ll have an end-to-end automated solution.

This is SAMPLE CODE so use it as a basis to develop – and remember – TEST, TEST, TEST before placing in production!

.\createcluster.ps1 `
  -cluster_Name FASCLUSTER `
  -cluster_IP 10.0.10.13 `
  -nodeA_IP 10.0.10.14 `
  -nodeB_IP 10.0.10.15 `
  -Password netapp123 `
  -base_license {base license key}

# -------------------------------------------------
# Parameters
# -------------------------------------------------
[cmdletbinding()]
Param (
    [Parameter(Mandatory = $True)]  [string]$cluster_Name,
    [Parameter(Mandatory = $True)]  [IPAddress]$cluster_IP,
    [Parameter(Mandatory = $True)]  [IPAddress]$nodeA_IP,
    [Parameter(Mandatory = $True)]  [IPAddress]$nodeB_IP,
    [Parameter(Mandatory = $True)]  [string]$Password,
    [Parameter(Mandatory = $True)]  [string]$base_license
)

# -------------------------------------------------
# Variables
# -------------------------------------------------
$netMask = "255.255.255.0"
$lif = $cluster_Name + "_mgmt"
$nodeA_Name = $cluster_Name + "-01"
$nodeB_Name = $cluster_Name + "-02"
$adminCred = New-Object System.Management.Automation.PSCredential ("admin", (ConvertTo-SecureString $Password -AsPlainText -Force))

# -------------------------------------------------
# Functions
# -------------------------------------------------
function MonitorClusterProgress
{
    $check = $true
    While ($check)
    {
        $result = Get-NcClusterCreateProgress
        
        If ($result.IsComplete)
        {
            If ($result.Status -eq "Success")
            {
                $check = $false
                $status = "Success"
            }
            else
            {
                $status = $result.CurrentStatusMessage
                $check = $false
            }
        }
    }
    Return $status
}

# -------------------------------------------------
# Open console settings and display variables
# -------------------------------------------------
$a = (Get-Host).UI.RawUI
$a.BackgroundColor = "Black"
$a.ForegroundColor = "White"
Clear-Host
Write-Host
Write-Host -ForegroundColor Magenta " Create Cluster Sample Script "
Write-Host -ForegroundColor Gray    " -------------------------------------------- "
Write-Host -ForegroundColor Cyan    " Cluster :   " -NoNewline
Write-Host -ForegroundColor White   "$cluster_Name      $cluster_IP"
Write-Host -ForegroundColor Cyan    " Node A  :   " -NoNewline
Write-Host -ForegroundColor White   "$nodeA_Name   $nodeA_IP"
Write-Host -ForegroundColor Cyan    " Node B  :   " -NoNewline
Write-Host -ForegroundColor White   "$nodeB_Name   $nodeB_IP"
Write-Host -ForegroundColor Cyan    " License :   " -NoNewline
Write-Host -ForegroundColor White   "$base_license"
Write-Host -ForegroundColor Gray    " -------------------------------------------- "
Write-Host -ForegroundColor Yellow  " Continue with these settings (Y|N) ? " -NoNewline
$yesno = Read-Host
Write-Host -ForegroundColor Gray " -------------------------------------------- "
If ($yesno -ne "Y") { Write-Host; EXIT }

# -------------------------------------------------
# Load Toolkit
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Load DataONTAP Module"
$modList = get-module -ListAvailable
if (!($modlist.Name -Contains "DataONTAP")) { Write-Host "`n DataONTAP Module Not Installed `n"; EXIT }

Import-Module DataOntap -Force

# -------------------------------------------------
# Connect to Node A
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Connect to Node A : " -NoNewline
Write-Host -ForegroundColor White $nodeA_IP

$nodeA = Connect-NcController $nodeA_IP -Credential $adminCred

# -------------------------------------------------
# Create Cluster
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Create Cluster " -NoNewline
Write-Host -ForegroundColor White $cluster_Name

New-NcCluster -ClusterName $cluster_Name -License $base_license -ErrorAction Stop

# -------------------------------------------------
# Check Progress
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Monitoring Progress ..... " -NoNewline
$result = MonitorClusterProgress
If ($result -eq "Success")
{
    Write-Host -ForegroundColor White "Success"
}
else
{
    Write-Host -ForegroundColor Red "ERROR"
    Write-Host -ForegroundColor Red "'n $result `n "
    EXIT
}

# -------------------------------------------------
# Two-Node Switchless Cluster (TNSC)
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Set to Two Node Switchless Cluster Mode "

Set-NcNetOption -SwitchlessCluster $true | Out-Null

# -------------------------------------------------
# Create Cluster Management LIF
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Create Cluster Management LIF "

New-NcNetInterface -Name $lif -Vserver $cluster_Name -Role cluster_mgmt -Node $nodeA_Name -Port e0M -Address $cluster_IP -Netmask $netMask | Out-Null

# -------------------------------------------------
# Connect to Node B
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Connect to Node B : " -NoNewline
Write-Host -ForegroundColor White $nodeB_IP

$nodeB = Connect-NcController $nodeB_IP -Credential $adminCred -ErrorAction Stop

# -------------------------------------------------
# Join Node B to Cluster
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Join to Cluster " -NoNewline
Write-Host -ForegroundColor White $cluster_Name

Add-NcCluster -ClusterName $cluster_Name

# -------------------------------------------------
# Check Progress
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Monitoring Progress ..... " -NoNewline
$result = MonitorClusterProgress
If ($result -eq "Success")
{
    Write-Host -ForegroundColor White "Success"
}
else
{
    Write-Host -ForegroundColor Red "ERROR"
    Write-Host -ForegroundColor Red "`n $result `n "
    EXIT
}

# -------------------------------------------------
# Connect to Cluster
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Connect to Cluster : " -NoNewline
Write-Host -ForegroundColor White $cluster_IP

$cluster = Connect-NcController $cluster_IP -Credential $adminCred -ErrorAction Stop

# -------------------------------------------------
# Set HA Mode on each node
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Set HA Mode on each node "

Set-NcClusterHaMode -Node $nodeA_Name -Enable -Confirm:$false -WarningAction SilentlyContinue
Set-NcClusterHaMode -Node $nodeB_Name -Enable -Confirm:$false -WarningAction SilentlyContinue

# -------------------------------------------------
# Reboot
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Reboot - Waiting ... " -NoNewline

Restart-NcNode -IgnoreQuorumWarnings -Node $nodeB_Name -Confirm:$false -WarningAction SilentlyContinue
Restart-NcNode -IgnoreQuorumWarnings -Node $nodeA_Name -Confirm:$false -WarningAction SilentlyContinue

sleep 120
$offline = $true
while ($offline)
{
    $online = Test-Connection -ComputerName $cluster_IP -Quiet
    If ($online)
    {
        $offline = $false
    }
    sleep 5
}
sleep 30
Write-host

# -------------------------------------------------
# Connect to Cluster
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Connect to Cluster : " -NoNewline
Write-Host -ForegroundColor White $cluster_IP

$cluster = Connect-NcController $cluster_IP -Credential $adminCred -ErrorAction Stop

# -------------------------------------------------
# Enable SSH for admin (if disabled)
# -------------------------------------------------
If (!((Get-NcUser admin).Application -contains "ssh"))
{
    $ssh_disabled = $true
    Write-Host -ForegroundColor Cyan " Enable SSH Access for admin "
    
    New-NcUser -UserName admin -Vserver $cluster_Name -Application ssh -AuthMethod password -Role admin | Out-Null
    
}
else
{
    $ssh_disabled = $false
}

# -------------------------------------------------
# Enable Cluster HA
# -------------------------------------------------
Write-Host -ForegroundColor Cyan " Enable Cluster HA "

Invoke-NcSSH -Command "cluster ha modify -configured true" | Out-Null

# -------------------------------------------------
# Disable SSH for admin if previously off
# -------------------------------------------------
If ($ssh_disabled)
{
    Write-Host -ForegroundColor Cyan " Disable SSH Access for admin "
    
    Remove-NcUser -UserName admin -Vserver $cluster_Name -Application ssh -AuthMethod password -Confirm:$false
    
}

Write-Host -ForegroundColor Gray " -------------------------------------------- "

# -------------------------------------------------
# Open System Manager in default browser?
# -------------------------------------------------
Write-Host -ForegroundColor Yellow " Open System Manager (Y|N) ? " -NoNewline
$yesno = Read-Host
If ($yesno -eq "Y")
{
    $sysMgrUrl = "https://" + $cluster_IP + "/sysmgr/SysMgr.html"
    
    Start-Process -FilePath $sysMgrUrl
    
}
Write-Host -ForegroundColor Gray " -------------------------------------------- `n"

# -------------------------------------------------
# END
# ------------------------------------------------------
John Champion
Professional Services Consultant at NetApp
John joined NetApp in February 2015 as a DoD Professional Services Consultant and has worked in the IT industry for over 30 years. He has extensive experience with automation, virtualization, and system integration. Currently involved with software defined storage and an active contributor to the ONTAP Select project.