public/cbb/New-MBSRestorePlan.ps1
function New-MBSRestorePlan { <# .SYNOPSIS Creates new restore plan. .DESCRIPTION Creates File-Level, Image-Based, Hyper-V, or MS SQL restore plan. .PARAMETER Name Restore plan name .PARAMETER StorageAccount Specify storage account object. Use Get-MBSStorageAccount cmdlet to list storages. Example: (Get-MBSStorageAccount -Name "AWS S3") .PARAMETER MasterPassword Master password. Should be specified if configuration is protected by master password. Use -MasterPassword (ConvertTo-SecureString -string "Your_Password" -AsPlainText -Force) .PARAMETER Schedule Specify schedule. Use New-MBSPlanSchedule to create an object .PARAMETER RestorePlanCommonOption Specify plan common options. Use New-MBSBackupPlanCommonOption to create an object .PARAMETER BackupPrefix Backup prefix .PARAMETER RestorePath Restore to specific location. Omit for restore to the original location. .PARAMETER RunOnce Run plan once (do not save) .PARAMETER Overwrite Overwrite existing files/database .PARAMETER RestoreFromGlacier Restore files located in Glacier (expedited or standard or bulk) .PARAMETER RestorePoint Restore type. Specify DateTime value or omit to restore the latest version. .PARAMETER File Restore file .PARAMETER Folder Restore folder .PARAMETER RestoreDeletedFiles Restore deleted files .PARAMETER RestoreNewFile Restore only new files. Existing files will be overwritten only if modification date of backed up file is newer than existing .PARAMETER RestoreNTFSPermissions Restore NTFS permissions .PARAMETER HVHost Hyper-V host .PARAMETER VM Hyper-V VM name .PARAMETER NewVM New Hyper-V machine name .PARAMETER ImportVM Import virtual machine .PARAMETER Disk Backed up disk ID .PARAMETER Volume Restore volume by id .PARAMETER DestinationDisk Restore to phisical disk specified by Id .PARAMETER DestinationVolume Restore to volume specified by id .PARAMETER VirtualDiskType Restore to virtual disk .PARAMETER VirtualDiskName Set target virtual disk name .PARAMETER VirtualDiskFolder Set target virtual disk destination folder .PARAMETER VirtualDiskCapacity Set target virtual disk capacity (integer value with size specifier in KB, MB, GB, TB. It can be used for extend of the original disk capacity only. Shrinking volumes will not be performed if the value set is smaller than the original disk size. .PARAMETER InstanceName Destination instance name .PARAMETER useSSL Use secure connection (SSL/TLS) .PARAMETER useWinauth Use Windows authentication .PARAMETER UserName MS SQL server user name .PARAMETER Password MS SQL server password .PARAMETER DataFileFolder Data file folder .PARAMETER LogFileFolder Log file folder .PARAMETER FileNameTemplate File name template. Possible values: You can use a %DATABASENAME% variable to automatically generate a file name as a 'restore as' database name .PARAMETER CloseExistingConnection Close existing connections to destination database .PARAMETER CheckPermissions Check if the specified account has necessary permissions to perform restore .PARAMETER SourceInstanceName Source instance name .PARAMETER Database Source database name .PARAMETER NewDatabase New database name .EXAMPLE PS:\> New-MBSRestorePlan -Name "Restore Image as VHD" -StorageAccount (Get-MBSStorageAccount | where {$_.DisplayName -eq "AWS S3"}) -RestorePlanCommonOption (New-MBSRestoreCommonOptions) -Disk "00000000-0000-0000-0000-000000000002" -VirtualDiskType VHDdynamic -VirtualDiskName "MyDisk" -VirtualDiskFolder "E:\Restore" Restore Image-Based backup as VHD dynamic file. .EXAMPLE PS> New-MBSRestorePlan -Name "Restore file" -StorageAccount (Get-MBSStorageAccount | where {$_.DisplayName -like "*AWS S3*"}) -RestorePlanCommonOption (New-MBSRestoreCommonOptions) -File C:\temp\test.txt -Folder "C:\myFolder","c:\Users" -RestorePath "E:\Restore" Restore C:\temp\test.txt and C:\myFolder,c:\Users folders to E:\Restore .EXAMPLE PS> New-MBSRestorePlan -Name "Restore disk" -StorageAccount (Get-MBSStorageAccount | where {$_.DisplayName -eq "AWS S3"}) -RestorePlanCommonOption (New-MBSRestoreCommonOptions) -Disk "00000000-0000-0000-0000-000000000002" -DestinationDisk "00000000-0000-0000-0000-000000000001" | Start-MBSBackupPlan Create plan to restore disk with ID "00000000-0000-0000-0000-000000000002" to disk with ID "00000000-0000-0000-0000-000000000001" and start it. .EXAMPLE PS> New-MBSRestorePlan -Name "Restore Hyper-V VM" -StorageAccount (Get-MBSStorageAccount | where {$_.DisplayName -eq "AWS S3"}) -RestorePlanCommonOption (New-MBSRestoreCommonOptions) -Host "MyHost" -VM "Server" -NewVM "RestoredServer" -ImportVM $true | Start-MBSBackupPlan Create plan to restore Hyper-V VM with name Server as new VM with name RestoredServer and import to Hyper-V. .INPUTS None. .OUTPUTS System.Management.Automation.PSCustomObject String .NOTES Author: Alex Volkov .LINK https://kb.msp360.com/managed-backup-service/powershell-module/cmdlets/backup-agent/new-mbsrestoreplan/ #> [CmdletBinding()] param ( # [Parameter(Mandatory=$true, HelpMessage="Restore plan name.")] [string] $Name, # [Parameter(Mandatory=$true, HelpMessage="Specify storage account object. Use Get-MBSStorageAccount cmdlet to list storages. Example: (Get-MBSStorageAccount -Name ""AWS S3"")")] [MBS.Agent.StorageAccount] $StorageAccount, # [Parameter(Mandatory=$False, HelpMessage="Master password. Should be specified if configuration is protected by master password. Use -MasterPassword (ConvertTo-SecureString -string ""Your_Password"" -AsPlainText -Force)")] [SecureString] $MasterPassword, # [Parameter(Mandatory=$False, HelpMessage="Specify schedule. Use New-MBSPlanSchedule to create an object.")] [MBS.Agent.Plan.Schedule] $Schedule, # [Parameter(Mandatory=$true, HelpMessage="Specify plan common options. Use New-MBSBackupPlanCommonOption to create an object.")] [MBS.Agent.Plan.RestorePlanCommonOption] $RestorePlanCommonOption, # [Parameter(Mandatory=$False, HelpMessage="Backup prefix")] [string] $BackupPrefix, # [Parameter(Mandatory=$False, HelpMessage="Restore to specific location. Omit for restore to the original location.", ParameterSetName='FileLevel')] [Parameter(Mandatory=$False, HelpMessage="Restore to specific location. Omit for restore to the original location.", ParameterSetName='HyperV')] [string] $RestorePath, # [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='FileLevel')] [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='HyperV')] [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='ImageBasedDisk')] [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='ImageBasedVolume')] [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='ImageBasedVHD')] [Parameter(Mandatory=$False, HelpMessage="Run plan once (do not save)", ParameterSetName='MSSQL')] [bool] $RunOnce = $true, # [Parameter(Mandatory=$False, HelpMessage="Overwrite existing files/database", ParameterSetName='FileLevel')] [Parameter(Mandatory=$False, HelpMessage="Overwrite existing files/database", ParameterSetName='HyperV')] [Parameter(Mandatory=$False, HelpMessage="Overwrite existing files/database", ParameterSetName='MSSQL')] [switch] $Overwrite, # [Parameter(Mandatory=$false, HelpMessage="Restore files located in Glacier (expedited or standard or bulk)", ParameterSetName='FileLevel')] [Parameter(Mandatory=$false, HelpMessage="Restore files located in Glacier (expedited or standard or bulk)", ParameterSetName='HyperV')] [MBS.Agent.Plan.GlacierRestoreType] $RestoreFromGlacier, # [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='FileLevel')] [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='ImageBasedDisk')] [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='ImageBasedVolume')] [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='ImageBasedVHD')] [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='HyperV')] [Parameter(Mandatory=$false, HelpMessage="Restore type. Specify DateTime value or omit to restore the latest version.", ParameterSetName='MSSQL')] [datetime] $RestorePoint, #-------------------- File-Level --------------- [Parameter(Mandatory=$false, HelpMessage="Restore file", ParameterSetName='FileLevel')] [string[]] $File, # [Parameter(Mandatory=$false, HelpMessage="Restore folder", ParameterSetName='FileLevel')] [string[]] $Folder, # [Parameter(Mandatory=$false, HelpMessage="Restore deleted files", ParameterSetName='FileLevel')] [switch] $RestoreDeletedFiles, # [Parameter(Mandatory=$false, HelpMessage="Restore only new files. Existing files will be overwritten only if modification date of backed up file is newer than existing", ParameterSetName='FileLevel')] [switch] $RestoreNewFile, # [Parameter(Mandatory=$false, HelpMessage="Restore NTFS permissions", ParameterSetName='FileLevel')] [switch] $RestoreNTFSPermissions, #-------------------- Hyper-V --------------- [Parameter(Mandatory=$true, HelpMessage="Hyper-V host", ParameterSetName='HyperV')] [string] $HVHost, # [Parameter(Mandatory=$true, HelpMessage="Hyper-V VM name", ParameterSetName='HyperV')] [string] $VM, # [Parameter(Mandatory=$true, HelpMessage="New Hyper-V machine name", ParameterSetName='HyperV')] [string] $NewVM, # [Parameter(Mandatory=$true, HelpMessage="Import virtual machine after restore", ParameterSetName='HyperV')] [bool] $ImportVM=$true, #-------------------- Image-Based --------------- [Parameter(Mandatory=$true, HelpMessage="Backed up disk ID", ParameterSetName='ImageBasedDisk')] [Parameter(Mandatory=$False, HelpMessage="Backed up disk ID", ParameterSetName='ImageBasedVolume')] [Parameter(Mandatory=$False, HelpMessage="Backed up disk ID", ParameterSetName='ImageBasedVHD')] [string] $Disk, # [Parameter(Mandatory=$true, HelpMessage="Restore volume by id", ParameterSetName='ImageBasedVolume')] [Parameter(Mandatory=$False, HelpMessage="Restore volume by id", ParameterSetName='ImageBasedVHD')] [string] $Volume, # [Parameter(Mandatory=$true, HelpMessage="Restore to phisical disk specified by Id", ParameterSetName='ImageBasedDisk')] [Parameter(Mandatory=$False, HelpMessage="Restore to phisical disk specified by Id", ParameterSetName='ImageBasedVolume')] [string] $DestinationDisk, # [Parameter(Mandatory=$true, HelpMessage="Restore to volume specified by id.", ParameterSetName='ImageBasedVolume')] [string] $DestinationVolume, # [Parameter(Mandatory=$true, HelpMessage="Restore to virtual disk", ParameterSetName='ImageBasedVHD')] [MBS.Agent.Plan.VirtualDiskType] $VirtualDiskType, # [Parameter(Mandatory=$False, HelpMessage="Set target virtual disk name", ParameterSetName='ImageBasedVHD')] [string] $VirtualDiskName, # [Parameter(Mandatory=$False, HelpMessage="Set target virtual disk destination folder", ParameterSetName='ImageBasedVHD')] [string] $VirtualDiskFolder, # [Parameter(Mandatory=$False, HelpMessage="Set target virtual disk capacity (integer value with size specifier in KB, MB, GB, TB. It can be used for extend of the original disk capacity only. Shrinking volumes will not be performed if the value set is smaller than the original disk size.", ParameterSetName='ImageBasedVHD')] [ValidatePattern("^\d+(\s|)(KB|MB|GB|TB)$")] [string] $VirtualDiskCapacity, #-------------------- MS SQL --------------- [Parameter(Mandatory=$true, HelpMessage="Destination instance name", ParameterSetName='MSSQL')] [string] $InstanceName, # [Parameter(Mandatory=$false, HelpMessage="Use secure connection (SSL/TLS)", ParameterSetName='ImageBased')] [bool] $useSSL, # [Parameter(Mandatory=$False, HelpMessage='Use Windows authentication.', ParameterSetName='MSSQL')] [Switch] $useWinauth, # [Parameter(Mandatory=$False, HelpMessage="MS SQL server user name", ParameterSetName='MSSQL')] [string] $UserName, # [Parameter(Mandatory=$False, HelpMessage="MS SQL server password", ParameterSetName='MSSQL')] [Securestring] $Password, # [Parameter(Mandatory=$False, HelpMessage="Data file folder", ParameterSetName='MSSQL')] [string] $DataFileFolder, # [Parameter(Mandatory=$False, HelpMessage="Log file folder", ParameterSetName='MSSQL')] [string] $LogFileFolder, # [Parameter(Mandatory=$False, HelpMessage="File name template. Possible values: You can use a %DATABASENAME% variable to automatically generate a file name as a 'restore as' database name", ParameterSetName='MSSQL')] [string] $FileNameTemplate, # [Parameter(Mandatory=$False, HelpMessage="Close existing connections to destination database.", ParameterSetName='MSSQL')] [switch] $CloseExistingConnection, # [Parameter(Mandatory=$False, HelpMessage="Check if the specified account has necessary permissions to perform restore.", ParameterSetName='MSSQL')] [bool] $CheckPermissions = $true, # [Parameter(Mandatory=$False, HelpMessage="Source instance name", ParameterSetName='MSSQL')] [string] $SourceInstanceName, # [Parameter(Mandatory=$False, HelpMessage="Source database name", ParameterSetName='MSSQL')] [string] $Database, # [Parameter(Mandatory=$False, HelpMessage="New database name", ParameterSetName='MSSQL')] [string] $NewDatabase ) begin { if (-not($CBB = Get-MBSAgent)) { Break } try { if ((Get-MBSAgentSetting -ErrorAction SilentlyContinue).MasterPassword -ne "" -and $null -ne (Get-MBSAgentSetting -ErrorAction SilentlyContinue).MasterPassword -and -not $MasterPassword) { $MasterPassword = Read-Host Master Password -AsSecureString } } catch { } } process { function Set-Schedule { param ( [Parameter()] [psobject] $Schedule, [Parameter()] [string] $Prefix = '' ) switch ($Schedule.Frequency) { Daily {$ScheduleCli += " -every$prefix day"} Weekly {$ScheduleCli += " -every$prefix week"} Monthly {$ScheduleCli += " -every$prefix month"} dayofmonth {$ScheduleCli += " -every$prefix dayofmonth"} Realtime {$ScheduleCli += " -every$prefix real-time"} Default { Write-Host "Schedule frequency is not specified." Break } } if ($Schedule.At){$ScheduleCli += " -at$prefix ""$($Schedule.At.ToString())"""} if ($Schedule.DayOfMonth){$ScheduleCli += " -day$prefix $($Schedule.DayOfMonth)"} if ($Schedule.DayOfWeek){$ScheduleCli += " -weekday$prefix "+(($Schedule.DayOfWeek | foreach-object -Begin {$weekdaylocal = @()} -Process{$weekdaylocal += $_.ToString().Substring(0,2)} -End {return $weekdaylocal.ToLower()}) -join ",")} if ($Schedule.Weeknumber){$ScheduleCli += " -weeknumber$prefix $($Schedule.Weeknumber)"} if ($Schedule.OccursFrom){$ScheduleCli += " -dailyFrom$prefix $($Schedule.OccursFrom.ToString('hh\:mm'))"} if ($Schedule.OccursTo){$ScheduleCli += " -dailyTill$prefix $($Schedule.OccursTo.ToString('hh\:mm'))"} if ($Schedule.OccursEvery.TotalMinutes -ne 0){ if ($Schedule.OccursEvery.TotalHours -gt 180){ $ScheduleCli += " -occurs$prefix hour -occurValue$prefix 180" }elseif($Schedule.OccursEvery.TotalHours -lt 180 -and $Schedule.OccursEvery.TotalHours -ge 1){ $ScheduleCli += " -occurs$prefix hour -occurValue$prefix $([Math]::Round($Schedule.OccursEvery.TotalHours))" }elseif($Schedule.OccursEvery.TotalHours -lt 1 -and $Schedule.OccursEvery.TotalMinutes -ge 1){ $ScheduleCli += " -occurs$prefix min -occurValue$prefix $([Math]::Round($Schedule.OccursEvery.TotalMinutes))" }else{ Write-host "Schedule 'OccursEvery' parameter cannot be less then 1 minute." } } if ($Schedule.RepeatInterval){$ScheduleCli += " -repeatEvery$prefix $($Schedule.RepeatInterval)"} if ($Schedule.RepeatStartDate){$ScheduleCli += " -repeatStartDate$prefix ""$($Schedule.RepeatStartDate.ToString())"""} return $Schedulecli } switch -Wildcard ($PSCmdlet.ParameterSetName){ 'FileLevel' {$Argument += " addRestorePlan"} 'ImageBased*' {$Argument += " addRestoreIBBPlan"} 'HyperV' {$Argument += " addRestoreHVPlan"} 'MSSQL' {$Argument += " addRestoreMSSQLPlan"} Default {} } if ($Name){$Argument += " -n ""$Name"""} $Argument += " -aid ""$($StorageAccount.ID)""" if($Schedule){$Argument += Set-Schedule -Schedule $Schedule} if($RestorePlanCommonOption.SyncRepositoryBeforeRun){$Argument += " -sync yes"}#else{$Argument += " -sync no"} if($RestorePlanCommonOption.EncryptionPassword){$Argument += " -ep """+([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($RestorePlanCommonOption.EncryptionPassword)))+""""} if($RestorePlanCommonOption.StopIfPlanRunsFor.TotalMinutes -gt 0){$Argument += " -stopAfter $( [math]::Round($RestorePlanCommonOption.StopIfPlanRunsFor.TotalHours)):$($RestorePlanCommonOption.StopIfPlanRunsFor.Minutes)"} if($PSCmdlet.ParameterSetName -ne "MSSQL"){ if($RestorePlanCommonOption.PreActionCommand){$Argument += " -preAction $($RestorePlanCommonOption.PreActionCommand)"} if($RestorePlanCommonOption.PreActionContinueAnyway){$Argument += " -pac yes"}else{$Argument += " -pac no"} if($RestorePlanCommonOption.PostActionCommand){$Argument += " -postAction $($RestorePlanCommonOption.PostActionCommand)"} if($RestorePlanCommonOption.PostActionRunAnyway){$Argument += " -paa yes"}else{$Argument += " -paa no"} if($RestorePlanCommonOption.ResultEmailNotification){$Argument += " -notification $($RestorePlanCommonOption.ResultEmailNotification)"} if($RestorePlanCommonOption.AddEventToWindowsLog){$Argument += " -winLog $($RestorePlanCommonOption.AddEventToWindowsLog)"} } if($BackupPrefix){$Argument += " -bp $BackupPrefix"} if($RunOnce){$Argument += " -runOnce yes"}else{$Argument += " -runOnce no"} if($RestoreFromGlacier){$Argument += " -glacier $RestoreFromGlacier"} if($RestorePoint){$Argument += " -rt ""$RestorePoint"""} switch -Wildcard ($PSCmdlet.ParameterSetName){ 'FileLevel' { # --------- File-Level ------------ if ($RestorePath) {$Argument += " -rlocation ""$RestorePath"""} if ($Overwrite){$Argument += " -o"} if ($File){$Argument += " -f "+'"{0}"' -f ($File -join '" -f "')} if ($Folder){$Argument += " -d "+'"{0}"' -f ($Folder -join '" -d "')} if ($RestoreDeletedFiles){$Argument += " -deleted"} if ($RestoreNewFile){$Argument += " -rn"} if ($RestoreNTFSPermissions){$Argument += " -ntfs yes"}else{$Argument += " -ntfs no"} } 'ImageBased*' { # ------------- Image-Based ------------- if ($Disk) {$Argument += " -did ""$Disk"""} if ($Volume) {$Argument += " -v ""$Volume"""} if ($DestinationDisk) {$Argument += " -pd ""$DestinationDisk"""} if ($DestinationVolume) {$Argument += " -pv ""$DestinationVolume"""} if ($null -ne $VirtualDiskType) { $VirtualDiskTypeHash = @{ VHDdynamic = "Hyper-V Virtual Disk (VHD-format) dynamic" VHDfixed = "Hyper-V Virtual Disk (VHD-format) fixed" VHDXdynamic = "Hyper-V Virtual Disk (VHDX-format) dynamic" Raw = "RAW disk image raw" Rawsparse = "RAW disk image rawsparse" Tar = "RAW disk image tar" Tgz = "RAW disk image tgz" VDIdynamic = "VirtualBox Virtual Disk dynamic" VDIfixed = "VirtualBox Virtual Disk fixed" VMDKdynamic = "VMware Virtual Disk vmfsdynamic" VMDKfixed = "VMware Virtual Disk vmfsfixed" } $Argument += " -vdt ""$($VirtualDiskTypeHash["$VirtualDiskType"])""" } if ($VirtualDiskName) {$Argument += " -vdn ""$VirtualDiskName"""} if ($VirtualDiskFolder) {$Argument += " -vdf ""$VirtualDiskFolder"""} if ($VirtualDiskCapacity) {$Argument += " -vdc ""$VirtualDiskCapacity"""} } 'HyperV' { # ------------- Hyper-V ------------- if ($HVHost) {$Argument += " -host ""$HVHost"""} if ($VM) {$Argument += " -machine ""$VM"""} if ($NewVM) {$Argument += " -newMachine ""$NewVM"""} if ($ImportVM){$Argument += " -ImportVM yes"}else{$Argument += " -ImportVM no"} } 'MSSQL' { # ------------- MS SQL ------------- if ($InstanceName){$Argument += " -instancename $InstanceName"} if ($useSSL){$Argument += " -secure"} if ($useWinauth){$Argument += " -winauth yes"} if ($UserName){$Argument += " -username $UserName"} if ($Password){$Argument += " -password """+([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)))+""""} if ($DataFileFolder){$Argument += " -dp $DataFileFolder"} if ($LogFileFolder){$Argument += " -lp $LogFileFolder"} if ($FileNameTemplate){$Argument += " -fm $FileNameTemplate"} if ($Overwrite){$Argument += " -ov yes"}else{$Argument += " -ov no"} if ($CloseExistingConnection){$Argument += " -cc yes"}else{$Argument += " -cc no"} if ($CheckPermissions){$Argument += " -cr yes"}else{$Argument += " -cr no"} if ($SourceInstanceName){$Argument += " -dbin $SourceInstanceName"} if ($Database){$Argument += " -dbn $Database"} if ($NewDatabase){$Argument += " -dbnn $NewDatabase"} } } switch ($PSCmdlet.ParameterSetName){ {$_ -in "ImageBasedDisk","ImageBasedVolume","ImageBasedVHD","HyperV"} { $result = Start-MBSProcess -cmdpath $CBB.CBBCLIPath -cmdarguments $Argument -output json -MasterPassword $MasterPassword if ($result.Result -eq "Success") { Get-MBSRestorePlan | Where-Object{$_.ID -eq $result.Id} } } {$_ -in "FileLevel","MSSQL"} { (Start-MBSProcess -cmdpath $CBB.CBBCLIPath -cmdarguments $Argument -output short -MasterPassword $MasterPassword).result } Default {} } } end { } } # SIG # Begin signature block # MIIbfAYJKoZIhvcNAQcCoIIbbTCCG2kCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAXrVtZaptMg1SJ # Fl1+uffDSa8HzxfxAPkYdvVNE5RdKaCCC04wggVmMIIETqADAgECAhEA3VtfmfWb # K32tKkM2xJo7CjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJHQjEbMBkGA1UE # CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQK # ExFDT01PRE8gQ0EgTGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNp # Z25pbmcgQ0EwHhcNMTcxMjE0MDAwMDAwWhcNMjExMjE0MjM1OTU5WjCBqDELMAkG # A1UEBhMCQ1kxDTALBgNVBBEMBDEwOTUxETAPBgNVBAgMCExlZmNvc2lhMRAwDgYD # VQQHDAdOaWNvc2lhMRUwEwYDVQQJDAxMYW1wb3VzYXMsIDExJjAkBgNVBAoMHVRy # aWNoaWxpYSBDb25zdWx0YW50cyBMaW1pdGVkMSYwJAYDVQQDDB1UcmljaGlsaWEg # Q29uc3VsdGFudHMgTGltaXRlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC # ggEBAJC5Ak9MZHfMGygnL9B+2OcFRvnTeYAJPa4tJS/ES3eSBBge9BiBUa6f+QlX # lIjt+NBD9QrewScUj9EnaguKzc8NFonBJAgT43jD5rCuuj3GljTIHftLDF9vgetf # 7KUYhwMypqxRP8pLMAuXzIzw5Yxjh1Quy92dZyJYpOuGbz1PQVRMj2fhRqeerP4J # OiRktwnykjrxDsRNm+Iuas1BM+vjVA7B9Cj0Wf5NsMxSegJezvs0yqwHrsngEQrY # GXDKHstfsxd8KM5LxJdYN1neIAO8v6AuM6yjQT1z1ZwVSCHu2swNCA3T3M26fkk9 # 9TIZZI/LvfR++FJCUvJkPoPbOKUCAwEAAaOCAbMwggGvMB8GA1UdIwQYMBaAFCmR # YP+KTfrr+aZquM/55ku9Sc4SMB0GA1UdDgQWBBRqlxdnVxjIxF6fnOYUd7LOYeNe # rjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEF # BQcDAzARBglghkgBhvhCAQEEBAMCBBAwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIB # AwIwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLm5ldC9DUFMw # QwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RP # UlNBQ29kZVNpZ25pbmdDQS5jcmwwdAYIKwYBBQUHAQEEaDBmMD4GCCsGAQUFBzAC # hjJodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDb2RlU2lnbmluZ0NB # LmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMCQGA1Ud # EQQdMBuBGWNvbnRhY3RAY2xvdWRiZXJyeWxhYi5jb20wDQYJKoZIhvcNAQELBQAD # ggEBAEeInauUdqKYV4ncwGMqz5+frptASCXVnCMLI7j3JK0KCzmJkwHHmkIk3P0A # Rzedj5+1aFuXANtT42IACVf00tqq0IHO2KT2vHHJHNnx3ht6kMcCmKmUlnkZMjEK # +0WJD0JSP7lBRQBf5QJpDLmpbBTVvlbe/3nzpUZ95O5reaPekoQ1xC4Ossu06ba0 # djKhwk0HgeqZz7ZruWOVY/YRDfnlZ3it5+4Ck2JTXIVcUcXzT/ZdwNTkUiIqmh4T # HwOj+k/Yej7Q13ILWTNZMELs3Iec6FSSGXUijHV65pPI0dUXnq8pWYMfutgwlBaL # 78yXl4ihf46TXsnAMottH+ld8lAwggXgMIIDyKADAgECAhAufIfMDpNKUv6U/Ry3 # zTSvMA0GCSqGSIb3DQEBDAUAMIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl # YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P # RE8gQ0EgTGltaXRlZDErMCkGA1UEAxMiQ09NT0RPIFJTQSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eTAeFw0xMzA1MDkwMDAwMDBaFw0yODA1MDgyMzU5NTlaMH0xCzAJ # BgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT # B1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSMwIQYDVQQDExpD # T01PRE8gUlNBIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP # ADCCAQoCggEBAKaYkGN3kTR/itHd6WcxEevMHv0xHbO5Ylc/k7xb458eJDIRJ2u8 # UZGnz56eJbNfgagYDx0eIDAO+2F7hgmz4/2iaJ0cLJ2/cuPkdaDlNSOOyYruGgxk # x9hCoXu1UgNLOrCOI0tLY+AilDd71XmQChQYUSzm/sES8Bw/YWEKjKLc9sMwqs0o # GHVIwXlaCM27jFWM99R2kDozRlBzmFz0hUprD4DdXta9/akvwCX1+XjXjV8QwkRV # PJA8MUbLcK4HqQrjr8EBb5AaI+JfONvGCF1Hs4NB8C4ANxS5Eqp5klLNhw972GIp # pH4wvRu1jHK0SPLj6CH5XkxieYsCBp9/1QsCAwEAAaOCAVEwggFNMB8GA1UdIwQY # MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBQpkWD/ik366/mmarjP # +eZLvUnOEjAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV # HSUEDDAKBggrBgEFBQcDAzARBgNVHSAECjAIMAYGBFUdIAAwTAYDVR0fBEUwQzBB # oD+gPYY7aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2VydGlmaWNh # dGlvbkF1dGhvcml0eS5jcmwwcQYIKwYBBQUHAQEEZTBjMDsGCCsGAQUFBzAChi9o # dHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FBZGRUcnVzdENBLmNydDAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEB # DAUAA4ICAQACPwI5w+74yjuJ3gxtTbHxTpJPr8I4LATMxWMRqwljr6ui1wI/zG8Z # wz3WGgiU/yXYqYinKxAa4JuxByIaURw61OHpCb/mJHSvHnsWMW4j71RRLVIC4nUI # BUzxt1HhUQDGh/Zs7hBEdldq8d9YayGqSdR8N069/7Z1VEAYNldnEc1PAuT+89r8 # dRfb7Lf3ZQkjSR9DV4PqfiB3YchN8rtlTaj3hUUHr3ppJ2WQKUCL33s6UTmMqB9w # ea1tQiCizwxsA4xMzXMHlOdajjoEuqKhfB/LYzoVp9QVG6dSRzKp9L9kR9GqH1NO # MjBzwm+3eIKdXP9Gu2siHYgL+BuqNKb8jPXdf2WMjDFXMdA27Eehz8uLqO8cGFjF # BnfKS5tRr0wISnqP4qNS4o6OzCbkstjlOMKo7caBnDVrqVhhSgqXtEtCtlWdvpnn # cG1Z+G0qDH8ZYF8MmohsMKxSCZAWG/8rndvQIMqJ6ih+Mo4Z33tIMx7XZfiuyfiD # FJN2fWTQjs6+NX3/cjFNn569HmwvqI8MBlD7jCezdsn05tfDNOKMhyGGYf6/VXTh # IXcDCmhsu+TJqebPWSXrfOxFDnlmaOgizbjvmIVNlhE8CYrQf7woKBP7aspUjZJc # zcJlmAaezkhb1LU3k0ZBfAfdz/pD77pnYf99SeC7MH1cgOPmFjlLpzGCD4Qwgg+A # AgEBMIGSMH0xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0 # ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVk # MSMwIQYDVQQDExpDT01PRE8gUlNBIENvZGUgU2lnbmluZyBDQQIRAN1bX5n1myt9 # rSpDNsSaOwowDQYJYIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkq # hkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGC # NwIBFTAvBgkqhkiG9w0BCQQxIgQgNMvAQEMwjyWtEcvYXc7dwb/uyUTHp2/Ovk8U # zVSLkj8wDQYJKoZIhvcNAQEBBQAEggEAVR40a72nF7+VQ8T3Som5gTIHoINH3Dr/ # rn0rtPx5gJJBBPTG/0leDhWFT+iuzQYVu5ftu4r9IiqTN2zl6JT1RbnumhtG0MQQ # XLlLNicBpFfMClt9UJnZ/q+KmlY2nFeh280G2wd5t1rjSefuJ633IRvdR48FKLgq # 6ObLPw8i2zdQ26vBC5T0hK+/R4u49je7Fet839S3Aj8KWtdn0JSm+ek4KDkoFIv9 # rYYnv50UmWIWNV8RRhmkbyirSFNBidrj65LeT+HZ7ylmYGew59uFnC/yst5ay/lw # Wg4urm9vkTpgoBlJiPraRfTYXSavtwdVbXUvMHbaRqnQ8y4zjhzAy6GCDUQwgg1A # BgorBgEEAYI3AwMBMYINMDCCDSwGCSqGSIb3DQEHAqCCDR0wgg0ZAgEDMQ8wDQYJ # YIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAx # MA0GCWCGSAFlAwQCAQUABCDugL23jA6nWNtfV3QjKbdzJnoZX1Ewmlxu+2Ks/vQE # XQIQDYy4u4uVF/lIsZDCvd/5/BgPMjAyMTAzMDIxMDMyMTlaoIIKNzCCBP4wggPm # oAMCAQICEA1CSuC+Ooj/YEAhzhQA8N0wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVz # dGFtcGluZyBDQTAeFw0yMTAxMDEwMDAwMDBaFw0zMTAxMDYwMDAwMDBaMEgxCzAJ # BgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UEAxMXRGln # aUNlcnQgVGltZXN0YW1wIDIwMjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK # AoIBAQDC5mGEZ8WK9Q0IpEXKY2tR1zoRQr0KdXVNlLQMULUmEP4dyG+RawyW5xpc # SO9E5b+bYc0VkWJauP9nC5xj/TZqgfop+N0rcIXeAhjzeG28ffnHbQk9vmp2h+mK # vfiEXR52yeTGdnY6U9HR01o2j8aj4S8bOrdh1nPsTm0zinxdRS1LsVDmQTo3Vobc # kyON91Al6GTm3dOPL1e1hyDrDo4s1SPa9E14RuMDgzEpSlwMMYpKjIjF9zBa+RSv # FV9sQ0kJ/SYjU/aNY+gaq1uxHTDCm2mCtNv8VlS8H6GHq756WwogL0sJyZWnjbL6 # 1mOLTqVyHO6fegFz+BnW/g1JhL0BAgMBAAGjggG4MIIBtDAOBgNVHQ8BAf8EBAMC # B4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBBBgNVHSAE # OjA4MDYGCWCGSAGG/WwHATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2lj # ZXJ0LmNvbS9DUFMwHwYDVR0jBBgwFoAU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHQYD # VR0OBBYEFDZEho6kurBmvrwoLR1ENt3janq8MHEGA1UdHwRqMGgwMqAwoC6GLGh0 # dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMuY3JsMDKgMKAu # hixodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDCB # hQYIKwYBBQUHAQEEeTB3MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy # dC5jb20wTwYIKwYBBQUHMAKGQ2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydFNIQTJBc3N1cmVkSURUaW1lc3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcN # AQELBQADggEBAEgc3LXpmiO85xrnIA6OZ0b9QnJRdAojR6OrktIlxHBZvhSg5SeB # pU0UFRkHefDRBMOG2Tu9/kQCZk3taaQP9rhwz2Lo9VFKeHk2eie38+dSn5On7UOe # e+e03UEiifuHokYDTvz0/rdkd2NfI1Jpg4L6GlPtkMyNoRdzDfTzZTlwS/Oc1np7 # 2gy8PTLQG8v1Yfx1CAB2vIEO+MDhXM/EEXLnG2RJ2CKadRVC9S0yOIHa9GCiurRS # +1zgYSQlT7LfySmoc0NR2r1j1h9bm/cuG08THfdKDXF+l7f0P4TrweOjSaH6zqe/ # Vs+6WXZhiV9+p7SOZ3j5NpjhyyjaW4emii8wggUxMIIEGaADAgECAhAKoSXW1jIb # fkHkBdo2l8IVMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBa # Fw0zMTAxMDcxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD # ZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQ # fdD5fU1ofue2oPSNs4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9l # P+Cb6+NGRwYaVX4LJ37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3I # mgtU46gJcWvgzyIQD3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDq # R9mIUF79Zm5WYScpiYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZ # chfxFwbvPc3WTe8GQv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIB # yjAdBgNVHQ4EFgQU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReui # r/SSy4IxLVGLp6chnfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E # BAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsG # AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0 # dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD # QS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0g # BEkwRzA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRp # Z2ljZXJ0LmNvbS9DUFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBx # lRLpUYdWac3v3dp8qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3 # BTQdaq6Z+CeiZr8JqmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy # 23UC4HLHmNY8ZOUfSBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWT # hZN+tpJn+1Nhiaj1a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZs # pe6HUSHkWGCbugwtK22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VW # MyIvIjayS6JKldj1po5SMYICTTCCAkkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBD # QQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEFAKCBmDAaBgkqhkiG9w0B # CQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIxMDMwMjEwMzIxOVow # KwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU4deCqOGRvu9ryhaRtaq0lKYkm/MwLwYJ # KoZIhvcNAQkEMSIEIOC/gknmf75TuxoFRwyZhQk+JvRg5mHQvsndyI11WwwvMA0G # CSqGSIb3DQEBAQUABIIBAAL4sXG3tTsT5zPLYJUrYZ2FSqqqV+wKIEl7kTFVxa9l # gZk+/iVvN5zeZDIRCn46dNwzNKQJQZlhBprF56fzC/c2VeLvDwwzJI6MD03cqQY7 # ck2TkckMsC8zEY08ntewEY3dg+uLJzfeBztIkdr9tTq/QHODwotl/bq8vYCbeWlo # MkF5Ww7xOGUa5EhyWXGax3GVT2XCuiDa0bGVQBsrovKpSAyDhOS9lJAiGZ1hwksA # 1MfvHvvUJqlKmODhuBZKhFaOIfNUqc5lkTz1gm0XOtFMo4Umaz3LF/DC3g32zgOe # 2PDPf5J9W6thkFPEIlrdX7wm6ylOJYz92/kIL87QWUk= # SIG # End signature block |