使用PowerShell和SMO库从.BAK文件创建新数据库
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PowerShell和SMO库从.BAK文件创建新数据库相关的知识,希望对你有一定的参考价值。
我正在尝试使用powershell从.bak
文件创建一个新的SQL Server数据库。
这是我的脚本:
TRY
{
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SmoExtended') | out-null
$servername = "MyServerMyServerInstance"
$datapath= "E:SQLDataMyNewDataBase"
$logpath= "E:SQLLogsMyNewDataBase"
$path= "\MyServerBKPFolder"
$server = new-object("Microsoft.SqlServer.Management.Smo.Server") $servername
$folderitem=Get-ChildItem $path -filter *.bak -rec
foreach($bkfiles in $folderitem)
{
$dbRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")
$files = $path+$bkfiles.Name
$backupFile = $files
$dbRestore.Devices.AddDevice($backupFile, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
$dbRestoreDetails = $dbRestore.ReadBackupHeader($server)
$dbFileList= $dbRestore.ReadFileList($server)
foreach ($row in $dbFileList)
{
$FileType = $row["Type"].ToUpper()
If ($FileType.Equals("D"))
{
$DBLogicalName = $Row["LogicalName"]
}
ELSEIf ($FileType.Equals("L"))
{
$LogLogicalName = $Row["LogicalName"]
}
}
$dbRestoreFile = new-object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$dbRestoreLog = new-object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$dbRestoreFile.LogicalFileName = $DBLogicalName
$dbRestoreFile.PhysicalFileName =$datapath + "" + $DBLogicalName + ".mdf"
$dbRestoreLog.LogicalFileName = $LogLogicalName
$dbRestoreLog.PhysicalFileName = $logpath + "" + $LogLogicalName + ".ldf"
$dbRestore.RelocateFiles.Add($dbRestoreFile)
$dbRestore.RelocateFiles.Add($dbRestoreLog)
$dbRestore.Database = "MyNewDataBase"
$dbRestore.NoRecovery = $false
$dbRestore.Action = "DataBase"
$dbRestore.FileNumber = 1;
$dbRestore.ReplaceDatabase = $false;
$dbRestore.SqlRestore($server)
}
} catch {
"Database restore failed:`n`n " + _.Exception.GetBaseException().Message
}
当我运行此代码时,我收到此错误:
文件“E: SQLData MyNewDataBase OLDDataBase_Data.mdf”的目录查找失败,出现操作系统错误2(系统找不到指定的文件。)。
文件'OLDDataBase_Data'无法还原为'E: SQLData MyNewDataBase OLDDataBase_Data.mdf'。使用WITH MOVE标识文件的有效位置。
在规划RESTORE语句时发现了问题。以前的消息提供详情。 RESTORE DATABASE异常终止。
看起来我的脚本试图从旧数据库中找到.mdf
和.ldf
文件。但我只是从旧数据库中获得了一个.bak
文件。
我错过了什么?
谢谢。
答案
经过大量的研究和尝试,我终于恢复了我的数据库。这对我有用:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
#Define o novo local dos arquivos de mdf e ldf
$RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("OldDataBase_Data", "E:SQLDataMyNewDataBase_DATA.mdf")
$RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("OldDataBase_Log", "E:SQLLogsMyNewDataBase_LOG.ldf")
#Executa a restauração
Restore-SqlDatabase -ServerInstance "MyServerMyServerInstance" -Database "MyNewDataBase" -BackupFile "\BackupFolderOldDataBase.bak" -RelocateFile @($RelocateData,$RelocateLog) -NoRecovery
Restore-SqlDatabase -ServerInstance "MyServerMyServerInstance" -Database "MyNewDataBase" -BackupFile "\BackupFolderOldDataBase.trn" -RestoreAction Log -NoRecovery
另一答案
希望这是你需要的:
function Restore-MsSqlDatabase {
<#
.Synopsis
Restore MSSQL database using Microsoft.SQLServer.Management.Smo.{BackupDeviceItem,Restore,RelocateFile}
.Description
Restore MSSQL database using Microsoft.SQLServer.Management.Smo.{BackupDeviceItem,Restore,RelocateFile}
.Example
Restore-MsSqlDatabase -BackupFile 'D:ackupsaateam_20491005.bak' -Verbose
.Example
Restore-MsSqlDatabase -BackupFile 'D:ackupsaateam_20491005.bak' -SqlHost SQL-SERVER001 -Verbose
#>
[CmdletBinding()]
Param(
[Parameter(Position=0)] [ValidateNotNullOrEmpty()]
[string]$BackupFile,
[Parameter(Position=1)] [ValidateNotNullOrEmpty()]
[string]$SqlHost="localhost"
)
Begin{
Write-Verbose ("$(Get-Date) - INFO - Load assembly for Microsoft.SqlServer.SMO")
$null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
Write-Verbose ("$(Get-Date) - INFO - Load assembly for Microsoft.SqlServer.SMOExtended")
$null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended")
Write-Verbose ("$(Get-Date) - INFO - New connection object")
$MsSqlConnection=New-Object Microsoft.SqlServer.Management.Smo.Server $SqlHost
Write-Verbose ("$(Get-Date) - INFO - Initialize connection")
$null=$MsSqlConnection.Initialize()
}
Process{
Try{
Write-Verbose ("$(Get-Date) - INFO - New backup device item")
$BackupDeviceItem=New-Object Microsoft.SQLServer.Management.Smo.BackupDeviceItem
$BackupDeviceItem.Name=$backupFile
$BackupDeviceItem.DeviceType="File"
Write-Verbose ("$(Get-Date) - INFO - New restore device")
$RestoreDevice=New-Object Microsoft.SQLServer.Management.Smo.Restore
$RestoreDevice.Action="Database"
$RestoreDevice.ReplaceDatabase=$true
$RestoreDevice.NoRecovery=$false
Write-Verbose ("$(Get-Date) - INFO - Add backup device item to restore device")
$RestoreDevice.Devices.Add($BackupDeviceItem)
Write-Verbose ("$(Get-Date) - INFO - Read backup header")
$BackupHeader=$RestoreDevice.ReadBackupHeader($MsSqlConnection)
Write-Verbose ("$(Get-Date) - INFO - Set databse name in restore device")
$RestoreName=$BackupHeader.Rows[0].DatabaseName
$RestoreDevice.Database=$RestoreName
Write-Verbose ("$(Get-Date) - INFO - Read backup file list")
$FileList=$RestoreDevice.ReadFileList($MsSqlConnection)
Write-Verbose ("$(Get-Date) - INFO - Relocate mdf,ldf,ndf files")
ForEach ($File in $FileList) {
Write-Verbose ("$(Get-Date) - INFO - New relocate device")
$RelocateFile=New-Object Microsoft.SqlServer.Management.Smo.RelocateFile
Switch ($File.FileId) {
1 {
Write-Verbose ("$(Get-Date) - INFO - New physical path for mdf file")
$NewPhysicalPath="{0}{1}.mdf" -f $MsSqlConnection.DefaultFile,$RestoreName
}
2 {
Write-Verbose ("$(Get-Date) - INFO - New physical path for ldf file")
$NewPhysicalPath="{0}{1}.ldf" -f $MsSqlConnection.DefaultFile,$RestoreName
}
Default {
Continue
}
}
Write-Verbose ("$(Get-Date) - INFO - Relocate files")
$RelocateFile.LogicalFileName=$File.LogicalName
$RelocateFile.PhysicalFileName=$NewPhysicalPath
$null=$RestoreDevice.RelocateFiles.Add($RelocateFile)
}
Write-Verbose ("$(Get-Date) - INFO - Test if database already exists")
If($MsSqlConnection.Databases[$RestoreName]){
Write-Verbose ("$(Get-Date) - INFO - Kill all processes connected to database")
$MsSqlConnection.KillAllProcesses($RestoreName)
Write-Verbose ("$(Get-Date) - INFO - Set database offline")
$MsSqlConnection.Databases[$RestoreName].SetOffline()
}
Else{
Write-Verbose ("$(Get-Date) - INFO - Databse currently not present in SQL instance")
}
Write-Verbose ("$(Get-Date) - INFO - Restore device")
$RestoreDevice.SQLRestore($MsSqlConnection)
$MsSqlConnection.Databases.Refresh()
Write-Verbose ("$(Get-Date) - INFO - Set database online")
$MsSqlConnection.Databases[$RestoreName].SetOnline()
}
Catch{
Write-Verbose ("$(Get-Date) - ERROR - {0}" -f $_.Exception.Message)
}
Finally{}
}
End{}
}
然后做:
Get-Help -Name Restore-MsSqlDatabase -Examples
以上是关于使用PowerShell和SMO库从.BAK文件创建新数据库的主要内容,如果未能解决你的问题,请参考以下文章
使用 smo 和 powershell 将数据库备份还原到新数据库时出错