2011-02-25 81 views
9

从另一台服务器,我想恢复到SQLEXPRESS本地主机上以数据库备份新的数据库。这种恢复将通过gui工作,但我遇到的问题使用PowerShell进行恢复。我收到以下错误信息:错误数据库备份恢复到与SMO和PowerShell

Exception calling "SqlRestore" with "1" argument(s): "Restore failed for Server 
+ $smoRestore.SqlRestore <<<< ($server) 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : DotNetMethodException 

错误信息指向该行的字符23:

 $smoRestore.SqlRestore($server) 

脚本:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null 

Import-Module PSCX 
Import-Module WebAdministration 

function GetLatestItem(){ 
    param([string]$RemotePath) 
    $returnString = Get-ChildItem $RemotePath -force -filter "*.7z" | sort @{expression={$_.LastWriteTime}; Descending=$true} | select Name -first 1 
    return $returnString.Name 
} 

function DatabaseExists(){ 
    param([Microsoft.SqlServer.Management.Smo.Server]$server,[string]$databaseName) 
    foreach($database in $server.Databases){ 
     if($database.Name -eq $databaseName){ 
      $true 
     } 
    } 
    $false 
} 

$LocalFile = "C:\backups\backupname.bak.7z" 
$LocalFilePath = "C:\backups\" 

Expand-Archive $Localfile $LocalFilePath  

# Most of the restore information was found at http://www.sqlmusings.com/2009/06/01/how-to-restore-sql-server-databases-using-smo-and-powershell/ 
$backupFile = $LocalFilePath + [IO.Path]::GetFileNameWithoutExtension($LocalFile) 
[Microsoft.SqlServer.Management.Smo.Server]$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") ".\SQLEXPRESS" 
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File") 
$smoRestore = New-Object Microsoft.SqlServer.Management.Smo.Restore 

$smoRestore.NoRecovery = $true; 
$smoREstore.ReplaceDatabase = $true; 
$smoRestore.Action = "Database" 
$smoRestore.PercentCompleteNotification = 10; 
$smoRestore.Devices.Add($backupDevice) 

# Get the details from the backup device for the database name and output that 
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server) 
$databaseName = $smoRestoreDetails.Rows[0]["DatabaseName"] 

"Database Name from Backup Header : " + $databaseName 
$smoRestore.Database = $databaseName  

if(DatabaseExists $server $databaseName -not){ 
    $smoRestoreFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile") 
    $smoRestoreLog = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile") 
    $smoRestoreFile.LogicalFileName = $smoRestoreDetails.Rows[0]["DatabaseName"] 
    $smoRestoreFile.PhysicalFileName = $server.Information.MasterDBPath + "\" + $smoRestore.Database + "_Data.mdf" 
    $smoRestoreLog.LogicalFileName = $smoRestoreDetails.Rows[0]["DatabaseName"] + "_Log" 
    $smoRestoreLog.PhysicalFileName = $server.Information.MasterDBPath + "\" + $smoRestore.Database + "_Log.ldf" 
    $smoRestore.RelocateFiles.Add($smoRestoreFile) 
    $smoRestore.RelocateFiles.Add($smoRestoreLog) 
} 

$smoRestore.SqlRestore($server) 
if($error.Count -eq 0){ 
} 
else{ 
    $Error[0].exception.message 
} 
+0

你的问题代码,帮我解决了问题!谢谢:) – Gezim 2013-01-28 20:23:45

回答

11

我有一个非常类似的脚本来你的,有一些值得注意的区别:

  • 致电SqlRestore之前,我打电话给$server.KillAllProcesses($databaseName)
  • 我有$smoRestore.NoRecovery = $false,而不是$true
  • 我有$smoRestore.FileNumber = 1,你不必在所有。我认为这对应于从GUI中的备份集检查文件。

我也有设置逻辑/物理文件名类似的代码,但不是使用$server.Information,我从注册表(不知道这是“更好”)提取信息。另一个区别是我使用$smoRestore.ReadFileList而不是$smoRestore.ReadBackupHeader

您也可以尝试使用上你的路几Write-Host报表,以确保他们看的权利,如果您还没有。

希望项目符号的调整的一个解决您的问题。让我知道,如果你想从我的脚本更多的信息。

+0

对于任何未来的读者,添加“$ smoRestore.FileNumber = 1”是为我做的窍门。 – CIGuy 2013-10-02 15:27:49

+6

你也可以尝试深入研究这个例外。尝试使用: '$错误[0] .exception.GetBaseException()Message' – sakadas 2015-01-26 06:22:06

1

一位同事和我都有这个问题,经过一些故障排除后,我们发现关闭SQL Server Management Studio的确有窍门。

希望别人可以跳过我们所做的所有故障排除,这个简单的解决方案将为他们节省几个小时。