PowerShellスクリプトを使用してSQL Serverデータベースを復元しようとしていますが、問題があります。
ここに私が得ているエラーがあります:
"1"引数を使用して "SqlRestore"を呼び出す例外: "サーバー 'WUSFK250042-OLU\SQLSERVER2008R2'の復元に失敗しました。"行:48 char:1 + $ smoRestore.SqlRestore($ server) =
これが私のコードです:
#clear screen
cls
#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for backup
[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
$backupFile = "C:\SafewayRT\SafewayRTFUll.bak"
#we will query the database name from the backup header later
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "WUSFK250042-OLU\SQLSERVER2008R2"
$backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")
#restore settings
$smoRestore.NoRecovery = $false;
$smoRestore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"
$smoRestorePercentCompleteNotification = 10;
$smoRestore.Devices.Add($backupDevice)
#get database name from backup file
$smoRestoreDetails = $smoRestore.ReadFileList($server)
#display database name
"Database Name from Backup Header : " +$smoRestoreDetails.Rows[0]["Safeway_LogixRT"]
#give a new database name
$smoRestore.Database =$smoRestoreDetails.Rows[0]["Safeway_LogixRT"]
#specify new data and log files (mdf and ldf)
$smoRestoreFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$smoRestoreLog = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
#the logical file names should be the logical filename stored in the backup media
$smoRestoreFile.LogicalFileName = $smoRestoreDetails.Rows[0]["Safeway_LogixRT"]
$smoRestoreFile.PhysicalFileName = $server.Information.MasterDBPath + "\" + $smoRestore.Database + "_Data.mdf"
$smoRestoreLog.LogicalFileName = $smoRestoreDetails.Rows[0]["Safeway_LogixRT"] + "_Log"
$smoRestoreLog.PhysicalFileName = $server.Information.MasterDBLogPath + "\" + $smoRestore.Database + "_Log.ldf"
$smoRestore.RelocateFiles.Add($smoRestoreFile)
$smoRestore.RelocateFiles.Add($smoRestoreLog)
#restore database
$smoRestore.SqlRestore($server)
私は同様の問題を抱えていましたが、私のバックアップファイルには、ターゲットDBで間違ったパスが含まれる複数のファイルが含まれていました。これが完全なソリューションです。
[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
$LocalFilePath = "C:\code\HQ_Support"
$backupFile=gi $LocalFilePath\HQ*.bak
#SQL server object
[Microsoft.SqlServer.Management.Smo.Server]$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = New-Object Microsoft.SqlServer.Management.Smo.Restore
$smoRestore.NoRecovery = $false;
$smoRestore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"
$smoRestore.PercentCompleteNotification = 10;
$smoRestore.FileNumber = 0
$smoRestore.Devices.Add($backupDevice)
# Get the details from the backup device for the database name and output that
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)
"Database Name from Backup Header : " + $databaseName
$dbLogicalName = ""
$logLogicalName = ""
$logicalFileNameList = $smoRestore.ReadFileList($server)
foreach($row in $logicalFileNameList)
{
$smoRestore.Database = $smoRestoreDetails.Rows[0]["DatabaseName"]
$fileType = $row["Type"].ToUpper()
if ($fileType.Equals("D"))
{
$dbLogicalName = $row["LogicalName"]
$smoRestoreFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$smoRestoreFile.LogicalFileName = $dbLogicalName
$smoRestoreFile.PhysicalFileName = $server.Information.MasterDBPath + "\" + $dbLogicalName + "_Data.mdf"
$smoRestoreFile
$smoRestore.RelocateFiles.Add($smoRestoreFile)
}
elseif ($fileType.Equals("L"))
{
$logLogicalName = $row["LogicalName"]
$smoRestoreLog = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$smoRestoreLog.LogicalFileName = $logLogicalName
$smoRestoreLog.PhysicalFileName = $server.Information.MasterDBPath + "\" + $dbLogicalName + "_Log.ldf"
$smoRestoreLog
$smoRestore.RelocateFiles.Add($smoRestoreLog)
}
}
$server.KillAllProcesses($databaseName)
$smoRestore.SqlRestore($server)
問題が何であるかを確認するには、その例外に入る必要があります。 Powershellは、ヒープである$ Errorと呼ばれるシステム変数でエラーを追跡します(つまり、インデックス0が最新のエラーです)。私は通常次のようなことをします:
$e = $error[0]
$e.Exception
$e.Exception.InnerException
$e.Exception.InnerException.InnerException
...
本当のエラーを見つけるまで。実際の復元に問題がある可能性があります(つまり、その名前のデータベースがすでに存在している、物理ファイルへの不正なパスなど)。しかし、その例外の根本にたどり着くまで、あなたにはわかりません!
今日この問題があり、バックアップと復元を実現するためにCmdLetを作成しました。私はそれをgithubに置きます: SqlBackupRestore.ps1 これも以下に再現されます:
#region SQL Assemblies
add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop
add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop
add-type -AssemblyName "Microsoft.SqlServer.SMOExtended, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop
add-type -AssemblyName "Microsoft.SqlServer.SqlEnum, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop
add-type -AssemblyName "Microsoft.SqlServer.Management.Sdk.Sfc, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop
#endregion SQL Assemblies
function New-SqlBackup(){
param
(
[parameter(Mandatory=$true)]
[String]
$Instance,
[parameter(Mandatory=$false)]
[String]
$Database
)
$svr = new-Object Microsoft.SqlServer.Management.Smo.Server($Instance)
while(!$Database){
Write-Host $svr.Databases
$Database = (Read-Host -Prompt "Type the database's name:") | % {$_.Trim()}
}
Write-Host 'Gerando backup...'
$dt = Get-Date -Format yyyyMMddHHmmss
$bdir = $svr.Settings.BackupDirectory
$db = $svr.Databases[$database]
$dbname = $db.Name
$dbbk = new-object ('Microsoft.SqlServer.Management.Smo.Backup')
$dbbk.Action = 'Database'
$dbbk.BackupSetDescription = "Full backup of " + $dbname
$dbbk.BackupSetName = $dbname + " Backup"
$dbbk.Database = $dbname
$dbbk.MediaDescription = "Disk"
$dbbk.Devices.AddDevice($bdir + "\" + $dbname + "_db_" + $dt + ".bak", 'File')
$dbbk.SqlBackup($svr.Name)
}
function New-SqlRestore(){
param
(
[parameter(Mandatory=$true)]
[String]
$Instance,
[parameter(Mandatory=$false)]
[String]
$Database,
[parameter(Mandatory=$false)]
[String]
$FileName
)
$svr = new-Object Microsoft.SqlServer.Management.Smo.Server($Instance)
while(!$Database){
Write-Host $svr.Databases
$Database = (Read-Host -Prompt "Type the database's name.") | % {$_.Trim()}
}
$bdir = $svr.Settings.BackupDirectory
$dbbk = new-object ('Microsoft.SqlServer.Management.Smo.Backup')
while(!$FileName){
Write-Host (Get-ChildItem $bdir)
$FileName = (Read-Host -Prompt "Type the filename:") | % {$_.Trim()}
}
Write-Host 'Restoring...'
$BackupFile = Get-ChildItem $bdir -Filter $FileName | select -First 1
Write-Host $BackupFile
$db = $svr.Databases[$Database]
$dbname = $db.Name
$smoRestore = New-Object Microsoft.SqlServer.Management.Smo.Restore
$smoRestore.PercentCompleteNotification = 10;
$smoRestore.Database = $dbname
$smoRestore.NoRecovery = $false
$smoRestore.ReplaceDatabase = $true
$smoRestore.FileNumber = 0
$bdi = new-object Microsoft.SqlServer.Management.Smo.BackupDeviceItem($BackupFile.FullName, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
$smoRestore.Devices.Add($bdi)
$svr.KillAllProcesses($dbname)
$smoRestore.SqlRestore($svr)
}