internal/Test-DbaRestoreVersion.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
function Test-DbaRestoreVersion {
    <#
 .SYNOPSIS
  Checks that the restore files are from a version of SQL Server that can be restored on the target version
 
 .DESCRIPTION
  Finds the anchoring Full backup (or multiple if it's a striped set).
  Then filters to ensure that all the backups are from that anchor point (LastLSN) and that they're all on the same RecoveryForkID
  Then checks that we have either enough Diffs and T-log backups to get to where we want to go. And checks that there is no break between
  LastLSN and FirstLSN in sequential files
 
 .PARAMETER FilteredRestoreFiles
  This is just an object consisting of the output from Read-DbaBackupHeader. Normally this will have been filtered down to a restorable chain
  before arriving here. (ie; only 1 anchoring Full backup)
 
 .PARAMETER SqlInstance
  Sql Server Instance against which the restore is going to be performed
 
 .PARAMETER SqlCredential
  Credential for connecting to SqlInstance
 
 .PARAMETER SystemDatabaseRestore
  Switch when restoring system databases
 
 .NOTES
  Author: Stuart Moore (@napalmgram), stuart-moore.com
  Tags:
  dbatools PowerShell module (https://dbatools.io, clemaire@gmail.com)
  Copyright (C) 2016 Chrissy LeMaire
  License: GNU GPL v3 https://opensource.org/licenses/GPL-3.0
 
 .EXAMPLE
  Test-DbaRestoreVersion -FilteredRestoreFiles $FilteredFiles -SqlInstance server1\instance1
 
  Checks that the Restore chain in $FilteredFiles is compatible with the SQL Server version of server1\instance1
 
#>

    [CmdletBinding()]
    param (
        [parameter(Mandatory = $true)]
        [Alias("ServerInstance", "SqlServer")]
        [object]$SqlInstance,
        [parameter(Mandatory = $true)]
        [object[]]$FilteredRestoreFiles,
        [PSCredential]$SqlCredential,
        [switch]$SystemDatabaseRestore
    )
    $RestoreVersion = ($FilteredRestoreFiles.SoftwareVersionMajor | Measure-Object -average).average
    Write-Message -Level Verbose -Message "RestoreVersion is $RestoreVersion"
    #Test to make sure we don't have an upgrade mid backup chain, there's a reason I'm paranoid..
    if ([int]$RestoreVersion -ne $RestoreVersion) {
        Write-Message -Level Warning -Message "Version number change during backups - $RestoreVersion"
        return $false
        break
    }
    #Can't restore backwards
    try {
        if ($SqlInstance -isnot [Microsoft.SqlServer.Management.Smo.SqlSmoObject]) {
            $Newconnection = $true
            $Server = Connect-SqlInstance -SqlInstance $SqlInstance -SqlCredential $SqlCredential
        }
        else {
            $server = $SqlInstance
        }
    }
    catch {
        Write-Message -Level Warning -Message "Cannot connect to $SqlInstance"
        break
    }

    if ($SystemDatabaseRestore) {
        if ($RestoreVersion -ne $Server.VersionMajor) {
            Write-Message -Level Warning -Message "For System Database restore versions must match)"
            return $false
            break
        }
    }
    else {
        if ($RestoreVersion -gt $Server.VersionMajor) {
            Write-Message -Level Warning -Message "Backups are from a newer version of SQL Server than $($Server.Name)"
            return $false
            break
        }

        if (($Server.VersionMajor -gt 10 -and $RestoreVersion -lt 9)  ) {
            Write-Message -Level Warning -Message "This version - $RestoreVersion - too old to restore on to $($Server.Name)"
            return $false
            break
        }
    }
    if ($Newconnection) {
        $server.ConnectionContext.Disconnect()
    }
    return $True
}