Erreur lors de la restauration de la sauvegarde de la database dans une nouvelle database avec smo et powershell

Prenant une sauvegarde de database à partir d'un autre server, j'essaie de restaurer en sqlexpress sur le localhost. Cette restauration fonctionnera via le gui mais j'ai des problèmes de restauration avec PowerShell. Je reçois le message d'erreur suivant:

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

Le message d'erreur pointe vers le caractère 23 de cette ligne:

  $smoRestore.SqlRestore($server) 

Scénario:

 [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([ssortingng]$RemotePath) $returnSsortingng = Get-ChildItem $RemotePath -force -filter "*.7z" | sort @{expression={$_.LastWriteTime}; Descending=$true} | select Name -first 1 return $returnSsortingng.Name } function DatabaseExists(){ param([Microsoft.SqlServer.Management.Smo.Server]$server,[ssortingng]$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 } 

J'ai un script très similaire au vôtre, avec quelques différences notables:

  • Avant d'appeler SqlRestore , j'appelle $server.KillAllProcesses($databaseName) .
  • J'ai $smoRestore.NoRecovery = $false , au lieu de $true
  • J'ai $smoRestore.FileNumber = 1 , que vous n'avez pas du tout. Je pense que cela correspond à vérifier un file du jeu de sauvegarde dans l'interface graphique.

J'ai également un code similaire pour définir les noms de files logiques / physiques, mais au lieu d'utiliser $server.Information , je tire les informations du registre (je ne sais pas qui est "meilleur"). Une autre différence est que j'utilise $smoRestore.ReadFileList au lieu de $smoRestore.ReadBackupHeader .

Vous pouvez également essayer d'utiliser quelques instructions Write-Host sur vos paths pour vous assurer qu'elles semblent correctes, si ce n'est déjà fait.

J'espère que l'un des réglages à puces résout votre problème. Faites-moi savoir si vous voulez plus d'informations de mon script.

Un collègue et moi avons tous deux eu ce problème, et après un peu de dépannage nous avons constaté que la fermeture de SQL Server Management Studio a fait l'affaire.

Heureusement, quelqu'un d'autre peut sauter tout le dépannage que nous avons fait et cette solution facile les sauvera quelques heures.