自动创建数据库镜像,证书交换

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 脚本有2个部分,1.证书交换,2.配置镜像只实现了简答的功能,比如镜像证书配置的检查,容错目前都还没有做1.证书交换$SourceServer='192.168.5.7'$SourcePath='d:\SQL Backups'$SourceUser='adminator'$Source...

脚本有2个部分,1.证书交换,2.配置镜像

只实现了简答的功能,比如镜像证书配置的检查,容错目前都还没有做

1.证书交换

$SourceServer='192.168.5.7'
$SourcePath='d:\SQL Backups'
$SourceUser='adminator'
$SourcePassword='Fam901'
$SourceDBUser='sa'
$SourceDBPassword='Fam901'
$SourceCertName='SQL17'
$DestServer='192.168.0.16'
$DestPath='d:\SQL Backups'
$DestUser='adminitor'
$DestPassword='Fam901'
$DestDBUser='sa'
$DestDBPassword='Fam901'
$DestCertName='SQL16'

Function SetupCertificate {
    Param([string]$server,[string]$database,[string]$uid,[string]$password,[string]$CertName)
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
    $CnnString ="Server = $server; Database = $database;User Id = $uid; Password = $password" 
    $SqlConnection.ConnectionString = $CnnString 
    $CC = $SqlConnection.CreateCommand(); 
    if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() } 
    $str=" 
        
    
    USE master
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<1_Strong_Password!>';
    
     
    USE master;
    CREATE CERTIFICATE $CertName
       WITH SUBJECT = '$CertName certificate for database mirroring',
    EXPIRY_DATE= '08/27/2099';
     
    CREATE ENDPOINT Endpoint_Mirroring
       STATE = STARTED
       AS TCP (
          LISTENER_PORT=5022
          , LISTENER_IP = ALL
       )
       FOR DATABASE_MIRRORING (
          AUTHENTICATION = CERTIFICATE $CertName
          , ENCRYPTION = REQUIRED ALGORITHM AES
          , ROLE = ALL
       );
    BACKUP CERTIFICATE $CertName TO FILE = '$SourcePath\$CertName.cer';


" 
    $str
    $cc.CommandText=$str
    $cc.ExecuteNonQuery()|out-null 
    $SqlConnection.Close();
}

Function LoadCertificate {
    Param([string]$server,[string]$database,[string]$uid,[string]$password,[string]$CertName,[string]$CertPath)
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
    $CnnString ="Server = $server; Database = $database;User Id = $uid; Password = $password" 
    $SqlConnection.ConnectionString = $CnnString 
    $CC = $SqlConnection.CreateCommand(); 
    if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() } 
    $str=" 
        
    
    USE master;
    CREATE LOGIN "+$CertName+"_login
       WITH PASSWORD = '1Sample_Strong_Password!@#';
     
    USE master;
    CREATE USER "+$CertName+"_user FOR LOGIN "+$CertName+"_login;
     
    USE master;
    CREATE CERTIFICATE $CertName
       AUTHORIZATION "+$CertName+"_user
       FROM FILE = '$CertPath\$CertName.cer'
     
    USE master;
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO ["+$CertName+"_login];



" 
    $str
    $cc.CommandText=$str
    $cc.ExecuteNonQuery()|out-null 
    $SqlConnection.Close();
}

Function CheckRmoteDir{
    #######################################
    #Check and create dir remote 
    ######################################
    
    #
    
$password = $SourcePassword | ConvertTo-SecureString -asPlainText -Force
$succredential = New-Object System.Management.Automation.PSCredential $SourceUser,$password

$password = $DestPassword | ConvertTo-SecureString -asPlainText -Force
$destcredential = New-Object System.Management.Automation.PSCredential $DestUser,$password
    
    $sourcesession=New-PSSession -ComputerName $SourceServer -Credential $succredential
    $destsession=New-PSSession -ComputerName $DestServer -Credential $destcredential
    #
    invoke-command -session $sourcesession -scriptblock {
        if (-not(Test-Path $args[0])){ mkdir $args[0] }
    } -ArgumentList $SourcePath 

    invoke-command -session $destsession -scriptblock {
        if (-not(Test-Path $args[0])){ mkdir $args[0] }
    } -ArgumentList $DestPath 
}



CheckRmoteDir

$srcUNC = Join-Path "\\$($SourceServer.Split('\\')[0])" $($SourcePath.Replace(':','$'))
if (-not(Test-Path $srcUNC)) { New-PSDrive -Name s -psprovider FileSystem -root $srcUNC -Credential $succredential }
$destUNC = Join-Path "\\$($DestServer.Split('\\')[0])" $($DestPath.Replace(':','$'))
if (-not(Test-Path $destUNC)) { New-PSDrive -Name d -psprovider FileSystem -root $destUNC -Credential $destcredential }

Test-Path $srcUNC
Test-Path $destUNC


SetupCertificate -server $SourceServer -database "master" -uid $SourceDBUser -password $SourceDBPassword -CertName $SourceCertName
SetupCertificate -server $DestServer -database "master" -uid $DestDBUser -password $DestDBPassword -CertName $DestCertName

$bkpfile = $SourceCertName+".cer"
Copy-Item $(Join-Path $srcUNC $bkpfile) -Destination $destUNC -Verbose
$bkpfile = $destCertName+".cer"
Copy-Item $(Join-Path $destUNC $bkpfile) -Destination $srcUNC -Verbose


LoadCertificate -server $SourceServer -database "master" -uid $SourceDBUser -password $SourceDBPassword -CertName $DestCertName -Certpath $SourcePath
LoadCertificate -server $DestServer -database "master" -uid $DestDBUser -password $DestDBPassword -CertName $SourceCertName -Certpath $SourcePath

2.配置镜像

<#
     .SYNOPSIS
          Set up a mirrored database
     .DESCRIPTION
          Backs up a database and tlog, copies it to the destination,
          Restores the database on the mirror server, sets up the partner,
          and starts the mirror.
     .PARAMETER  database
          The name of the database to be mirrored
     .PARAMETER  SourceServer
          The name of the primary server
     .PARAMETER  SourcePath
          Local Path for the backup
     .PARAMETER  DestServer
          The name of mirror server
     .PARAMETER  DestPath
          Local path for restore file
     .EXAMPLE
          PS C:\> Invoke-Mirror -database 'string value' 1
                    -SourceServer 'string\string' -SourcePath 'string' `
                    -DestServer 'string\string' -DestPath 'string'
     .NOTES
          AUTHOR:    John P. Wood
          CREATED:   July, 2010
          VERSION:   1.0.5
          The SQL connections rely on Windows authentication and assumes Endpoints
          already exist. Error checking is minimal (i.e. no check is made to
          verify the recovery model is FULL).
#>
#Param(
#    [Parameter(Mandatory=$true)]
#    [string]$database,
#    [string]$SourceServer='lcfsqlvs3\sqlvs3',
#    [string]$SourcePath='U:\SQL Backups',
#    [string]$DestServer='ldrsqlvs3\sqlvs3',
#    [string]$DestPath='U:\SQL Backups'
#    )

    $database='mirror_test'
    $SourceServer='192.168.5.17'
    $SourcePath='d:\SQL Backups'
    $SourceUser='adminiator'
    $SourcePassword='Fam901'
    $SourceDBUser='sa'
    $SourceDBPassword='Fam901'
    $DestServer='192.168.5.16'
    $DestPath='d:\SQL Backups'
    $DestUser='adminisor'
    $DestPassword='Fam901'
    $DestDBUser='sa'
    $DestDBPassword='Fams901'
    
Set-StrictMode -Version 2
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")
Function Get-FileName {
    Param([string]$path)
    $names = $path.Split('\\')
    $names[$names.Count - 1]
}
Function New-SMOconnection {
    Param (
        [string]$server,
        [string]$usr,
        [string]$password
    )
    
    $pwd = $password | ConvertTo-SecureString -asPlainText -Force
    $conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($server,$usr ,$pwd)
    $conn.applicationName = "PowerShell SMO"
    $conn.StatementTimeout = 0
    $conn.Connect()
    if ($conn.IsOpen -eq $false) {
        Throw "Could not connect to server $($server) for database backup of $($dbname)."
    }
    $smo = New-Object Microsoft.SqlServer.Management.Smo.Server($conn)
    $smo
}
Function Invoke-SqlBackup {
    $dbbk = new-object ('Microsoft.SqlServer.Management.Smo.Backup')
    $dbbk.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database
    $dbbk.BackupSetDescription = "Full backup of " + $database
    $dbbk.BackupSetName = $database + " Backup"
    $dbbk.Database = $database
    $dbbk.MediaDescription = "Disk"
    $device = "$SourcePath\$bkpfile"
    $dbbk.Devices.AddDevice($device, 'File')
    $smo = New-SMOconnection -server $SourceServer -usr $SourceDBUser -password $SourceDBPassword
    Try {
        $dbbk.SqlBackup($smo)
        $dbbk.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Log
        $dbbk.SqlBackup($smo)
        $smo.ConnectionContext.Disconnect()
    }
    Catch {
        $ex = $_.Exception
        Write-Output $ex.message
        $ex = $ex.InnerException
        while ($ex.InnerException)
        {
            Write-Output $ex.InnerException.message
            $ex = $ex.InnerException
        };
        continue
    }
    Finally {
        if ($smo.ConnectionContext.IsOpen -eq $true) {
            $smo.ConnectionContext.Disconnect()
        }
    }
}
Function Invoke-SqlRestore {
    Param(
        [string]$filename
    )
    # Get a new connection to the server
    $smo = New-SMOconnection -server $DestServer -usr $DestDBUser -password $DestDBPassword
    $backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($filename, "File")
    # Get local paths to the Database and Log file locations
    If ($smo.Settings.DefaultFile.Length -eq 0) {$DBPath = $smo.Information.MasterDBPath }
    Else { $DBPath = $smo.Settings.DefaultFile}
    If ($smo.Settings.DefaultLog.Length -eq 0 ) {$DBLogPath = $smo.Information.MasterDBLogPath }
    Else { $DBLogPath = $smo.Settings.DefaultLog}
 
    # Load up the Restore object settings
    $Restore = new-object Microsoft.SqlServer.Management.Smo.Restore
    $Restore.Action = 'Database'
    $Restore.Database = $database
    $Restore.ReplaceDatabase = $true
    $Restore.NoRecovery = $true
    $Restore.Devices.Add($backupDevice)
 
    # Get information from the backup file
    $RestoreDetails = $Restore.ReadBackupHeader($smo)
    $DataFiles = $Restore.ReadFileList($smo)
 
    # Restore all backup files
    ForEach ($DataRow in $DataFiles) {
        $LogicalName = $DataRow.LogicalName
        $PhysicalName = Get-FileName -path $DataRow.PhysicalName
        $RestoreData = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
        $RestoreData.LogicalFileName = $LogicalName
        if ($DataRow.Type -eq "D") {
            # Restore Data file
            $RestoreData.PhysicalFileName = $DBPath + "\" + $PhysicalName
        }
        Else {
            # Restore Log file
            $RestoreData.PhysicalFileName = $DBLogPath + "\" + $PhysicalName
        }
        [Void]$Restore.RelocateFiles.Add($RestoreData)
 
    }
    Try {
    $Restore.SqlRestore($smo)
    # If there are two files, assume the next is a Log
    if ($RestoreDetails.Rows.Count -gt 1) {
        $Restore.Action = [Microsoft.SqlServer.Management.Smo.RestoreActionType]::Log
        $Restore.FileNumber = 2
        $Restore.SqlRestore($smo)
    }
        $smo.ConnectionContext.Disconnect()
    }
    Catch {
        $ex = $_.Exception
        Write-Output $ex.message
        $ex = $ex.InnerException
        while ($ex.InnerException)
        {
            Write-Output $ex.InnerException.message
            $ex = $ex.InnerException
        };
        continue
    }
    Finally {
        if ($smo.ConnectionContext.IsOpen -eq $true) {
            $smo.ConnectionContext.Disconnect()
        }
    }
}
Function Set-Mirror { 
  
    Param([string]$server,[string]$db,[string]$uid,[string]$password,[string]$partner)
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
    $CnnString ="Server = $server; Database = $db;User Id = $uid; Password = $password" 
    $SqlConnection.ConnectionString = $CnnString 
    $CC = $SqlConnection.CreateCommand(); 
    if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() } 
    $str= "
    ALTER DATABASE $database SET PARTNER off    
    ALTER DATABASE $database SET PARTNER = 'TCP://" + $partner + ":5022'"
    $str
    $cc.CommandText =$str
    $cc.ExecuteNonQuery()|out-null 
    $SqlConnection.Close();
}

Function CheckRmoteDir{
    #######################################
    #Check and create dir remote 
    ######################################
    
    #
    $sourcesession=New-PSSession -ComputerName $SourceServer -Credential $succredential
    $destsession=New-PSSession -ComputerName $DestServer -Credential $destcredential
    #
    invoke-command -session $sourcesession -scriptblock {
        if (-not(Test-Path $args[0])){ mkdir $args[0] }
    } -ArgumentList $SourcePath 

    invoke-command -session $destsession -scriptblock {
        if (-not(Test-Path $args[0])){ mkdir $args[0] }
    } -ArgumentList $DestPath 
}


$password = $SourcePassword | ConvertTo-SecureString -asPlainText -Force
$succredential = New-Object System.Management.Automation.PSCredential $SourceUser,$password

$password = $DestPassword | ConvertTo-SecureString -asPlainText -Force
$destcredential = New-Object System.Management.Automation.PSCredential $DestUser,$password

CheckRmoteDir

$srcUNC = Join-Path "\\$($SourceServer.Split('\\')[0])" $($SourcePath.Replace(':','$'))
if (-not(Test-Path $srcUNC)) { New-PSDrive -Name s -psprovider FileSystem -root $srcUNC -Credential $succredential }
$destUNC = Join-Path "\\$($DestServer.Split('\\')[0])" $($DestPath.Replace(':','$'))
if (-not(Test-Path $destUNC)) { New-PSDrive -Name d -psprovider FileSystem -root $destUNC -Credential $destcredential }

Test-Path $srcUNC
Test-Path $destUNC

$bkpfile =  $($SourceServer.Replace("\", "$")) + "_" + $database + "_FULL_" + $(get-date -format yyyyMMdd-HHmmss) + ".bak"

Invoke-SqlBackup
Copy-Item $(Join-Path $srcUNC $bkpfile) -Destination $destUNC -Verbose
$bkpfile = $DestPath +"\" + $bkpfile
$bkpfile
Invoke-SqlRestore -filename $bkpfile
# Establish Mirroring from the mirrored database
Set-Mirror -server $DestServer -db "master" -uid $DestDBUser -password $DestDBPassword  -partner $($SourceServer.Split('\\')[0])
# Start the mirror
Set-Mirror -server $SourceServer -db "master" -uid $SourceDBUser -password $SourceDBPassword   -partner $($DestServer.Split('\\')[0])

 

目录
相关文章
|
Kubernetes 数据可视化 Docker
Kubeadm方式搭建k8s集群全流程-20230207
Kubeadm方式搭建k8s集群全流程-20230207
257 0
|
人工智能 架构师 NoSQL
24岁程序媛,二战考研失利、三无人员 ==> 最佳新人、优秀个人,讲讲我的技术成长之路
能力、格局、谋略、远见、耐心。灵魂的欲望是命运的先知,希望永远自信、洒脱、松弛、明媚、张扬;追随自己的内心、以喜欢的方式、往正确的方向前行,永远在路上,我甘之如饴! 持续精进Java领域相关技术,包括微服务、高并发、高可用、分布式、集群等等;希望能接触到更多更大的优质项目,逐渐成长为一名具备全栈思维的架构师,既能深入理解底层技术,又能把控全局架构;抽时间了解学习Go语言、人工智能、大模型等领域。 在探索中明晰后续的发展方向,形成自己的一套体系,成为主管、管理层乃至更高,不希望自己的上限只是程序员。
|
网络协议 网络虚拟化 数据中心
VLAN和VXLAN,两者有何区别
随着网络技术发展,云计算因其高利用率、低管理成本及灵活性成为各行业IT建设新趋势。服务器虚拟化作为核心技术之一,提升了数据中心计算密度,但传统二三层网络难以满足虚拟机无限制迁移需求。VLAN技术因支持VLAN数有限,无法满足云服务商需求;而VXLAN技术通过将二层网络扩展到三层,可支持多达1600万个网络,有效克服了VLAN的局限性,实现多租户支持和网络可靠性的提升。
399 1
|
存储 JSON 安全
phpStudy 小皮 Windows面板 RCE漏洞
详情看文章内叙述
545 1
|
C++
[C++] 提取字符串中的所有数字并组成一个数
[C++] 提取字符串中的所有数字并组成一个数
329 0
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
200 4
|
存储 监控 API
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)
本文详细介绍了软件保护技术中的程序脱壳过程,包括IAT(导入地址表)的重建、OD(OllyDbg)跟踪输入表、HOOK-API技术以及FSG、UPX和WinUpacx等常见压缩壳的加脱壳方法。文章通过具体实例和详细步骤,帮助读者理解并掌握逆向工程的基本技巧。[原文链接](https://developer.aliyun.com/article/1618653)
384 0
|
存储 数据处理 索引
数据类型转换:int()、str()、float()
在Python中,数据类型转换是一项基础且重要的操作
|
人工智能 运维 监控
智能化运维:AI在IT基础架构管理中的应用
【6月更文挑战第8天】本文将探讨人工智能(AI)如何革新传统的IT运维领域,实现智能化的故障预测、自动化的修复流程以及高效的资源分配。我们将通过实例分析AI技术如何优化数据中心的能源使用,提升网络性能监控的准确性,并降低系统维护成本。
337 2
|
分布式计算 Kubernetes 监控
容器服务Kubernetes版产品使用合集之registry.aliyuncs.com/google_containers 镜像仓库的地址是什么
容器服务Kubernetes版,作为阿里云提供的核心服务之一,旨在帮助企业及开发者高效管理和运行Kubernetes集群,实现应用的容器化与微服务化。以下是关于使用这些服务的一些建议和合集,涵盖基本操作、最佳实践、以及一些高级功能的使用方法。
1372 0

热门文章

最新文章