Check for Over-Aged Clustered ONTAP Snapshots with Powershell

The following script was created to find over-aged snapshots in a multi-cluster Clustered ONTAP environment. The script runs interactively, asks for connection IP and credentials, asks what age we’re looking for as over-aged, and then runs through the cluster checking for over-aged snapshots. When finished checking one cluster, it prompts whether you want to check another. The culmination of the script is an excel spreadsheet report with each cluster on a different tab, and listing all the aged snapshots.

Copy the below and save as getOverAgedSnapshots.ps1 (or whatever name you like) and run!

PS Apologies for the formatting of this script on this blog … and at the end is an image of the script in action and example of the output.

## START COPYING HERE ##

# The following interactive script
#  connects to a NetApp Clustered ONTAP Cluster (or more)
#  prompts for an age beyond which you want to find snapshots
#  then outputs an Excel report of all the aged snapshots
#  + additional information

## Section 1: Import DOT PS, create Excel Workbook, setup templates

Import-module DataOnTap
$xl=New-Object -ComObject "Excel.Application"
$wb=$xl.Workbooks.Add()
$xl.Worksheets.Item("Sheet2").Delete()
$xl.Worksheets.Item("Sheet3").Delete()
$ws=$wb.ActiveSheet
$worksheets=1
$confirm_do_loop1 = "y"

# do loop to cycle through clusters
do {

## Section 2: User prompts and connect

echo ""
$controller = Read-host "Enter IP of cluster-mgmt LIF"
$user = Read-host "Enter username"
echo "" "connecting ..."
Connect-NcController $controller -credential $user
echo ""
$daysWorth = Read-host "Enter age of aged snapshots to look for (days)"
if ($worksheets -eq "1"){$filename = Read-host "Enter file name for output file"}
if ($worksheets -eq "1"){$filename = $filename + ".xlsx"}
$units = Read-host "Units for output [g=gigabyte,m=megabyte,k=kilobyte]"
$conversion = 1; $unit = "B"
if ($units -eq "k"){ $conversion = 1024; $unit = "KB" }
if ($units -eq "m"){ $conversion = 1048576; $unit = "MB" }
if ($units -eq "g"){ $conversion = 1073741824; $unit = "GB" }
echo ""

## Section 3: Excel Worksheet Setup

$cells=$ws.Cells
$cells.item(1,1)="Aged Snapshots Report for "+$controller
$cells.item(1,1).font.bold=$True
$cells.item(1,1).font.size=18
$row=2
$col=1
$grandSnapTotal=0

## Section 4: For every Vserver and Volume, find those aged snapshots  

# We're only interested in data Vservers
$template1 = Get-NcVserver -Template
$template1.VserverType = "data"
$vservers = Get-NcVserver -Query $template1

# loop through Vservers
foreach ($vserver in $vservers){

$vserverName = $vserver.Vserver
echo "checking Vserver $vserverName ..."
$row++
$cells.item($row,1)="Vserver $vserverName"
$cells.item($row,1).font.bold=$True
$cells.item($row,1).font.size=16
$row++
$global:CurrentNcController.Vserver = $vserverName

# We only want to pull volume names when run Get-NcVol
$template2 = Get-NcVol -Template
$template2.Name = ""
$volumes = Get-NcVol -Attributes $template2

# loop through Volumes  
foreach ($volume in $volumes){
  
$volumeName=$volume.name
echo "checking volume $volumeName ..."

$snapCount = (Get-NcSnapshot $volumeName | where-object {$_.Created -lt (Get-Date).AddDays(-$daysWorth)} | measure).count
echo " volume $volumeName has $snapCount snapshots older than $daysWorth days"

# ignore volumes with no aged snapshots        
if ($snapcount -ne "0" ){

$row++
$cells.item($row,1)=$volumeName+" has "+$snapcount+" snapshots older than "+$daysWorth+" days."
$cells.item($row,1).font.bold=$True
$cells.item($row,1).font.size=14
$row++

# output column headers             
"Name","Volume","Vserver","Created","Total ($unit)","Cumulative ($unit)","Dependency" | foreach {
$cells.item($row,$col)=$_
$cells.item($row,$col).font.bold=$True
$col++
}

$row++
$col=1
$snapshots = Get-NcSnapshot $volumeName | where-object {$_.Created -lt (Get-Date).AddDays(-$daysWorth)}
$snapSizeTotal = 0

# loop through snapshots outputting info            
foreach ($snapshot in $snapshots){

$cells.item($row,1)=$snapshot.Name
$cells.item($row,2)=$snapshot.Volume
$cells.item($row,3)=$snapshot.Vserver
$cells.item($row,4)=$snapshot.Created
$total=[int]($snapshot.Total/$conversion)
$cells.item($row,5)=$total
$snapSizeTotal = $snapSizeTotal + $total
$cumulative=[int]($snapshot.Cumulative/$conversion)
$cells.item($row,6)=$cumulative
$cells.item($row,7)=$snapshot.Dependency    
$row++
     
} # foreach ($snapshot in $snapshots)

# display the total of the SnapShots
$cells.item($row,4)="TOTAL ($unit)"
$cells.item($row,4).font.bold=$True
$cells.item($row,5)=$snapSizeTotal
$cells.item($row,5).font.bold=$True
$row++
$grandSnapTotal = $grandSnapTotal + $snapSizeTotal
 
} # if ($snapcount -ne "0")

} # foreach ($volume in $volumes)

echo ""

} # foreach ($vserver in $vservers)

# display the GRAND total of the SnapShots
$row++
$cells.item($row,4)="GRAND TOTAL ($unit)"
$cells.item($row,4).font.bold=$True
$cells.item($row,5)=$grandSnapTotal
$cells.item($row,5).font.bold=$True
$row++

# autofit excel columns and name
$range = $ws.UsedRange
$range.EntireColumn.Autofit() | out-null

# name the current worksheet and move it to the end
$ws.name = "$controller"
$lastSheet = $wb.WorkSheets.Item($wb.WorkSheets.Count)
$ws.Move([System.Reflection.Missing]::Value,$lastSheet)
  
# check more clusters?
$confirm_do_loop1 = Read-host "Do you want to check more Clusters (y/n)"
if ($confirm_do_loop1 -eq "y"){$ws=$wb.Worksheets.Add();$worksheets++}

} until ($confirm_do_loop1 -ne "y") # do

## Section 6: Display the Excel Workbook and Save

$xl.Visible=$True
$path = [Environment]::GetFolderPath('MyDocuments')
$path = $path + "\" + $filename
Remove-Item $path -Force -ErrorAction SilentlyContinue
$wb.SaveAs($filename)

# Note: Excel defaults to your documents path and
#  the above deletes any pre-existing file with the same name!

## STOP COPYING HERE ##

Image 1: The Over-Aged Snapshot Check script in action!
Image 2: Example Output (each Cluster will appear on a separate tab)

Comments