diff --git a/Restore_DB_Keyvi.ps1 b/Restore_DB_Keyvi.ps1 new file mode 100644 index 0000000..8af0fe9 --- /dev/null +++ b/Restore_DB_Keyvi.ps1 @@ -0,0 +1,124 @@ +# ========================= +# Konfiguration +# ========================= +$Server = ".\KEYVI" +$Mode = "Test" # "Test" oder "Production" +$BackupFile = "D:\SQLBackup\DB_Keyvi\2026\07\DB_Keyvi_20260729_205555.bak" + +$ProdDb = "DB_Keyvi" +$TestDb = "DB_Keyvi_RestoreTest" +# ========================= + +$ErrorActionPreference = "Stop" + +if ($Mode -notin @("Test","Production")) { + throw "Ungültiger Mode '$Mode'. Erlaubt: Test oder Production." +} +if (-not (Test-Path $BackupFile)) { + throw "Backup-Datei nicht gefunden: $BackupFile" +} + +$TargetDb = if ($Mode -eq "Production") { $ProdDb } else { $TestDb } + +Write-Host "Modus: $Mode" +Write-Host "Server: $Server" +Write-Host "Ziel-Datenbank: $TargetDb" +Write-Host "Backup-Datei: $BackupFile" + +if ($Mode -eq "Production") { + Write-Warning "PRODUCTION-MODUS: Datenbank [$ProdDb] wird überschrieben!" + $confirm = Read-Host "Tippe genau 'JA' zum Fortfahren" + if ($confirm -ne "JA") { throw "Abgebrochen durch Benutzer." } +} + +# Alles in SQL erledigen (robust, kein Text-Parsing nötig) +$sql = @" +USE [master]; + +DECLARE @BackupFile nvarchar(4000) = N'$BackupFile'; +DECLARE @TargetDb sysname = N'$TargetDb'; + +DECLARE @DataPath nvarchar(4000) = CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS nvarchar(4000)); +DECLARE @LogPath nvarchar(4000) = CAST(SERVERPROPERTY('InstanceDefaultLogPath') AS nvarchar(4000)); + +IF @DataPath IS NULL OR @LogPath IS NULL +BEGIN + RAISERROR(N'InstanceDefaultDataPath/LogPath konnte nicht ermittelt werden.',16,1); + RETURN; +END + +DECLARE @filelist TABLE ( + LogicalName nvarchar(128), + PhysicalName nvarchar(260), + [Type] char(1), + FileGroupName nvarchar(128), + [Size] numeric(20,0), + MaxSize numeric(20,0), + FileID bigint, + CreateLSN numeric(25,0), + DropLSN numeric(25,0), + UniqueID uniqueidentifier, + ReadOnlyLSN numeric(25,0), + ReadWriteLSN numeric(25,0), + BackupSizeInBytes bigint, + SourceBlockSize int, + FileGroupID int, + LogGroupGUID uniqueidentifier, + DifferentialBaseLSN numeric(25,0), + DifferentialBaseGUID uniqueidentifier, + IsReadOnly bit, + IsPresent bit, + TDEThumbprint varbinary(32), + SnapshotURL nvarchar(360) +); + +DECLARE @sqlFileList nvarchar(max) = + N'RESTORE FILELISTONLY FROM DISK = N''' + REPLACE(@BackupFile,'''','''''') + N''';'; + +INSERT INTO @filelist +EXEC(@sqlFileList); + +DECLARE @DataLogical sysname = (SELECT TOP(1) LogicalName FROM @filelist WHERE [Type]='D' ORDER BY FileID); +DECLARE @LogLogical sysname = (SELECT TOP(1) LogicalName FROM @filelist WHERE [Type]='L' ORDER BY FileID); + +IF @DataLogical IS NULL OR @LogLogical IS NULL +BEGIN + RAISERROR(N'Konnte logische Daten-/Log-Datei im Backup nicht finden.',16,1); + RETURN; +END + +DECLARE @MdfTarget nvarchar(4000) = @DataPath + @TargetDb + N'.mdf'; +DECLARE @LdfTarget nvarchar(4000) = @LogPath + @TargetDb + N'_log.ldf'; + +IF DB_ID(@TargetDb) IS NOT NULL +BEGIN + DECLARE @sqlSingle nvarchar(max) = N'ALTER DATABASE [' + @TargetDb + N'] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;'; + EXEC(@sqlSingle); +END + +DECLARE @sqlRestore nvarchar(max) = N' +RESTORE DATABASE [' + @TargetDb + N'] +FROM DISK = N''' + REPLACE(@BackupFile,'''','''''') + N''' +WITH + MOVE N''' + REPLACE(@DataLogical,'''','''''') + N''' TO N''' + REPLACE(@MdfTarget,'''','''''') + N''', + MOVE N''' + REPLACE(@LogLogical, '''','''''') + N''' TO N''' + REPLACE(@LdfTarget, '''','''''') + N''', + REPLACE, + RECOVERY, + STATS = 10;'; + +EXEC(@sqlRestore); + +DECLARE @sqlMulti nvarchar(max) = N'ALTER DATABASE [' + @TargetDb + N'] SET MULTI_USER;'; +EXEC(@sqlMulti); + +PRINT N'Restore erfolgreich: ' + @TargetDb; +PRINT N'MDF: ' + @MdfTarget; +PRINT N'LDF: ' + @LdfTarget; +"@ + +sqlcmd -S $Server -E -C -b -Q $sql +if ($LASTEXITCODE -ne 0) { + throw "Restore fehlgeschlagen (ExitCode $LASTEXITCODE)." +} + +Write-Host "Fertig." -ForegroundColor Green \ No newline at end of file