Public/Set-UnitySnap.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
Function Set-UnitySnap {

  <#
      .SYNOPSIS
      Modifies snapshot parameters.
      .DESCRIPTION
      Modifies snapshot parameters.
      You need to have an active session with the array.
      .NOTES
      Written by Erwan Quelin under MIT licence - https://github.com/equelin/Unity-Powershell/blob/master/LICENSE
      .LINK
      https://github.com/equelin/Unity-Powershell
      .PARAMETER Session
      Specify an UnitySession Object.
      .PARAMETER ID
      Snapshot ID or Object.
      .PARAMETER Name
      Snapshot name (Applies to block type storage resource snaps only. Filesystem snapshot names cannot be modified).
      .PARAMETER Description
      Snapshot description.
      .PARAMETER isAutoDelete
      Indicates whether the system will automatically delete the snapshot when the pool snapshot space or total pool space reaches an automatic deletion threshold.
      .PARAMETER retentionDuration
      How long (in seconds) to keep the snapshot (Can be specified only if auto delete is set to false).
      .PARAMETER ioLimitParameters
      The IO limit policy that is applied to this snapshot. This is only applicable to attached snapshots.
      .PARAMETER copyName
      Base name for the new snapshot copies or Name of the backup snapshot created before the restore/attach operation occurs.
      .PARAMETER numCopies
      Number of snapshot copies to make.
      .PARAMETER copyStartNum
      Starting number for the group of copies. This number gets appended to the name specified in the copyName argument to form the name of the first snapshot copy. The system increments the number for each new snapshot.
      .PARAMETER copy
      Copy a snapshot.
      .PARAMETER restore
      Restore the snapshot to the associated storage resource.
      .PARAMETER refresh
      Refresh the snapshot to the associated storage resource.
      .PARAMETER attach
      Attach the snapshot so hosts can access it. Attaching a snapshot makes the snapshot accessible to configured hosts for restoring files and data.
      .PARAMETER detach
      Detach the snapshot so hosts can no longer access it.
      .PARAMETER Confirm
      If the value is $true, indicates that the cmdlet asks for confirmation before running. If the value is $false, the cmdlet runs without asking for user confirmation.
      .PARAMETER WhatIf
      Indicate that the cmdlet is run only to display the changes that would be made and actually no objects are modified.
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Description 'Modified description'

      Change the description of the snapshot with ID '171798691854'
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Copy -numCopies 2

      Copy 2 times the snapshot with ID '171798691854'
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Restore

      Restore the snapshot with ID '171798691854' to the associated storage resource.
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Attach

      Attach the snapshot with ID '171798691854' so hosts can access it.'
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Detach

      Detach the snapshot with ID '171798691854' so hosts can no longer access it.
      .EXAMPLE
      Set-UnitySnap -ID '171798691854' -Refresh

      Refreshes snapshot with ID '171798691854' with the latest data from the parent LUN.
  #>


  [CmdletBinding(SupportsShouldProcess = $True,ConfirmImpact = 'High',DefaultParameterSetName="Set")]
  Param (
    #Default Parameters
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'EMC Unity Session')]
    [Parameter(Mandatory = $false,ParameterSetName="Copy",HelpMessage = 'EMC Unity Session')]
    [Parameter(Mandatory = $false,ParameterSetName="Restore",HelpMessage = 'EMC Unity Session')]
    [Parameter(Mandatory = $false,ParameterSetName="Attach",HelpMessage = 'EMC Unity Session')]
    [Parameter(Mandatory = $false,ParameterSetName="Detach",HelpMessage = 'EMC Unity Session')]
    [Parameter(Mandatory = $false,ParameterSetName="Refresh",HelpMessage = 'EMC Unity Session')]
    $session = ($global:DefaultUnitySession | where-object {$_.IsConnected -eq $true}),
    
    #ID
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Set",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Copy",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Restore",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Attach",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Detach",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [Parameter(Mandatory = $true,Position = 0,ParameterSetName="Refresh",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,HelpMessage = 'Snapshot ID or Object.')]
    [String[]]$ID,

    # Set
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'Snapshot name (Applies to block type storage resource snaps only. Filesystem snapshot names cannot be modified).')]
    [String[]]$name,
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'Snapshot description.')]
    [String]$Description,
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'Auto delete policy for snapshot')]
    [bool]$isAutoDelete,
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'How long to keep the snapshot (Can be specified only if auto delete is set to false).')]
    [uint64]$retentionDuration,
    [Parameter(Mandatory = $false,ParameterSetName="Set",HelpMessage = 'The IO limit policy that is applied to this snapshot. This is only applicable to attached snapshots.')]
    [String]$ioLimitParameters,

    # Copy
    [Parameter(Mandatory = $true,ParameterSetName="Copy",HelpMessage = 'Copy a snapshot.')]
    [switch]$copy,
    [Parameter(Mandatory = $false,ParameterSetName="Copy",HelpMessage = 'Number of snapshot copies to make.')]
    [Uint32]$numCopies,
    [Parameter(Mandatory = $false,ParameterSetName="Copy",HelpMessage = 'Starting number for the group of copies.')]
    [Uint32]$copyStartNum,

    # Restore
    [Parameter(Mandatory = $true,ParameterSetName="Restore",HelpMessage = 'Restore the snapshot to the associated storage resource. ')]
    [switch]$restore,

    # Attach
    [Parameter(Mandatory = $true,ParameterSetName="Attach",HelpMessage = 'Attach the snapshot so hosts can access it.')]
    [switch]$attach,

    # Detach
    [Parameter(Mandatory = $true,ParameterSetName="Detach",HelpMessage = 'Detach the snapshot so hosts can no longer access it.')]
    [switch]$detach,

    # Refresh
    [Parameter(Mandatory = $true,ParameterSetName="Refresh",HelpMessage = 'Refresh the snapshot data from the parent volume.')]
    [switch]$refresh,

    # Copy, Restore, Refresh & Attach
    [Parameter(Mandatory = $false,ParameterSetName="Copy",HelpMessage = 'Base name for the new snapshot copies.')]
    [Parameter(Mandatory = $false,ParameterSetName="Restore",HelpMessage = 'Name of the backup snapshot created before the restore operation occurs.')]
    [Parameter(Mandatory = $false,ParameterSetName="Attach",HelpMessage = 'Name of the backup snapshot created before the attach operation occurs.')]
    [Parameter(Mandatory = $false,ParameterSetName="Refresh",HelpMessage = 'Name of the backup snapshot created before the attach operation occurs.')]
    [String]$copyName
  )

  Begin {
    Write-Debug -Message "[$($MyInvocation.MyCommand)] Executing function"

    # Variables
    Switch ($PsCmdlet.ParameterSetName) {
      'Set' {
        $URI = '/api/instances/snap/<id>/action/modify'
        $StatusCode = 204
      }
      'Copy' {
        $URI = '/api/instances/snap/<id>/action/copy'
        $StatusCode = 200
      }
      'Restore' {
        $URI = '/api/instances/snap/<id>/action/restore'
        $StatusCode = 200
      }
      'Attach' {
        $URI = '/api/instances/snap/<id>/action/attach'
        $StatusCode = 200
      }
      'Detach' {
        $URI = '/api/instances/snap/<id>/action/detach'
        $StatusCode = 204
      }
      'Refresh' {
        $URI = '/api/instances/snap/<id>/action/refresh'
        $StatusCode = 200
      }
    }
    
    $Type = 'snapshot'
    $TypeName = 'UnitySnap'
  }

  Process {

    Foreach ($sess in $session) {

      Write-Debug -Message "Processing Session: $($sess.Server) with SessionId: $($sess.SessionId)"

      If ($Sess.TestConnection()) {

        Foreach ($i in $ID) {

          #Snap ID are normally integers. Convert it to strings
          If (($i.GetType().Name) -Like "*Int*") {
            $i = $i.ToString()
          }

          # Determine input and convert to object if necessary
          Switch ($i.GetType().Name)
          {
            "String" {
              $Object = get-UnitySnap -Session $Sess -ID $i
              $ObjectID = $Object.id
              If ($Object.Name) {
                $ObjectName = $Object.Name
              } else {
                $ObjectName = $ObjectID
              }
            }
            "$TypeName" {
              Write-Verbose "Input object type is $($i.GetType().Name)"
              $ObjectID = $i.id
              If ($Object = Get-UnitySnap -Session $Sess -ID $ObjectID) {
                If ($Object.Name) {
                  $ObjectName = $Object.Name
                } else {
                  $ObjectName = $ObjectID
                }          
              }
            }
          }

          If ($ObjectID) {

            #### REQUEST BODY

            # Creation of the body hash
            $body = @{}

            Switch ($PsCmdlet.ParameterSetName) {
              'Set' {
                If ($PSBoundParameters.ContainsKey('name')) {
                      $body["name"] = $name
                }

                If ($PSBoundParameters.ContainsKey('description')) {
                      $body["description"] = $description
                }

                If ($PSBoundParameters.ContainsKey('isAutoDelete')) {
                      $body["isAutoDelete"] = $isAutoDelete
                }

                If ($PSBoundParameters.ContainsKey('retentionDuration')) {
                      $body["retentionDuration"] = $retentionDuration
                }

                If ($PSBoundParameters.ContainsKey('ioLimitParameters')) {
                      $body["ioLimitParameters"] = @{}
                      $ioLimit = @{}
                      $ioLimit['id'] = $ioLimitParameters
                      $body["ioLimitParameters"] = $ioLimit
                }
              }
              'Copy' {
                If ($PSBoundParameters.ContainsKey('copyName')) {
                      $body["copyName"] = $copyName
                }

                If ($PSBoundParameters.ContainsKey('numCopies')) {
                      $body["numCopies"] = $numCopies
                }

                If ($PSBoundParameters.ContainsKey('copyStartNum')) {
                      $body["copyStartNum"] = $copyStartNum
                }
              }
              'Restore' {
                If ($PSBoundParameters.ContainsKey('copyName')) {
                      $body["copyName"] = $copyName
                }
              }
              'Attach' {
                If ($PSBoundParameters.ContainsKey('copyName')) {
                  $body["copyName"] = $copyName
                }
              }
              'Refresh' {
                If ($PSBoundParameters.ContainsKey('copyName')) {
                  $body["copyName"] = $copyName
                }
              }
              'Detach' {}
            }

            ####### END BODY - Do not edit beyond this line

            #Show $body in verbose message
            $Json = $body | ConvertTo-Json -Depth 10
            Write-Verbose $Json 

            #Building the URL
            $FinalURI = $URI -replace '<id>',$ObjectID

            $URL = 'https://'+$sess.Server+$FinalURI
            Write-Verbose "URL: $URL"

            #Sending the request
            If ($pscmdlet.ShouldProcess($Sess.Name,"Modify $Type $ObjectName")) {
              $request = Send-UnityRequest -uri $URL -Session $Sess -Method 'POST' -Body $Body
            }
            
            If ($request.StatusCode -eq $StatusCode) {

              Write-Verbose "$Type with ID $ObjectID has been modified"

              Get-UnitySnap  -Session $Sess -ID $ObjectID

            }  # End If ($request.StatusCode -eq $StatusCode)
          } else {
            Write-Warning -Message "$Type with ID $i does not exist on the array $($sess.Name)"
          } # End If ($ObjectID)
        } # End Foreach ($i in $ID)
      } # End If ($Sess.TestConnection())
    } # End Foreach ($sess in $session)
  } # End Process
} # End Function