functions/Remove-AzSRRecoveryServiceVaultProtectedItem.ps1
<#
.SYNOPSIS Remove a protected item from a Recovery Service Vault .DESCRIPTION Remove a protected item from a Recovery Service Vault .PARAMETER ProtectedItemId Azure Resource id of the protected item .PARAMETER Async Do not wait until the Protected Item was deleted. Wait time is minium 60 seconds to honor 'Retry-After' HTTP Response .PARAMETER Force Delete Protected Item even if there are still valid Recovery Points .EXAMPLE Get-AzSRSubscription | Get-AzSRRecoveryServiceVault | Get-AzSRRecoveryServiceVaultProtectedItems | Remove-AzSRRecoveryServiceVaultProtectedItem Removes every Protected item when no Recovery Points are available. .NOTES Copyright: (c) 2018 Fabian Bader License: MIT https://opensource.org/licenses/MIT #> function Remove-AzSRRecoveryServiceVaultProtectedItem { [CmdletBinding(SupportsShouldProcess = $True)] param ( [Alias('Id')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateScript( { if ($_ -match "subscriptions\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/resourcegroups\/[\w\d-\.]+\/providers\/microsoft\.RecoveryServices\/vaults\/[\w|()-;\/]+\/backupFabrics\/[\w|()-\/;]+\/protectedItems\/[\w|()-\/;]+$" ) { $true } else { throw "Not a valid 'microsoft.RecoveryServices/vaults' URI" } } )] [string]$ProtectedItemId, [switch]$Async, [switch]$Force ) # Delete a Backup Protected Item # https://docs.microsoft.com/en-us/rest/api/backup/protecteditems/delete Begin { #region Get AccessToken try { $AccessToken = Get-AzCachedAccessToken $LoginHeader = @{ 'authorization' = "Bearer $AccessToken" } } catch { throw $($_.Exception.Message) } #endregion } Process { $baseURI = "https://management.azure.com" $suffixURI = "?api-version=2016-12-01" $uri = $baseURI + $ProtectedItemId + $suffixURI $params = @{ Headers = $LoginHeader Method = 'DELETE' URI = $uri Verbose = $false UseBasicParsing = $true } # Retrieve extended information about the Protected Item $ProtectedItem = Get-AzSRRecoveryServiceVaultProtectedItemExtendedInformation -ProtectedItemId $ProtectedItemId if ($ProtectedItem) { # Only delete the Protected Item if there are no more recoveryPoints if ($Force.IsPresent -or $ProtectedItem.recoveryPointCount -eq 0 ) { if ($PSCmdlet.ShouldProcess("Delete protected item for VM `"$($ProtectedItem.vmName)`" in Resource Group `"$($ProtectedItem.vmResourceGroup)`"")) { try { $Response = Invoke-WebRequest @params if ( $Response.StatusCode -eq 202) { Write-Verbose "Delete request was accepted." if ( -not $Async.IsPresent ) { # Query status until not 'InProgress' if ASync is not present do { Start-Sleep -Seconds $Response.Headers.'Retry-After' $params = @{ Headers = $LoginHeader Method = 'GET' URI = $Response.Headers.'Azure-AsyncOperation' Verbose = $false } $ASyncResponse = Invoke-RestMethod @params } while ($ASyncResponse.status -eq "InProgress") switch ($ASyncResponse.status) { "Canceled" { throw "Delete operation was canceled." } "Failed" { throw "Protected item for VM `"$($ProtectedItem.vmName)`" in Resource Group `"$($ProtectedItem.vmResourceGroup)`" could not be deleted" } "Invalid" { throw "Invalid request" } "Succeeded" { Write-Information "Protected item for VM `"$($ProtectedItem.vmName)`" in Resource Group `"$($ProtectedItem.vmResourceGroup)`" was successfully deleted" } Default {} } } else { Write-Verbose "Azure-AsyncOperation: $($Response.Headers.'Azure-AsyncOperation')" } } else { throw "Request was not accepted. No content provided" } } catch { if ($_.ErrorDetails) { Write-Warning "$(($_.ErrorDetails.Message | ConvertFrom-Json).error.message)" } else { Write-Warning "$($_.Exception.Message)" } } } } else { Write-Warning "Protected item for VM `"$($ProtectedItem.vmName)`" in Resource Group `"$($ProtectedItem.vmResourceGroup)`" still has $($ProtectedItem.recoveryPointCount) Recovery Points. Use Force parameter to delete it anyways." } } } } |