Restore-SqlDatabaseコマンドレットを使用してデータベースを復元しようとしています。ファイルを再配置する必要がありますが、次のエラーが発生します
Restore-SqlDatabase : Cannot bind parameter 'RelocateFile'. Cannot convert the
"Microsoft.SqlServer.Management.Smo.RelocateFile" value of type
"Microsoft.SqlServer.Management.Smo.RelocateFile" to type
"Microsoft.SqlServer.Management.Smo.RelocateFile".
At line:25 char:108
+ ... e -RelocateFil $RelocateData
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Restore-SqlDatabase], ParameterBindingException
+ FullyQualifiedErrorId CannotConvertArgumentNoMessage,Microsoft.SqlServer.Management.PowerShell.RestoreSqlDatabaseCommand
私のPowerShellコードは次のようになります
$RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("MyDB_Data", "c:\data\MySQLServerMyDB.mdf")
$RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("MyDB_Log", "c:\data\MySQLServerMyDB.ldf")
$file = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile($RelocateData,$RelocateLog)
$myarr=@($RelocateData,$RelocateLog)
Restore-SqlDatabase -ServerInstance DEV\DEMO -Database "test" -BackupFile $backupfile -RelocateFile $myarr
これは、ロードしたSMOのバージョンとRestore-SqlDatabaseが期待するバージョンの違いのように見えます。ここにはおそらく2つのアプローチがあります...
以下のより大きなスクリプトから関連する部分を抽出しました。この形式ではテストされておらず、$ ServerNameなど、使用可能であると想定される変数がいくつかありますが、それで十分です。
if($useSqlServerAuthentication)
{
$passwordSecureString = ConvertTo-SecureString -String $password -AsPlainText -Force;
$serverConnection = new-object Microsoft.SqlServer.Management.Common.ServerConnection $ServerName, $UserName, $passwordSecureString;
$server = new-object Microsoft.SqlServer.Management.Smo.Server $serverConnection;
}
else
{
$server = new-object Microsoft.SqlServer.Management.Smo.Server $ServerName;
}
$dataFolder = $server.Settings.DefaultFile;
$logFolder = $server.Settings.DefaultLog;
if ($dataFolder.Length -eq 0)
{
$dataFolder = $server.Information.MasterDBPath;
}
if ($logFolder.Length -eq 0)
{
$logFolder = $server.Information.MasterDBLogPath;
}
$backupDeviceItem = new-object Microsoft.SqlServer.Management.Smo.BackupDeviceItem $Path, 'File';
$restore = new-object 'Microsoft.SqlServer.Management.Smo.Restore';
$restore.Database = $DatabaseName;
$restore.Devices.Add($backupDeviceItem);
$dataFileNumber = 0;
foreach ($file in $restore.ReadFileList($server))
{
$relocateFile = new-object 'Microsoft.SqlServer.Management.Smo.RelocateFile';
$relocateFile.LogicalFileName = $file.LogicalName;
if ($file.Type -eq 'D'){
if($dataFileNumber -ge 1)
{
$suffix = "_$dataFileNumber";
}
else
{
$suffix = $null;
}
$relocateFile.PhysicalFileName = "$dataFolder\$DatabaseName$suffix.mdf";
$dataFileNumber ++;
}
else
{
$relocateFile.PhysicalFileName = "$logFolder\$DatabaseName.ldf";
}
$restore.RelocateFiles.Add($relocateFile) | out-null;
}
$restore.SqlRestore($server);
ソリューション#1の場合、正しいアセンブリを使用するためにファイルの再配置をインスタンス化するときに、アセンブリ修飾名を指定する必要があります。
$ RelocateData = New-Object'Microsoft.SqlServer.Management.Smo.RelocateFile、Microsoft.SqlServer.SmoExtended、Version = 11.0.0.0、Culture = neutral、PublicKeyToken = 89845dcd8080cc91 '-ArgumentList "MyDB_Data"、 "c :\ data\MySQLServerMyDB.mdf " $ RelocateLog = New-Object'Microsoft.SqlServer.Management.Smo.RelocateFile、Microsoft.SqlServer.SmoExtended、Version = 11.0.0.0、Culture = neutral、PublicKeyToken = 89845dcd8080cc91 ' -ArgumentList "MyDB_Log"、 "c:\ data\MySQLServerMyDB.ldf" $ file = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile($ RelocateData、$ RelocateLog) $ myarr = @($ RelocateData、$ RelocateLog) Restore-SqlDatabase -ServerInstance DEV\DEMO -Database "test" -BackupFile $ backupfile -RelocateFile $ myarr
それが役に立てば幸い !
これは、バージョンに依存しない方法で実行できます。
$sqlServerSnapinVersion = (Get-Command Restore-SqlDatabase).ImplementingType.Assembly.GetName().Version.ToString()
$assemblySqlServerSmoExtendedFullName = "Microsoft.SqlServer.SmoExtended, Version=$sqlServerSnapinVersion, Culture=neutral, PublicKeyToken=89845dcd8080cc91"
$RelocateData = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, $assemblySqlServerSmoExtendedFullName"('MyDB_Data', 'c:\data\MySQLServerMyDB.mdf')
$RelocateLog = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile, $assemblySqlServerSmoExtendedFullName"('MyDB_Log', 'c:\data\MySQLServerMyDB.ldf')
$myarr=@($RelocateData,$RelocateLog)
Restore-SqlDatabase -ServerInstance DEV\DEMO -Database "test" -BackupFile $backupfile -RelocateFile $myarr
環境パス変数を変更してこの問題を解決することについてブログを書きました。 http://powershelldiaries.blogspot.in/2015/08/backup-sqldatabase-restore-sqldatabase.html を確認してください。上でも述べたように、「サミュエル・デュフォー」の答えが助けになりました。私は別の方法を考えました。
SQLServerとMangementStudioがインストールされていないビルドエージェントでも同じ問題が発生しました。 PSモジュール「SqlServer」のみが使用可能です。
スクリプトの先頭に次の行を追加するだけで、問題は解決しました。
(Get-Command Restore-SqlDatabase).ImplementingType.Assembly
その後、アセンブリがロードされ、すべてのタイプを使用できるようになります。
Snapin Assemblyのバージョン15.0.0.0が、参照されているMicrosoft.SqlServer.SmoExtendedバージョン15.100.0.0と一致しなかったことを除いて、@ Linharesソリューションを使用しました。
そのため、この行を微調整して、参照されているアセンブリから直接バージョンを取得しました。
$sqlServerSnapinVersion = ((Get-Command Restore-SqlDatabase).ImplementingType.Assembly.GetReferencedAssemblies() | ? { $_.Name -eq "Microsoft.SqlServer.SmoExtended" }).Version.ToString()