UPDATE: CDOT Snapshot Deletor PowerShell (non-interactive for specific volumes)

For an UPDATE of the UPDATE see: PowerShell Script to Delete Aged Snapshots for NetApp Clustered ONTAP

The following post is an update of the PowerShell script from the below post after some development:

Essentially the script is the same except it now:

- Has a customer friendly amount of comment
- Details how to create a minimal permission role and user account to run SnapDeletor
- Outputs to console much more detail (such as the individual Snapshots being deleted, date they were created)
- Outputs to a date-stamped log file at a user specified path
- Has intelligence to know if the volume has no aged Snapshots
- Has intelligence to alert/report if a Snapshot could not be deleted
- Sends a simple text email to an administrator(s)

An example of its use:

The script was designed to work in an environment with Exchange 2010 DAGs across two sites. The remote DAGs required 90 day retention using NetApp SnapManager for Exchange (SME). The Snapshots of the transaction logs beyond 7 days were not required (I mean, who’s going to roll database beyond much more than 7 days of logs and definitely not 90!) And the SME version in use (6.0.4) did not have the ability to have different Snapshot retention on transaction log volumes compared to database volumes. Hence, the script was designed to run as a scheduled task on a management server, to keep the Snapshot retention on the transaction log volumes to a more reasonable level (like 9 days.)

The Script

Save the following script into Notepad++ as say ‘cdotsnapdeletor.ps1’ and run in PowerShell (after first setting credentials with set-cred.ps1):

### START COPYING HERE ###

#############
### TITLE ###
###################################################################
## CDOT Snapshot Deletor of Snapshots older than X days          ##
##  (Non-interactive using Cluster login, and for a specified    ##
##   list of volumes only)                                       ##
###################################################################
## AUTHOR: vCosonok @ www.cosonok.com                            ##
## CREDITS: The awesome PowerShell community on the internet!    ##
###################################################################

######################
## COMMENTS SECTION ##
###################################################################
# For the cluster, cluster user account, Vserver, list of volumes #
#  and number of days specified in SECTION 1: this script will    #
#  delete snapshots older than the specified number of days       #
#  of days. Also specify $logFilePath.                            #
# If you want to email the text report, unhash SECTION 3 and      #
#  specify: email from, email to, and SMTP server                 #
# If you want to run it in "REPORT-MODE" then simply hash out the #
#  one line that starts with Remove-NcSnapshot                    #
# This script does not force delete snapshots, the Powershell     #
#  option "-IgnoreOwners" flag has not been added to the          #
#  Remove-NcSnapshot line                                         #
# SECTION 2: Removes snapshots/does reporting                     #
# SECTION 3: Creates and sends the report as an email             #
# Save this script in notepad/notepad++ as say                    #
#  cdotSnapshotDeletor.ps1 and run in Powershell!                 #
# NOTE: This script designed specifically to trim down snapshots  #
#  on certain volumes to a certain number of days (example:       #
#  remote Exchange DAG transaction log snapshots where a database #
#  retention of 90 days is required but logs only for 7 days, and #
#  SME cannot currently do this (27/11/2013)                      #
###################################################################
# Pre-requisities:                                                #
#  1) The file c:\scripts\encrypted_password.txt must have been   #
#      created first using set-cred.ps1                           #
#      (commented below for reference)                            #
#  2) Additionally the Data ONTAP PowerShell Toolkit must be      #
#      installed, and PowerShell execution policy set accordingly #
#      (RemoteSigned will work.)                                  #
###################################################################
# # set-cred.ps1 file contents
# # Creates a text file with encrypted password string
# # Note: A blank file c:\scripts\encrypted_password.txt must be created first!
# $credential = Get-Credential
# $credential.Password | ConvertFrom-SecureString | Set-Content c:\scripts\encrypted_password.txt
###################################################################
# Using a specific cluster logon account for SnapDeletor:         #
# If you don't want to use your cluster admin account to run this #
# (which you shouldn't really be using for security reasons),     #
# then the following Clustershell commands can be used to         #
# create a SnapDeletor role and SnapDeletor account that will     #
# work with this script                                           #
###################################################################
# ::> sec login role create -role SnapDeletor -cmddirname DEFAULT -access readonly
# ::> sec login role create -role SnapDeletor -cmddirname snapshot -access all
# ::> sec login role create -role SnapDeletor -cmddirname volume -access all
# ::> sec login create -username SnapDeletor -application ontapi -authmethod password -role SnapDeletor
###################################################################
## END OF COMMENTS SECTION ##
#############################

#################################
## SECTION 1: Set Up Variables ##
#################################

# Enter the following variables/lists: $cluster,$username,$vserver,$volumes,$daysWorth,$logFilePath
$cluster = "192.168.168.40"
$username = "SnapDeletor"
$vserver = "vs1"
$volumes = "REMOTEDAG_TL01", "REMOTEDAG_TL02", "REMOTEDAG_TL03"
$daysWorth = 9
$logFilePath = "C:\scripts\logs\"

# These two lines get the encrypted password string from the text file
$encrypted = Get-Content c:\scripts\encrypted_password.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)

# The following section creates the filename for the output report file
$fileTag = "CLUSTER_SnapshotDeletorOutput_"
$dateStamp = (get-date).tostring("yyyyMMddHHmm")
$extension = ".log"
$filename = $filetag + $dateStamp + $extension
$fullPathToFile = $logFilePath + $filename

###################################
## SECTION 2: Removing Snapshots ##
###################################

# NOTE: If you want to test (run in "report-mode"), hash the Remove-NcSnapshot line

# Connect to Cluster
Import-Module DataOnTap
echo "Connecting ... this can take a few minutes!"
Connect-NcController $cluster -Credential $credential -Vserver $vserver
echo "Connected to cluster $cluster and vserver $vserver" ""
echo "Connected to cluster $cluster and vserver $vserver" "" >> $fullPathToFile

# POWERSHELL NOTE 1: If this was Powershell 3.0, we could use:
# > "text","" | tee-object -FilePath $fullPathToFile -Append
# but -Append is not available Powershell pre-3.0.
# POWERSHELL NOTE 2: write-host has more functionality than echo but echo works here for our purposes

echo "The following snapshots are older than $daysWorth days and are being deleted!" ""
echo "The following snapshots are older than $daysWorth days and are being deleted!" "" >> $fullPathToFile

# This line cycles through each volume in the $volumes list
foreach ($volume in $volumes){

echo "" "Volume=$volume" ""
echo "" "Volume=$volume" "" >> $fullPathToFile
$snapshots = Get-NcSnapshot -Volume $volume | where-object {$_.Created -lt (Get-Date).AddDays(-$daysWorth)}

# This if statement operates if $snapshots is not null/empty
if ($snapshots){

# This line cycles through each snapshot in the $snapshots list
foreach ($snapshot in $snapshots){

$snapshotName = $snapshot.name
$snapshotDate = $snapshot.created

# NOTE: If you hash the next line this script just does reporting!
# Remove-NcSnapshot -Volume $volume -Snapshot $snapshotName -confirm:$false

$snapStillThere = Get-NcSnapshot -Volume $volume -Snapshot $snapshotName

# This if statement operates if $snapStillThere is null/empty
if (!$snapStillThere) {
echo "Deleted $snapshotName from $snapshotDate. "
echo "Deleted $snapshotName from $snapshotDate. " >> $fullPathToFile
} # END of if (!$snapStillThere)

# This if statement operates if $snapStillThere is not null/empty
if ($snapStillThere) {
echo "$snapshotName from $snapshotDate @@@@@ WAS NOT DELETED!"
echo "$snapshotName from $snapshotDate @@@@@ WAS NOT DELETED!" >> $fullPathToFile
} # END of if ($snapStillThere)

} # END of "foreach ($snapshot in $snapshots)"

} # END of "if ($snapshots)"

# This if statement operates if $snapshots is null/empty
if (!$snapshots){
echo "Volume $volume has no snapshots older than $daysWorth days!"
echo "Volume $volume has no snapshots older than $daysWorth days!" >> $fullPathToFile
} # END of "if (!$snapshots)

} # END of "foreach ($volume in $volumes)"

echo "" "Snapshot deletion complete." "Report saved as $filename."
echo "" "Snapshot deletion complete." "Report saved as $filename." >> $fullPathToFile

################################################
## SECTION 3: Sending the report as an email! ##
################################################

# Define these 3 email variables
$emailFrom = "noreply@domain.com"
$emailTo = "email1@domain.com,email2@domain.com"
$smtpserver = "smtprelay.domain.com"

# Subject will be the output filename
$subject = $filename

# Email message contents taken from the output file
[string]$message = ""
$messageRaw = get-content -path $fullPathToFile
foreach ($line in $messageRaw) {$message = $message + $line + "`r`n"}

# Send the email
$smtp=new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom, $emailTo, $subject, $message)

### STOP COPYING HERE ###

Illustration

Image: Example of SnapDeletor running on a LAB VSIM and deleting snapshots older than 2 days!

Comments