|
| 1 | +<# |
| 2 | + .SYNOPSIS |
| 3 | + Performs a backup of a SQL Server database. |
| 4 | +
|
| 5 | + .DESCRIPTION |
| 6 | + This command performs a backup of a SQL Server database using SQL Server |
| 7 | + Management Objects (SMO). It supports full, differential, and transaction |
| 8 | + log backups with options for compression, verification, and copy-only |
| 9 | + backups. |
| 10 | +
|
| 11 | + .PARAMETER ServerObject |
| 12 | + Specifies the current server connection object. |
| 13 | +
|
| 14 | + .PARAMETER DatabaseObject |
| 15 | + Specifies a database object to backup. |
| 16 | +
|
| 17 | + .PARAMETER Name |
| 18 | + Specifies the name of the database to backup. |
| 19 | +
|
| 20 | + .PARAMETER BackupFile |
| 21 | + Specifies the full path to the backup file. For full and differential |
| 22 | + backups, use the .bak extension. For transaction log backups, use the |
| 23 | + .trn extension. |
| 24 | +
|
| 25 | + .PARAMETER BackupType |
| 26 | + Specifies the type of backup to perform. Valid values are 'Full', |
| 27 | + 'Differential', and 'Log'. Default value is 'Full'. |
| 28 | +
|
| 29 | + .PARAMETER CopyOnly |
| 30 | + Specifies that a copy-only backup should be performed. Copy-only backups |
| 31 | + do not affect the sequence of conventional backups and are useful for |
| 32 | + taking backups for special purposes without disrupting the normal backup |
| 33 | + chain. This is particularly useful in AlwaysOn Availability Group scenarios. |
| 34 | +
|
| 35 | + .PARAMETER Compress |
| 36 | + Specifies that the backup should be compressed. Backup compression requires |
| 37 | + SQL Server 2008 Enterprise or later, or SQL Server 2008 R2 Standard or later. |
| 38 | +
|
| 39 | + .PARAMETER Checksum |
| 40 | + Specifies that checksums should be calculated and verified during the |
| 41 | + backup operation to help detect backup media errors. |
| 42 | +
|
| 43 | + .PARAMETER Description |
| 44 | + Specifies a description for the backup set. This description is stored |
| 45 | + in the backup media and can be useful for identifying backups. |
| 46 | +
|
| 47 | + .PARAMETER RetainDays |
| 48 | + Specifies the number of days that must elapse before the backup media |
| 49 | + can be overwritten. This provides protection against accidental overwrites. |
| 50 | +
|
| 51 | + .PARAMETER Initialize |
| 52 | + Specifies that the backup media should be initialized (overwritten) rather |
| 53 | + than appending to existing backup sets. Use with caution as this will |
| 54 | + destroy any existing backups on the media. |
| 55 | +
|
| 56 | + .PARAMETER Refresh |
| 57 | + Specifies that the **ServerObject**'s databases should be refreshed before |
| 58 | + accessing the database. This is helpful when databases could have been |
| 59 | + modified outside of the **ServerObject**, for example through T-SQL. But |
| 60 | + on instances with a large amount of databases it might be better to make |
| 61 | + sure the **ServerObject** is recent enough, or pass in **DatabaseObject**. |
| 62 | +
|
| 63 | + .PARAMETER Force |
| 64 | + Specifies that the backup should be performed without any confirmation. |
| 65 | +
|
| 66 | + .EXAMPLE |
| 67 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 68 | + $serverObject | Backup-SqlDscDatabase -Name 'MyDatabase' -BackupFile 'C:\Backups\MyDatabase.bak' |
| 69 | +
|
| 70 | + Performs a full backup of the database named **MyDatabase** to the specified |
| 71 | + backup file. |
| 72 | +
|
| 73 | + .EXAMPLE |
| 74 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 75 | + $databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase' |
| 76 | + $databaseObject | Backup-SqlDscDatabase -BackupFile 'C:\Backups\MyDatabase.bak' -Force |
| 77 | +
|
| 78 | + Performs a full backup of the database named **MyDatabase** using a |
| 79 | + database object from the pipeline, without prompting for confirmation. |
| 80 | +
|
| 81 | + .EXAMPLE |
| 82 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 83 | + $serverObject | Backup-SqlDscDatabase -Name 'MyDatabase' -BackupFile 'C:\Backups\MyDatabase_Diff.bak' -BackupType 'Differential' |
| 84 | +
|
| 85 | + Performs a differential backup of the database named **MyDatabase**. |
| 86 | +
|
| 87 | + .EXAMPLE |
| 88 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 89 | + $serverObject | Backup-SqlDscDatabase -Name 'MyDatabase' -BackupFile 'C:\Backups\MyDatabase.trn' -BackupType 'Log' |
| 90 | +
|
| 91 | + Performs a transaction log backup of the database named **MyDatabase**. |
| 92 | +
|
| 93 | + .EXAMPLE |
| 94 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 95 | + $serverObject | Backup-SqlDscDatabase -Name 'MyDatabase' -BackupFile 'C:\Backups\MyDatabase_CopyOnly.bak' -CopyOnly |
| 96 | +
|
| 97 | + Performs a copy-only full backup of the database named **MyDatabase**. |
| 98 | + This backup does not affect the normal backup chain. |
| 99 | +
|
| 100 | + .EXAMPLE |
| 101 | + $serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance' |
| 102 | + $serverObject | Backup-SqlDscDatabase -Name 'MyDatabase' -BackupFile 'C:\Backups\MyDatabase.bak' -Compress -Checksum |
| 103 | +
|
| 104 | + Performs a compressed full backup with checksum verification of the |
| 105 | + database named **MyDatabase**. |
| 106 | +
|
| 107 | + .INPUTS |
| 108 | + `Microsoft.SqlServer.Management.Smo.Server` |
| 109 | +
|
| 110 | + Server object accepted from the pipeline (ServerObject parameter set). |
| 111 | +
|
| 112 | + .INPUTS |
| 113 | + `Microsoft.SqlServer.Management.Smo.Database` |
| 114 | +
|
| 115 | + Database object accepted from the pipeline (DatabaseObject parameter set). |
| 116 | +
|
| 117 | + .OUTPUTS |
| 118 | + None. |
| 119 | +#> |
| 120 | +function Backup-SqlDscDatabase |
| 121 | +{ |
| 122 | + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('UseSyntacticallyCorrectExamples', '', Justification = 'Because the rule does not yet support parsing the code when a parameter type is not available. The ScriptAnalyzer rule UseSyntacticallyCorrectExamples will always error in the editor due to https://github.com/indented-automation/Indented.ScriptAnalyzerRules/issues/8.')] |
| 123 | + [OutputType()] |
| 124 | + [CmdletBinding(DefaultParameterSetName = 'ServerObject', SupportsShouldProcess = $true, ConfirmImpact = 'Low')] |
| 125 | + param |
| 126 | + ( |
| 127 | + [Parameter(ParameterSetName = 'ServerObject', Mandatory = $true, ValueFromPipeline = $true)] |
| 128 | + [Microsoft.SqlServer.Management.Smo.Server] |
| 129 | + $ServerObject, |
| 130 | + |
| 131 | + [Parameter(ParameterSetName = 'DatabaseObject', Mandatory = $true, ValueFromPipeline = $true)] |
| 132 | + [Microsoft.SqlServer.Management.Smo.Database] |
| 133 | + $DatabaseObject, |
| 134 | + |
| 135 | + [Parameter(ParameterSetName = 'ServerObject', Mandatory = $true)] |
| 136 | + [ValidateNotNullOrEmpty()] |
| 137 | + [System.String] |
| 138 | + $Name, |
| 139 | + |
| 140 | + [Parameter(Mandatory = $true)] |
| 141 | + [ValidateNotNullOrEmpty()] |
| 142 | + [System.String] |
| 143 | + $BackupFile, |
| 144 | + |
| 145 | + [Parameter()] |
| 146 | + [ValidateSet('Full', 'Differential', 'Log')] |
| 147 | + [System.String] |
| 148 | + $BackupType = 'Full', |
| 149 | + |
| 150 | + [Parameter()] |
| 151 | + [System.Management.Automation.SwitchParameter] |
| 152 | + $CopyOnly, |
| 153 | + |
| 154 | + [Parameter()] |
| 155 | + [System.Management.Automation.SwitchParameter] |
| 156 | + $Compress, |
| 157 | + |
| 158 | + [Parameter()] |
| 159 | + [System.Management.Automation.SwitchParameter] |
| 160 | + $Checksum, |
| 161 | + |
| 162 | + [Parameter()] |
| 163 | + [ValidateNotNullOrEmpty()] |
| 164 | + [System.String] |
| 165 | + $Description, |
| 166 | + |
| 167 | + [Parameter()] |
| 168 | + [ValidateRange(0, 99999)] |
| 169 | + [System.Int32] |
| 170 | + $RetainDays, |
| 171 | + |
| 172 | + [Parameter()] |
| 173 | + [System.Management.Automation.SwitchParameter] |
| 174 | + $Initialize, |
| 175 | + |
| 176 | + [Parameter(ParameterSetName = 'ServerObject')] |
| 177 | + [System.Management.Automation.SwitchParameter] |
| 178 | + $Refresh, |
| 179 | + |
| 180 | + [Parameter()] |
| 181 | + [System.Management.Automation.SwitchParameter] |
| 182 | + $Force |
| 183 | + ) |
| 184 | + |
| 185 | + begin |
| 186 | + { |
| 187 | + if ($Force.IsPresent -and -not $Confirm) |
| 188 | + { |
| 189 | + $ConfirmPreference = 'None' |
| 190 | + } |
| 191 | + } |
| 192 | + |
| 193 | + process |
| 194 | + { |
| 195 | + if ($PSCmdlet.ParameterSetName -eq 'ServerObject') |
| 196 | + { |
| 197 | + if ($Refresh.IsPresent) |
| 198 | + { |
| 199 | + # Refresh the server object's databases collection |
| 200 | + $ServerObject.Databases.Refresh() |
| 201 | + } |
| 202 | + |
| 203 | + # Get the database object |
| 204 | + $DatabaseObject = $ServerObject.Databases[$Name] |
| 205 | + |
| 206 | + if (-not $DatabaseObject) |
| 207 | + { |
| 208 | + $errorMessage = $script:localizedData.Backup_SqlDscDatabase_NotFound -f $Name |
| 209 | + |
| 210 | + $PSCmdlet.ThrowTerminatingError( |
| 211 | + [System.Management.Automation.ErrorRecord]::new( |
| 212 | + [System.Management.Automation.ItemNotFoundException]::new($errorMessage), |
| 213 | + 'BSDD0001', # cspell: disable-line |
| 214 | + [System.Management.Automation.ErrorCategory]::ObjectNotFound, |
| 215 | + $Name |
| 216 | + ) |
| 217 | + ) |
| 218 | + } |
| 219 | + } |
| 220 | + else |
| 221 | + { |
| 222 | + $Name = $DatabaseObject.Name |
| 223 | + $ServerObject = $DatabaseObject.Parent |
| 224 | + } |
| 225 | + |
| 226 | + # Validate that log backups are only performed on databases with FULL or BULK_LOGGED recovery model |
| 227 | + if ($BackupType -eq 'Log') |
| 228 | + { |
| 229 | + $recoveryModel = $DatabaseObject.RecoveryModel |
| 230 | + |
| 231 | + if ($recoveryModel -eq [Microsoft.SqlServer.Management.Smo.RecoveryModel]::Simple) |
| 232 | + { |
| 233 | + $errorMessage = $script:localizedData.Database_Backup_LogBackupSimpleRecoveryModel -f $Name |
| 234 | + |
| 235 | + $PSCmdlet.ThrowTerminatingError( |
| 236 | + [System.Management.Automation.ErrorRecord]::new( |
| 237 | + [System.InvalidOperationException]::new($errorMessage), |
| 238 | + 'BSDD0002', # cspell: disable-line |
| 239 | + [System.Management.Automation.ErrorCategory]::InvalidOperation, |
| 240 | + $DatabaseObject |
| 241 | + ) |
| 242 | + ) |
| 243 | + } |
| 244 | + } |
| 245 | + |
| 246 | + # Validate that the database is online |
| 247 | + if ($DatabaseObject.Status -ne [Microsoft.SqlServer.Management.Smo.DatabaseStatus]::Normal) |
| 248 | + { |
| 249 | + $errorMessage = $script:localizedData.Database_Backup_DatabaseNotOnline -f $Name, $DatabaseObject.Status |
| 250 | + |
| 251 | + $PSCmdlet.ThrowTerminatingError( |
| 252 | + [System.Management.Automation.ErrorRecord]::new( |
| 253 | + [System.InvalidOperationException]::new($errorMessage), |
| 254 | + 'BSDD0003', # cspell: disable-line |
| 255 | + [System.Management.Automation.ErrorCategory]::InvalidOperation, |
| 256 | + $DatabaseObject |
| 257 | + ) |
| 258 | + ) |
| 259 | + } |
| 260 | + |
| 261 | + # Determine the backup type description for messages |
| 262 | + $backupTypeDescription = switch ($BackupType) |
| 263 | + { |
| 264 | + 'Full' { 'full' } |
| 265 | + 'Differential' { 'differential' } |
| 266 | + 'Log' { 'transaction log' } |
| 267 | + } |
| 268 | + |
| 269 | + $descriptionMessage = $script:localizedData.Database_Backup_ShouldProcessVerboseDescription -f $backupTypeDescription, $Name, $BackupFile |
| 270 | + $confirmationMessage = $script:localizedData.Database_Backup_ShouldProcessVerboseWarning -f $backupTypeDescription, $Name |
| 271 | + $captionMessage = $script:localizedData.Database_Backup_ShouldProcessCaption |
| 272 | + |
| 273 | + if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage)) |
| 274 | + { |
| 275 | + Write-Verbose -Message ($script:localizedData.Database_Backup_BackingUp -f $backupTypeDescription, $Name, $BackupFile) |
| 276 | + |
| 277 | + try |
| 278 | + { |
| 279 | + # Create the backup object |
| 280 | + $backup = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Backup' |
| 281 | + |
| 282 | + # Set the database name |
| 283 | + $backup.Database = $Name |
| 284 | + |
| 285 | + # Set the backup action type based on BackupType parameter |
| 286 | + switch ($BackupType) |
| 287 | + { |
| 288 | + 'Full' |
| 289 | + { |
| 290 | + $backup.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database |
| 291 | + $backup.Incremental = $false |
| 292 | + } |
| 293 | + |
| 294 | + 'Differential' |
| 295 | + { |
| 296 | + $backup.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database |
| 297 | + $backup.Incremental = $true |
| 298 | + } |
| 299 | + |
| 300 | + 'Log' |
| 301 | + { |
| 302 | + $backup.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Log |
| 303 | + } |
| 304 | + } |
| 305 | + |
| 306 | + # Create and add the backup device |
| 307 | + $backupDevice = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.BackupDeviceItem' -ArgumentList $BackupFile, 'File' |
| 308 | + $backup.Devices.Add($backupDevice) |
| 309 | + |
| 310 | + # Set optional properties |
| 311 | + if ($CopyOnly.IsPresent) |
| 312 | + { |
| 313 | + $backup.CopyOnly = $true |
| 314 | + } |
| 315 | + |
| 316 | + if ($Compress.IsPresent) |
| 317 | + { |
| 318 | + $backup.CompressionOption = [Microsoft.SqlServer.Management.Smo.BackupCompressionOptions]::On |
| 319 | + } |
| 320 | + |
| 321 | + if ($Checksum.IsPresent) |
| 322 | + { |
| 323 | + $backup.Checksum = $true |
| 324 | + } |
| 325 | + |
| 326 | + if ($PSBoundParameters.ContainsKey('Description')) |
| 327 | + { |
| 328 | + $backup.BackupSetDescription = $Description |
| 329 | + } |
| 330 | + |
| 331 | + if ($PSBoundParameters.ContainsKey('RetainDays')) |
| 332 | + { |
| 333 | + $backup.RetainDays = $RetainDays |
| 334 | + } |
| 335 | + |
| 336 | + if ($Initialize.IsPresent) |
| 337 | + { |
| 338 | + $backup.Initialize = $true |
| 339 | + } |
| 340 | + |
| 341 | + # Perform the backup |
| 342 | + $backup.SqlBackup($ServerObject) |
| 343 | + |
| 344 | + Write-Verbose -Message ($script:localizedData.Database_Backup_Success -f $backupTypeDescription, $Name) |
| 345 | + } |
| 346 | + catch |
| 347 | + { |
| 348 | + $errorMessage = $script:localizedData.Database_Backup_Failed -f $backupTypeDescription, $Name, $ServerObject.InstanceName |
| 349 | + |
| 350 | + $PSCmdlet.ThrowTerminatingError( |
| 351 | + [System.Management.Automation.ErrorRecord]::new( |
| 352 | + [System.InvalidOperationException]::new($errorMessage, $_.Exception), |
| 353 | + 'BSDD0004', # cspell: disable-line |
| 354 | + [System.Management.Automation.ErrorCategory]::InvalidOperation, |
| 355 | + $DatabaseObject |
| 356 | + ) |
| 357 | + ) |
| 358 | + } |
| 359 | + } |
| 360 | + } |
| 361 | +} |
0 commit comments