1 Reply Latest reply: Oct 28, 2016 3:03 PM by Nickolay Milovanov RSS

    Use PowerShell and Nimble's RESTful API's to remove orphaned snapshots

    Paul Sabin Newbie
    Visibility: Open to anyone

      After looking in the community for how to remove orphaned snapshots, I found that the current solution is to create a request for support to build you a script to remove orphaned snapshots en masse. I figured this would be a great opportunity to use Nimble Storage's REST API to find those snapshots and, optionally, remove them. Note, I use PowerShell as my scripting engine of choice, but the script could be modified into a Perl script without much to do. Please note, this is a destructive script; use at your own risk.

       

      The latest version of this script can be found here or at https://github.com/justpowershell/nimblestorage_powershell/blob/master/remove-nssnapshot.ps1

      <#

         .SYNOPSIS

          Removes snapshots from Nimble array based on search criteria.

       

         .DESCRIPTION

          The four functions can be used in conjunction to remove orphaned snapshots (snapshots whose

          lifecycle is no longer being managed automatically and will not be removed without manual

          intervention). The script can also be used to remove snapshots older than a certain date,

          delete all snapshots in a volume, or delete a specific snapshot within a volume.

       

         .EXAMPLE

          #Remove all snapshots not created from the volume's current volume collection, possibly indicating an orphaned snapshot.

          get-nsvol | foreach { $nsvol = $_ ; $_ | get-nssnapshot | where {$_.snap_collection_name -notlike "$($nsvol.volcoll_name)*"} | remove-nssnapshot }

       

          #Show all snapshots older than 7 days that would be removed without the -whatif parameter

          get-nsvol | foreach { $_ | get-nssnapshot | where {$_.creation_time -lt (convertto-epoch ((Get-Date).AddDays(-7)))} | remove-nssnapshot -whatif }

       

          #Remove all snapshots in a volume

          get-nsvol MyVol | get-nssnapshot | remove-nssnapshot

       

          #Remove any snapshots in a volume with 'manual' without a prompt, careful here.

          get-nsvol MyVol | get-nssnapshot | where {$_.description -like "*manual*"} | remove-nssnapshot -confirm:$false

         

        

         .NOTES

          Name            : remove-nssnapshot.ps1

          Author          : Paul Sabin

          Lastedit        : 10/17/2016 11:03:01

       

         .INPUTS

          none

       

         .OUTPUTS

          none

       

         .LINK

          https://devgit01.bakerbotts.net/it_oi/powershell_scripts

      #>

       

      #Requires -Version 4.0

       

      $nsarray = Read-Host "Enter DNS Name for array"  # Replace with your array name

       

      $nscreds = Get-Credential # See http://social.technet.microsoft.com/wiki/contents/articles/4546.working-with-passwords-secure-strings-and-credentials-in-windows-powershell.aspx on how to store credentials in script.

       

      function get-token {

          $nsuser = $nscreds.UserName

          $nspass = $nscreds.GetNetworkCredential().Password

       

          $data = @{

              username = $nsuser

           password = $nspass

          }

       

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

       

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

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

          $global:token = $token.data.session_token

      }

       

      function get-nsvol {

          Param(

              [Parameter(Mandatory=$False,

              ValueFromPipeLine=$True)]

              [string]$name

          )

          get-token

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

          if ($name){

              $uri = "https://" + $array + ":5392/v1/volumes?name=$name"

          } else {

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

          }       

          $volume_list = Invoke-RestMethod -Uri $uri -Method Get -Header $header

          $vol_array = @()

          foreach ($volume_id in $volume_list.data.id){

           $uri = "https://" + $array + ":5392/v1/volumes/" + $volume_id

           $volume = Invoke-RestMethod -Uri $uri -Method Get -Header $header

           #write-host $volume.data.name :     $volume.data.id

           $vol_array += $volume.data

          }

          return $vol_array

      }

       

      function get-nssnapshot {

          Param(

              [Parameter(Position=0,

              Mandatory=$True,

              ValueFromPipeLine=$True, 

              ValueFromPipeLineByPropertyName=$True)]

              [string]$id

          )

          get-token

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

          $uri = "https://" + $array + ":5392/v1/snapshots/detail/?vol_id=$id"

          $nssnapshots = @()

          $nssnapshots += Invoke-RestMethod -Uri $uri -Method Get -Header $header | select -ExpandProperty data

          return $nssnapshots

      }

       

      function remove-nssnapshot {

          [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact="High")]

          Param(

              [Parameter(Mandatory=$True,

              ValueFromPipeLine=$True, 

              ValueFromPipeLineByPropertyName=$True)]

              [string]$id,

              [Parameter(Mandatory=$False,

              ValueFromPipeLine=$True, 

              ValueFromPipeLineByPropertyName=$True)]

              [string]$name="Unknown"

          )

          begin {

              Write-Verbose "$(get-date) starting remove-nssnapshot"

          } process {

              Write-Verbose "id = $id"

              Write-Verbose "name=$name"

       

              if ($pscmdlet.shouldprocess($name)) {       

                  write-host "Removing `"$name`""

                  get-token

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

                  $uri = "https://" + $array + ":5392/v1/snapshots/$id"

                  Invoke-RestMethod -Uri $uri -Method Delete -Header $header

              }

          } end {

              Write-Verbose "$(get-date) ending remove-snapshot"

          }

      }

       

      function convertto-epoch {

          param (

              [Parameter(Mandatory=$True,

              ValueFromPipeLine=$True)]

              [datetime]$date

          )

          [datetime]$origin = '1970-01-01 00:00:00'

          [int]$return = $date - $origin | select -ExpandProperty TotalSeconds

          return $return

      }

       

        • Re: Use PowerShell and Nimble's RESTful API's to remove orphaned snapshots
          Nickolay Milovanov Wayfarer

          @Paul Great work! Any human "busy work" is saved is a win in my book.. I do want to mention couple of gotcha's regarding unmanaged snapshots on Nimble Storage array.

           

          Currently, an unmanaged snapshot is defined as any snapshot not currently managed by an active volume collection schedule.

          This means that snapshots created on volume level manually, snapshot collections created manually, third party app snapshots/collections are considered "unmanaged" by the system.

          Only schedule-generated snapshots which no longer have said schedule are the snapshots which become unmanaged due to configuration error/change.

           

          An interesting case is where volume collection or a schedule is deleted, but one with the same name is created. In this case, the snapshots are in-fact unmanaged, but many scripts which use name comparison cannot detect them.

          The more frequent and more impacting scenario, however, is where a schedule name or a volume collection name was changed without deletion/recreation first. In those scenarios, the snapshots with different name are actually still managed by the schedule and will follow the retention policy. Using name comparison, however will show those snapshots as unmanaged which could lead to unexpected deletion of the snapshot and restore point data loss.

           

          Another very important to note, that it is possible to delete a snapshot which was left in "online" state. Thus, script should account for such scenario and not attempt to delete an "online" snapshot.

           

          I hope this information provides clarification of the potential impacts of using scripts. However, as you have mentioned, script is marked as "Use at your own risk".

           

          Regards,

          Nickolay