2011-02-25 5 views
9

다른 서버에서 데이터베이스 백업을 사용하고 있습니다. localhost의 sqlexpress로 복원하려고합니다. 이 복원은 GUI를 통해 작동하지만 PowerShell로 복원 할 때 문제가 있습니다. 이 라인의 문자 23smo 및 powershell을 사용하여 데이터베이스 백업을 새 데이터베이스로 복원하는 중 오류가 발생했습니다.

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

오류 메시지 포인트 : 나는 다음과 같은 오류 메시지가

 $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

답변

11

, 몇 가지 주목할만한 차이점이 있습니다 :

  • SqlRestore으로 전화하기 전에 $server.KillAllProcesses($databaseName)으로 전화를 겁니다.
  • 나는 당신이 전혀없는 $smoRestore.FileNumber = 1을 가지고 대신 $true
  • 의, $smoRestore.NoRecovery = $false 있습니다. 나는 이것이 GUI에서 설정된 백업으로부터 파일을 검사하는 것에 해당한다고 생각한다.

도 논리적/물리적 파일 이름을 설정하는 코드가 비슷하지만 $server.Information 대신에 레지스트리에서 정보를 가져옵니다 (어느 것이 "더 좋음"인지는 확실하지 않음). 또 다른 차이점은 $smoRestore.ReadBackupHeader 대신 $smoRestore.ReadFileList을 사용한다는 것입니다.

경로 상에 몇 개의 Write-Host 문을 사용하여 올바르게 보이는지 확인할 수도 있습니다.

글 머리 기호 조정 중 하나가 문제를 해결하기를 바랍니다. 제 스크립트에서 더 많은 정보를 원한다면 알려주십시오.

+0

"$ smoRestore.FileNumber = 1"을 추가하는 모든 독자는 나를 위해 해낸 속임수였습니다. – CIGuy

+6

예외를 자세히 파고들 수도 있습니다. 사용해보십시오 : '$ Error [0] .exception.GetBaseException(). Message' – sakadas

1

동료와 나는이 문제를 모두 가지고 있었고 약간의 문제 해결 후에 SQL Server Management Studio를 닫는 것이 트릭을 찾았다.

다른 누군가가 우리가 수행 한 모든 문제 해결을 건너 뛰어도 좋지만이 간단한 솔루션을 사용하면 몇 시간 만 절약 할 수 있기를 바랍니다.

관련 문제