param ( [string] $Server, [string] $Database, [string] $Backup ) ## Path and name used to invoke script $CUR_SCRIPT = $myinvocation.InvocationName ## Load SMO assemblies [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")|out-null [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum")|out-null [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")|out-null $SMO = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") ## Parse out the internal version number $SMOVer = $SMO.FullName.Split(",")[1].Split("=")[1].Split(".")[0] ## Load SMOExtended if not SQL Server 2005 (9) if ($SMOVer -ne 9) { [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended")|out-null } ## Check user input, prompt for each value not provided as parameters if(!$Server) { $Server = read-host "Enter Server Name" } if(!$Database) { $Database = read-host "Enter Database Name" } if(!$Backup) { $Backup = read-host "Enter Backup Path\Name" } ## Return Help and exit if any required input is missing if(!$Server -or !$Database -or !$Backup) { write-host "Usage: $CUR_SCRIPT options: string SQL Server Instance string Database Name string Backup Path and Name" -f red exit } ## Function to raise error Function RaisError ([string]$ErrMsg){ write-host $ErrMsg -f red $error.clear() } ## Create server object $Srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $Server ## Make sure backup file exists $BackupExists = Test-Path $Backup if (!$BackupExists) { RaisError "`tBackup file does not exist or is not accessible." Exit } ## If database exists, delete it $DBExists = $Srv.Databases[$Database] if ($DBExists) { if ($DBExists.status -eq "online") { $Srv.KillDatabase($Database) } else { $DBExists.drop() } if ($error){ RaisError "`tDrop of existing database returned an error." Exit } } ## Restore the database $Restore = new-object "Microsoft.SqlServer.Management.Smo.Restore" $Restore.Database = $Database $Restore.Action = 'Database' $BkFile = new-object "Microsoft.SqlServer.Management.Smo.BackupDeviceItem" $BkFile.DeviceType = 'File' $BkFile.Name = $Backup $Restore.Devices.Add($BkFile) $Restore.ReplaceDatabase = $false ## Check file list and generate new file names if files already exists $DateSerial = Get-Date -Format yyyyMMddHHmmss $DataFiles = $Restore.ReadFileList($Server) ForEach ($DataRow in $DataFiles) { $LogicalName = $DataRow.LogicalName $PhysicalName = $DataRow.PhysicalName $FileExists = Test-Path $PhysicalName if ($FileExists) { $PhysicalName = $PhysicalName -replace(".mdf", "_$DateSerial.mdf") $PhysicalName = $PhysicalName -replace(".ldf", "_$DateSerial.ldf") $PhysicalName = $PhysicalName -replace(".ndf", "_$DateSerial.ndf") $Restore.RelocateFiles.Add((new-object microsoft.sqlserver.management.smo.relocatefile -ArgumentList $LogicalName, $PhysicalName)) | out-null; } } $Restore.NoRecovery = $false $Restore.PercentCompleteNotification = 5 $Restore.SqlRestore($Server) if (!$error){ write-host "`tDatabase $Database restored from $Backup" -f green } else { RaisError "`tRestore of database $Database returned an error." Exit }