Copy-sqmBackupToAgPeer
Backup
sqmSQLTool v1.9.210+ · Copy
✓ -WhatIf supported
You give it only the source directory. The partner servers come from
sys.availability_replicas (the instance part is removed, NODE2\INST1 becomes NODE2; the local replica is skipped), and the target is the partner's admin share with the same path: G:\Backup\Anonym is copied to \\NODE2\G$\Backup\Anonym. With three replicas it copies to both others.
It never deletes and never overwrites a newer file. robocopy runs with
/XO and without /MIR or /PURGE. After a failover the partner may hold the younger state, and that must survive. Running it twice is harmless: the second run copies nothing. The default filter *.bak leaves .tmp files of a backup that is still running alone.
Install it as a job
Use New-sqmAgentCommandJob with PrimaryOnly = $true. The same job is installed on every node, and on a secondary the step ends with success without doing anything, so it follows the failover. Add it as a step after the backup, and as a catch-up job for the case that the copy at the end of the backup was cut short by a failover or a patch reboot.
| When | Purpose |
|---|---|
| Step right after the backup | The partner has the file as soon as it exists. |
| Catch-up job, for example Saturday and Sunday 06:00 | Copies what a failover or a rebooting partner prevented. Idempotent, so it costs nothing when everything is there. |
Parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| -SourcePath | string | Required | , | Local directory with the backups, for example G:\Backup\Anonym. A drive letter is required, because the admin-share path on the partner is built from it. UNC paths are refused. |
| -Filter | string[] | Optional | *.bak | File patterns, for example *_anonym*.bak. Files with another extension, such as .tmp of a running backup, are not copied. |
| -Recurse | switch | Switch | $false | Also copy sub-folders and keep the folder structure on the partner (robocopy /E). Needed for Ola layouts such as <root>\<Server$AG>\<Database>\FULL; without it only the files directly in the source folder are copied. Still nothing is deleted. |
| -AvailabilityGroupName | string | Optional | all AGs | Only use the partners of this availability group. |
| -PartnerServer | string[] | Optional | , | Fix the partner computer names instead of reading them from the AG. For environments without an AG, or for testing. |
| -SqlInstance | string | Optional | $env:COMPUTERNAME | Instance the replicas are read from. The source path is read on the machine the function runs on, so run it locally on the node. |
| -SqlCredential | PSCredential | Optional | , | SQL authentication for the replica query. |
| -EnableException | switch | Switch | $false | Throw after the last partner if a copy failed, so the Agent job step turns red. Set automatically inside Agent jobs. |
| -WhatIf / -Confirm | switch | Optional | , | Shows the target path per partner without copying anything. |
Execution Flow
Return value
One object per partner with SqlInstance, PartnerServer, SourcePath, TargetPath, Status, ExitCode and Message.
| Status | Meaning |
|---|---|
Copied | At least one file was copied (robocopy exit code bit 1). |
UpToDate | Everything was already on the partner. Nothing was copied. |
WhatIf | -WhatIf: this is the path that would have been written. |
Failed | robocopy exit code 8 or higher, for example access denied on the admin share. The message carries the code and the last output lines. |
The account running the function (for an Agent job the service account or a proxy) needs write access to the admin share of every partner.
Examples
Copy a directory to the other replicas, partners found automatically
Copy-sqmBackupToAgPeer -SourcePath "G:\Backup\Anonym"
Ola backups with sub-folders (Server$AG\Database\FULL), structure kept on the partner
Copy-sqmBackupToAgPeer -SourcePath 'F:\Daten\MSSQLSERVER\Backup\Usr-DB' -Recurse
Show the target paths first, copy nothing
Copy-sqmBackupToAgPeer -SourcePath "G:\Backup\Anonym" -Filter "*_anonym*.bak" -WhatIf
Extra step in the existing backup job, active only on the primary
New-sqmAgentCommandJob -SqlInstance "SQL01" -JobName "Anonym_Backup" -AppendStep -Command @{
FunctionName = "Copy-sqmBackupToAgPeer"
Parameters = @{ SourcePath = "G:\Backup\Anonym"; Filter = "*_anonym*.bak" }
PrimaryOnly = $true
}Catch-up job on Saturday and Sunday morning
New-sqmAgentCommandJob -SqlInstance "SQL01" -JobName "Anonym_Backup_Nachkopie" `
-ScheduleType Weekly -ScheduleDays "Saturday","Sunday" -ScheduleTime "06:00" -Command @{
FunctionName = "Copy-sqmBackupToAgPeer"
Parameters = @{ SourcePath = "G:\Backup\Anonym"; Filter = "*_anonym*.bak" }
PrimaryOnly = $true
}No availability group: name the partner yourself
Copy-sqmBackupToAgPeer -SourcePath "G:\Backup\Anonym" -PartnerServer "NODE2"