2011-02-25 25 views
9

Tomando una copia de seguridad de la base de datos desde otro servidor Estoy tratando de restaurar a sqlexpress en el host local. Esta restauración funcionará a través de la interfaz gráfica de usuario, pero estoy teniendo problemas para restaurarla con PowerShell. Me sale el siguiente mensaje de error:Error al restaurar la copia de seguridad de la base de datos a la nueva base de datos con smo y powershell

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

El error puntos mensaje a caracteres 23 de esta línea:

 $smoRestore.SqlRestore($server) 

Guión:

[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

¡Su código de pregunta me ayudó a resolver un problema! Gracias :) – Gezim

Respuesta

11

Tengo un guión muy similar a la suya, con algunas diferencias notables:

  • Antes de llamar al SqlRestore, hago una llamada al $server.KillAllProcesses($databaseName).
  • tengo $smoRestore.NoRecovery = $false, en lugar de $true
  • tengo $smoRestore.FileNumber = 1, que no tiene en absoluto. Creo que esto corresponde a verificar un archivo del conjunto de copias de seguridad en la GUI.

que también tienen un código similar para establecer los nombres de archivos lógicos/físicos, pero en lugar de utilizar $server.Information, me tire de la información del registro (no estoy seguro que es "mejor"). Otra diferencia es que utilizo $smoRestore.ReadFileList en lugar de $smoRestore.ReadBackupHeader.

También puede intentar usar algunas declaraciones Write-Host en sus rutas para asegurarse de que se vean bien, si no lo ha hecho ya.

Espero que uno de los ajustes con viñetas resuelva su problema. Avísame si quieres más información de mi script.

+0

Para cualquier lector futuro, agregando "$ smoRestore.FileNumber = 1" fue el truco que lo hizo por mí. – CIGuy

+6

También puede intentar profundizar en la excepción. Intente usar: '$ Error [0] .exception.GetBaseException(). Message' – sakadas

1

Un compañero de trabajo y yo teníamos este problema, y ​​después de un poco de solución de problemas descubrimos que cerrar SQL Server Management Studio hizo el truco.

Esperemos que alguien más se salte toda la resolución de problemas que hicimos y esta sencilla solución les ahorrará unas horas.

Cuestiones relacionadas