Copy-sqmBackupToArchive
Backup
sqmSQLTool v1.9.211+ · Copy
✓ -WhatIf supported
-Period Month archives the month-end backups, -Period Year the year-end backups. The period is derived from -ReferenceDate (default: today), so on 3 December Month means November and Year means the previous year.
Always On aware. Backups of an availability group sit on changing nodes, depending on the backup preference, and every
msdb knows only its own backups. The function therefore reads the history of all replicas (from sys.availability_replicas), takes the latest full backup per database regardless of which node wrote it, and fetches the files through the admin share of that node. Without an AG it simply uses the given instance.
It will not guess. If a replica cannot be read, the function stops. That replica's
msdb may hold exactly the month-end backup, and an older backup from an incomplete history would be the wrong one. Run as a daily job it simply tries again the next day.
Files are copied per file with robocopy
/XO, never with /MIR or /PURGE. Nothing in the archive is ever deleted or overwritten, so repeated runs are harmless. Retention of the archive is deliberately not part of this function.
Archive layout
| Period | Target directory |
|---|---|
Month | <Destination>\2026\2026-10\<Database>\ |
Year | <Destination>\2026\<Database>\ |
Characters that are not allowed in a folder name are replaced by _. robocopy creates the directories.
Install it as a job
One daily job on every node, active only on the primary through PrimaryOnly = $true. It picks up the month-end backup as soon as the month is over and does nothing on the days after. For year-end backups install a second job with Period = 'Year'. See New-sqmAgentCommandJob.
Parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| -Destination | string | Required | , | Archive directory, local or UNC, for example \\fileserver\sqlarchive. |
| -Period | string | Required | , | Month (month end) or Year (year end). |
| -ReferenceDate | datetime | Optional | today | Date the completed period is derived from. For an older period pass a date in the following month or year. |
| -Database | string[] | Optional | all | Only these databases. Without it: every database with a full backup in the period. |
| -ExcludeDatabase | string[] | Optional | , | Leave these databases out. |
| -IncludeSystemDatabases | switch | Switch | $false | Also master, model and msdb. |
| -AvailabilityGroupName | string | Optional | all AGs | Only use the replicas of this availability group. |
| -SqlInstance | string | Optional | $env:COMPUTERNAME | Instance the replicas are looked up from. In an AG any replica works. |
| -SqlCredential | PSCredential | Optional | , | SQL authentication for all connections. |
| -EnableException | switch | Switch | $false | Throw if a copy failed (after all databases were processed) or right away if a replica is unreachable. Set automatically inside Agent jobs. |
| -WhatIf / -Confirm | switch | Optional | , | Shows which backup would go where, per database, without copying. |
Execution Flow
Return value
One object per database with DatabaseName, Period, BackupFinish, SourceReplica, FileCount, TargetPath, Status and Message.
| Status | Meaning |
|---|---|
Copied | At least one file of the backup was copied to the archive. |
UpToDate | All files were already in the archive. |
WhatIf | -WhatIf: this backup would have gone to this TargetPath. |
NoBackup | An online user database has no full backup in the period. Written to the log as a warning. |
Skipped | The backup is not on a disk file (tape, TSM/VDI, URL). The message names the device. |
Failed | robocopy exit code 8 or higher. The message carries the code and the file. |
The account running the function needs read access to msdb on every replica, read access to the admin share of the nodes, and write access to the archive.
Examples
What would be archived for the last completed month
Copy-sqmBackupToArchive -Destination "\\fileserver\sqlarchive" -Period Month -WhatIf |
Format-Table DatabaseName, Period, BackupFinish, SourceReplica, FileCount, StatusYear-end backups of 2026, run in January 2027
Copy-sqmBackupToArchive -Destination "\\fileserver\sqlarchive" -Period Year -ReferenceDate "2027-01-15"
Only some databases, system databases included
Copy-sqmBackupToArchive -Destination "D:\Archive" -Period Month `
-Database "SalesDB","HrDB" -IncludeSystemDatabasesDaily job, active only on the primary
New-sqmAgentCommandJob -SqlInstance "SQL01" -JobName "Archiv_Monatsende" `
-ScheduleType Daily -ScheduleTime "05:00" -Command @{
FunctionName = "Copy-sqmBackupToArchive"
Parameters = @{ Destination = "\\fileserver\sqlarchive"; Period = "Month" }
PrimaryOnly = $true
}Restrict to one availability group
Copy-sqmBackupToArchive -Destination "\\fileserver\sqlarchive" -Period Month -AvailabilityGroupName "AG_Prod"