Skip to content

Instantly share code, notes, and snippets.

@flakshack
Created July 19, 2017 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flakshack/cc6e2e52f49fc046c8e5c7c533a9a9d2 to your computer and use it in GitHub Desktop.
Save flakshack/cc6e2e52f49fc046c8e5c7c533a9a9d2 to your computer and use it in GitHub Desktop.
NetApp SnapDrive Snapshot Management Script
Option Explicit
'-----------------------------------------------------------------
' Procedure: Snapshot.vbs
' Author: Scott Vintinner
' Last Edit: 07/19/2017
' Purpose: This script will manage NetApp snapshots for the
' specified drive(s) using SnapDrive.
'-----------------------------------------------------------------
'--------
'Settings
'--------
'Location of snapdrive executable
Const SDCLI = "C:\Program Files\NetApp\SnapDrive\sdcli.exe"
'Indicate how many snapshots you want to keep.
Const snapshotCount = 4
'Indicate the naming convention for the snapshot (a date-time will be added to the end).
Const snapshotPrefix = "dmindex-sdcli-snapshot"
'SMTP Mail Server
Const smtpServer = "5.5.5.5"
'Send emails to this address
Const toAddress = "myaddress@mycompany.com"
'Emails come from this address
Const fromAddress = "servername@mycompany.com"
Dim drives
' Identify the drives that we want to snapshot
' NOTE: the drive parameter can be either a drive letter (ex: "G") or a mount point folder (ex: "C:\mydirectory").
' Examples:
' drives = Array("E","F","G")
drives = Array("E")
'--------
'Main
'--------
'Declare our scripting objects
Dim fs, scriptShell, i
Set fs = CreateObject ("Scripting.FileSystemObject")
Set scriptShell = CreateObject("WScript.Shell")
'Figure out the current computer name
Dim network, serverName
Set network = WScript.CreateObject("WScript.Network")
serverName = network.ComputerName
'Open the LogFile for writing
Dim logFile, errorCount, logFileName
errorCount=0
On Error Resume Next
logFileName=WScript.ScriptFullName & " - " & serverName & "-SNAPSHOT.log"
Set logFile = fs.CreateTextFile(logFileName)
LogEntry("Logfile opened")
If Err.Number<>0 Then
wscript.echo("Unable to open the file(s) for writing: " & logFileName)
wscript.quit
End If
On Error Goto 0
'Loop through the list of drives and snapshot them
For i=0 to Ubound(drives)
LogEntry("")
LogEntry("")
LogEntry("--------------------STARTING------------------------")
Call ManageSnapshots(drives(i), snapshotCount, snapshotPrefix)
Call TakeSnapshot(drives(i), snapshotPrefix)
Next
logFile.Close
Set logFile=Nothing
If errorCount > 0 then
Call SendEmail(toAddress, _
fromAddress, _
"Error while taking a snapshot on " & serverName, smtpServer, _
"There was an error while taking a snapshot on " & serverName & ". Please review the attached log file for more info.", _
array(logFileName))
End If
'Clean Up
Set fs=Nothing
Set scriptShell=Nothing
'-------------
'TakeSnapshot
'-------------
Sub TakeSnapshot(driveLetter, snapshotName)
Dim execResult, execCommand, snapSuccess, line
LogEntry("Creating new snapshot...")
snapSuccess = false
snapshotName = snapshotName & "_recent"
'Take the new snapshot
execCommand = SDCLI & " snap create -s " & snapshotName & " -D " & driveLetter
LogEntry("Launching command: " & execCommand)
Set execResult = scriptShell.Exec(execCommand)
Do While Not execResult.StdOut.AtEndOfStream
line=execResult.StdOut.ReadLine()
LogEntry(line)
If Instr(line, "The operation completed successfully.") > 0 Then
snapSuccess=true
End If
Loop
If Not snapSuccess Then
LogError("***It seems that the sdcli.exe command has failed!***")
Else
LogEntry("--------------------FINISHED------------------------")
End If
End Sub
'---------------
'ManageSnapshots
'---------------
Sub ManageSnapshots(driveLetter, snapshotCount, snapshotPrefix)
Dim execResult, execCommand, line, snapshots, index, snapshotName, TypeLib
snapshots=Array("")
'Generate a list of existing snapshots that match our prefix
execCommand = SDCLI & " snap list -d " & driveLetter
LogEntry("Launching command: " & execCommand)
Set execResult = scriptShell.Exec(execCommand)
Do While Not execResult.StdOut.AtEndOfStream
line=execResult.StdOut.ReadLine()
'Parse out the name of the snapshot and stuff it into an array
index = InStr(1,line," ")
line = Trim(Mid(line,1,index))
line = Replace(line, Chr(9), "") 'Replace Tab characters
If InStr(1,line,snapshotPrefix) > 0 Then
snapshots(UBound(snapshots,1)) = Trim(line)
LogEntry("Found snapshot: " & snapshots(Ubound(snapshots,1)) )
'Add room for the next entry in the array
Redim Preserve snapshots(ubound(snapshots,1)+1)
End If
Loop
LogEntry("Found " & ubound(snapshots,1) & " manageable snapshots. Limit is: " & snapshotCount & ".")
'If there are too many snapshots, delete the oldest one
If ubound(snapshots,1) >= snapshotCount Then
LogEntry("Limit of " & snapshotCount & " reached. Deleting oldest snapshot")
'Delete the oldest snapshot (should be the last one added to the snapshots array)
'per Chris Watkins (@ChrisWatkinsUK): The line below is for newer clustered ontap filers. Where the order
'of snapshots returned by the command is reversed.
execCommand = SDCLI & " snap delete -d " & driveLetter & " -s " & snapshots(ubound(snapshots,1)-snapshotCount)
'original 7-mode sort order
'execCommand = SDCLI & " snap delete -d " & driveLetter & " -s " & snapshots(ubound(snapshots,1)-1)
LogEntry("Launching command: " & execCommand)
Set execResult = scriptShell.Exec(execCommand)
Do While Not execResult.StdOut.AtEndOfStream
line=execResult.StdOut.ReadLine()
LogEntry(line)
If Instr(line, "The operation completed successfully.") > 0 Then
LogEntry("Snapshot: " & snapshotName & " successfully deleted.")
Else
If Instr(line, "does not exist and cannot be deleted") > 0 Then
LogEntry("Oldest Snapshot: " & snapshotName & " did not exist.")
End If
End If
Loop
End If
'If there is an _recent snapshot, rename it
For index=0 To UBound(snapshots,1)-1
If InStr(1,snapshots(index),"_recent") > 0 Then
LogEntry("Renaming previous _recent snapshot...")
Set TypeLib = CreateObject("Scriptlet.TypeLib")
snapshotName = snapshotPrefix & "-" & Left(TypeLib.Guid,Len(TypeLib.guid)-2) 'strip off strange nul chars returned by Typelib.GUID
Set TypeLib = Nothing
execCommand = SDCLI & " snap rename -d " & driveLetter & " -o " & snapshots(index) & " -n " & snapshotName
LogEntry("Launching command: " & execCommand)
Set execResult = scriptShell.Exec(execCommand)
Do While Not execResult.StdOut.AtEndOfStream
line=execResult.StdOut.ReadLine()
LogEntry(line)
If Instr(line, "The operation completed successfully.") > 0 Then
LogEntry("Snapshot: " & snapshots(index) & " successfully renamed to " & snapshotName & ".")
Else
LogError("Snapshot: " & snapshots(index) & " could not be renamed.")
End If
Loop
End If
Next
End Sub
'--------
'LogEntry
'--------
Sub LogEntry(logText)
logFile.Write(now & ": " & logText & vbcrlf)
wscript.StdOut.WriteLine(now & ": " & logText)
End Sub
Sub LogError(logText)
LogEntry(logText)
errorCount=errorCount+1
End Sub
'--------
'SendEmail
'--------
Sub SendEmail(recipient, sender, subject, smtpServer, message, attachments)
On Error Resume Next
Dim cdo
Set cdo = CreateObject("CDO.Message")
cdo.From = sender
cdo.To = recipient
cdo.Subject = subject
cdo.HTMLBody = message
Dim attachment
For each attachment in attachments
cdo.AddAttachment(attachment)
Next
cdo.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
cdo.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtpServer
cdo.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
cdo.Configuration.Fields.Update
cdo.send
Set cdo = nothing
If Err.Number<>0 then Wscript.Echo("Error Sending Email!" & vbcrlf & Err.Description)
On Error Goto 0
End Sub
@flakshack
Copy link
Author

flakshack commented Jul 19, 2017

This is a script that I wrote when we had NetApp at my company back in 2008. We have since moved on to different storage, but it seems the script is still being used by some, so I'm posting it here.

The script is intended to be run from a server with SnapDrive installed. The script will handle taking new snapshots, deleting old snapshots and will email reports.

Thanks to @ChrisWatkinsUK for the latest update which allows the script to continue working with Clustered OnTap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment