Skip to content

Commit 7150399

Browse files
backup cleanup
1 parent f8dcaa7 commit 7150399

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

CIPPTimers.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,14 @@
203203
"Priority": 20,
204204
"RunOnProcessor": true,
205205
"IsSystem": true
206+
},
207+
{
208+
"Id": "b8f3c2e1-5d4a-4f7b-9a2c-1e6d8f3b5a7c",
209+
"Command": "Start-BackupRetentionCleanup",
210+
"Description": "Timer to cleanup old backups based on retention policy",
211+
"Cron": "0 0 2 * * *",
212+
"Priority": 21,
213+
"RunOnProcessor": true,
214+
"IsSystem": true
206215
}
207216
]
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
function Invoke-ExecBackupRetentionConfig {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
.ROLE
6+
CIPP.AppSettings.ReadWrite
7+
#>
8+
[CmdletBinding()]
9+
param($Request, $TriggerMetadata)
10+
$Table = Get-CIPPTable -TableName Config
11+
$Filter = "PartitionKey eq 'BackupRetention' and RowKey eq 'Settings'"
12+
13+
$results = try {
14+
if ($Request.Query.List) {
15+
$RetentionSettings = Get-CIPPAzDataTableEntity @Table -Filter $Filter
16+
if (!$RetentionSettings) {
17+
# Return default values if not set
18+
@{
19+
RetentionDays = 30
20+
}
21+
} else {
22+
@{
23+
RetentionDays = [int]$RetentionSettings.RetentionDays
24+
}
25+
}
26+
} else {
27+
$RetentionDays = [int]$Request.Body.RetentionDays
28+
29+
# Validate minimum value
30+
if ($RetentionDays -lt 7) {
31+
throw 'Retention days must be at least 7 days'
32+
}
33+
34+
$RetentionConfig = @{
35+
'RetentionDays' = $RetentionDays
36+
'PartitionKey' = 'BackupRetention'
37+
'RowKey' = 'Settings'
38+
}
39+
40+
Add-CIPPAzDataTableEntity @Table -Entity $RetentionConfig -Force | Out-Null
41+
Write-LogMessage -headers $Request.Headers -API $Request.Params.CIPPEndpoint -message "Set backup retention to $RetentionDays days" -Sev 'Info'
42+
"Successfully set backup retention to $RetentionDays days"
43+
}
44+
} catch {
45+
$ErrorMessage = Get-CippException -Exception $_
46+
Write-LogMessage -headers $Request.Headers -API $Request.Params.CIPPEndpoint -message "Failed to set backup retention configuration: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
47+
"Failed to set configuration: $($ErrorMessage.NormalizedError)"
48+
}
49+
50+
$body = [pscustomobject]@{'Results' = $Results }
51+
52+
return ([HttpResponseContext]@{
53+
StatusCode = [HttpStatusCode]::OK
54+
Body = $body
55+
})
56+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
function Start-BackupRetentionCleanup {
2+
<#
3+
.SYNOPSIS
4+
Start the Backup Retention Cleanup Timer
5+
.DESCRIPTION
6+
This function cleans up old CIPP and Tenant backups based on the retention policy
7+
#>
8+
[CmdletBinding(SupportsShouldProcess = $true)]
9+
param()
10+
11+
try {
12+
# Get retention settings
13+
$ConfigTable = Get-CippTable -tablename Config
14+
$Filter = "PartitionKey eq 'BackupRetention' and RowKey eq 'Settings'"
15+
$RetentionSettings = Get-CIPPAzDataTableEntity @ConfigTable -Filter $Filter
16+
17+
# Default to 30 days if not set
18+
$RetentionDays = if ($RetentionSettings.RetentionDays) {
19+
[int]$RetentionSettings.RetentionDays
20+
} else {
21+
30
22+
}
23+
24+
# Ensure minimum retention of 7 days
25+
if ($RetentionDays -lt 7) {
26+
$RetentionDays = 7
27+
}
28+
29+
Write-Host "Starting backup cleanup with retention of $RetentionDays days"
30+
31+
# Calculate cutoff date
32+
$CutoffDate = (Get-Date).AddDays(-$RetentionDays).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
33+
34+
$DeletedCounts = [System.Collections.Generic.List[int]]::new()
35+
36+
# Clean up CIPP Backups
37+
if ($PSCmdlet.ShouldProcess('CIPPBackup', 'Cleaning up old backups')) {
38+
$CIPPBackupTable = Get-CippTable -tablename 'CIPPBackup'
39+
$Filter = "PartitionKey eq 'CIPPBackup' and Timestamp lt datetime'$CutoffDate'"
40+
41+
$OldCIPPBackups = Get-AzDataTableEntity @CIPPBackupTable -Filter $Filter -Property @('PartitionKey', 'RowKey', 'ETag')
42+
43+
if ($OldCIPPBackups) {
44+
Write-Host "Found $($OldCIPPBackups.Count) old CIPP backups to delete"
45+
Remove-AzDataTableEntity @CIPPBackupTable -Entity $OldCIPPBackups -Force
46+
$DeletedCounts.Add($OldCIPPBackups.Count)
47+
Write-LogMessage -API 'BackupRetentionCleanup' -message "Deleted $($OldCIPPBackups.Count) old CIPP backups" -Sev 'Info'
48+
} else {
49+
Write-Host 'No old CIPP backups found'
50+
}
51+
}
52+
53+
# Clean up Scheduled/Tenant Backups
54+
if ($PSCmdlet.ShouldProcess('ScheduledBackup', 'Cleaning up old backups')) {
55+
$ScheduledBackupTable = Get-CippTable -tablename 'ScheduledBackup'
56+
$Filter = "PartitionKey eq 'ScheduledBackup' and Timestamp lt datetime'$CutoffDate'"
57+
58+
$OldScheduledBackups = Get-AzDataTableEntity @ScheduledBackupTable -Filter $Filter -Property @('PartitionKey', 'RowKey', 'ETag')
59+
60+
if ($OldScheduledBackups) {
61+
Write-Host "Found $($OldScheduledBackups.Count) old tenant backups to delete"
62+
Remove-AzDataTableEntity @ScheduledBackupTable -Entity $OldScheduledBackups -Force
63+
$DeletedCounts.Add($OldScheduledBackups.Count)
64+
Write-LogMessage -API 'BackupRetentionCleanup' -message "Deleted $($OldScheduledBackups.Count) old tenant backups" -Sev 'Info'
65+
} else {
66+
Write-Host 'No old tenant backups found'
67+
}
68+
}
69+
70+
$TotalDeleted = ($DeletedCounts | Measure-Object -Sum).Sum
71+
Write-LogMessage -API 'BackupRetentionCleanup' -message "Backup cleanup completed. Total backups deleted: $TotalDeleted (retention: $RetentionDays days)" -Sev 'Info'
72+
73+
} catch {
74+
$ErrorMessage = Get-CippException -Exception $_
75+
Write-LogMessage -API 'BackupRetentionCleanup' -message "Failed to run backup cleanup: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
76+
throw
77+
}
78+
}

0 commit comments

Comments
 (0)