public/maester/azure/Test-MtVaultSoftDelete.ps1
|
<# .SYNOPSIS Checks if all Recovery Services Vaults have Soft Delete enabled .DESCRIPTION This test ensures that all Recovery Services Vaults have Soft Delete enabled by evaluating the `enhancedSecurityState` property. Soft Delete protects backup data from accidental or malicious deletion and is a recommended security control. .EXAMPLE Test-MtVaultSoftDelete Returns true if all vaults have Soft Delete enabled. .LINK https://maester.dev/docs/commands/Test-MtVaultSoftDelete #> function Test-MtVaultSoftDelete { [CmdletBinding()] [OutputType([bool])] param() if (!(Test-MtConnection Azure)) { Add-MtTestResultDetail -SkippedBecause NotConnectedAzure return $null } $nonCompliantVaults = @() $resultsMarkdown = "" try { # Use Azure Resource Graph to get all Recovery Services Vaults across all subscriptions $query = "Resources | where type =~ 'Microsoft.RecoveryServices/vaults' | project id, name, resourceGroup, subscriptionId, location" $vaults = Invoke-MtAzureResourceGraphRequest -Query $query } catch { Add-MtTestResultDetail -SkippedBecause "Custom" -SkippedCustomReason "Failed to get Recovery Services Vaults" -SkippedError $_ return $null } Write-Verbose "Found $($vaults.Count) Recovery Services Vaults to check" foreach ($vault in $vaults) { try { $vaultName = $vault.name $vaultRg = $vault.resourceGroup $subId = $vault.subscriptionId # Get the vault configuration to check soft delete status $vaultConfig = Invoke-MtAzureRequest ` -RelativeUri "/subscriptions/$subId/resourceGroups/$vaultRg/providers/Microsoft.RecoveryServices/vaults/$vaultName/backupconfig/vaultconfig" ` -ApiVersion "2025-02-01" $softDeleteState = $vaultConfig.properties.enhancedSecurityState if (-not $softDeleteState) { $softDeleteState = "Unknown" } if ($softDeleteState -ne "Enabled") { $nonCompliantVaults += "- $vaultName (subscription: $subId, resource group: $vaultRg) has soft delete not enabled (state: $softDeleteState)" } else { $resultsMarkdown += "- $vaultName (subscription: $subId, resource group: $vaultRg) soft delete is enabled.`n" } } catch { $resultsMarkdown += "- Failed to check vault $($vault.name) in subscription $($vault.subscriptionId): $($_.Exception.Message)`n" continue } } if (!$vaults) { $testResult = $true $testResultMarkdown = "No Recovery Services Vaults found" } else { $testResult = $nonCompliantVaults.Count -eq 0 if ($testResult) { $testResultMarkdown = "All $($vaults.Count) Recovery Services Vaults have soft delete enabled.`n`n$resultsMarkdown" } else { $testResultMarkdown = "Some vaults do not have soft delete enabled:`n`n" $testResultMarkdown += ($nonCompliantVaults -join "`n") $testResultMarkdown += "`n`n**Compliant vaults:**`n$resultsMarkdown" } } Add-MtTestResultDetail -Result $testResultMarkdown return $testResult } |