Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
2 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 185

Powershell +SQL Восстановление баз с прогрессом

31.01.2018, 16:13. Показов 2887. Ответов 3

Студворк — интернет-сервис помощи студентам
Доброго времени уважаемые форумчани.

Есть у меня один рабочий скрипт по восстановлению баз даных
в котором идет обращения на файлы. sql в которых и прописано само восстановление
код такой:

Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlCatalog = "master";
$SqlLogin = "sa";
$arrayofDATA=@(
$(New-Object PSOBJECT -Property @{
PATH='C:\Temp\analit.sql'
SERVER="."
Pass="321"
}),
$(New-Object PSOBJECT -Property @{
PATH='C:\Temp\kassa.sql'
SERVER=".\KASSA"
Pass="123"
}))
 
foreach($data in $arrayofDATA)
{
    $SERV=$data.Server
    $PATH=$data.PATH
    $Pass=$data.Pass
    $SqlConnection.ConnectionString = "Server=$SERV; Database=$SqlCatalog; User ID=$SqlLogin; Password=$Pass;"
    $SqlConnection.Open()
    $SqlCmd = $SqlConnection.CreateCommand()
    $SqlCmd.CommandTimeout = 0;
    $SqlCmd.CommandText = [IO.File]::ReadAllText($PATH) ;
    $objReader = $SqlCmd.ExecuteReader()
    while ($objReader.HasRows)
{
 
    while ($objReader.read()) {
    echo $objReader.GetValue(0)
}
$objReader.NextResult();    
}
    $objReader.close()
    $SqlConnection.Close()
}


У меня вопрос Следующего характера , хочу для себя сделать прогресс бар востановления, т.к. неудобно и не понятно
через сколько и какие базы на каком этапе восстанавливаются
в инете, накопал 2 интересных готовых решений, но они в коем веке для меня не до конца понятны

Прошу вашей помощи . подсказать , допилить уже существующий скрипт. чтоб в момент восстановления был
информативный прогрессбар

Скрипты которые я нашел ниже
Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<#
  sqlps dependency
  If module sqlps does not exist, install from:
    Microsoft SQL Server 2016 Feature Pack ([url]https://www.microsoft.com/en-us/download/details.aspx?id=52676[/url])
    - SQLSysClrTypes.msi
    - SharedManagementObjects.msi
    - PowershellTools.msi
#>
 
param(
  [Parameter(Mandatory=$true,Position=0)]
  [string]$servername,
  [Parameter(Mandatory=$true,Position=1)]
  [string]$dbname,
  [Parameter(Mandatory=$true,Position=2)]
  [string]$filename)
 
 
 
Push-Location
Import-Module "sqlps" -DisableNameChecking
Pop-Location
 
<#
  MAIN
#>
 
$server = New-Object Microsoft.SqlServer.Management.Smo.Server $servername
$restore = New-Object Microsoft.SqlServer.Management.Smo.Restore
$device = New-Object Microsoft.SqlServer.Management.Smo.BackupDeviceItem $filename, "FILE"
$restore.Devices.Add($device)
try {
  $filelist = $restore.ReadFileList($server)
}
catch {
    $exception = $_.Exception
    Write-Host "$exception. `n`nDoes the SQL Server service account have acccess to the backup location?" -ForegroundColor Red
  exit 1
}
 
$filestructure = @{}; $datastructure = @{}; $logstructure = @{}
$logfiles = $filelist | Where-Object {$_.Type -eq "L"}
$datafiles = $filelist | Where-Object {$_.Type -ne "L"}
 
# Data Files (if db has filestreams, make sure server has them enabled)
$defaultdata = $server.DefaultFile
$defaultlog = $server.DefaultLog
if ($defaultdata.Length -eq 0) {
    $defaultdata = $server.Information.MasterDBPath
}
 
if ($defaultlog.Length -eq 0) {
    $defaultlog = $server.Information.MasterDBLogPath
}
 
foreach ($file in $datafiles) {
    $newfilename = Split-Path $($file.PhysicalName) -leaf
 
    $datastructure.physical = "$defaultdata$newfilename"
    $datastructure.logical = $file.LogicalName
    $filestructure.add($file.LogicalName,$datastructure)
}
 
# Log Files
foreach ($file in $logfiles) {
    $newfilename = Split-Path $($file.PhysicalName) -leaf
 
    $logstructure.physical = "$defaultlog$newfilename"
    $logstructure.logical = $file.LogicalName
    $filestructure.add($file.LogicalName,$logstructure)
}
 
# Make sure big restores don't timeout
$server.ConnectionContext.StatementTimeout = 0
 
foreach ($file in $filestructure.values) {
    $movefile = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile"
    $movefile.LogicalFileName = $file.logical
    $movefile.PhysicalFileName = $file.physical
    $null = $restore.RelocateFiles.Add($movefile)
}
 
Write-Host "Restoring $dbname to $servername" -ForegroundColor Yellow
 
# kill all connections
$server.KillAllProcesses($dbname)
 
try {
 
    $percent = [Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler] {
        Write-Progress -id 1 -activity "Restoring $dbname to $servername" -percentcomplete $_.Percent -status ([System.String]::Format("Progress: {0} %", $_.Percent))
    }
    $restore.add_PercentComplete($percent)
    $restore.PercentCompleteNotification = 1
    $restore.add_Complete($complete)
    $restore.ReplaceDatabase = $true
    $restore.Database = $dbname
    $restore.Action = "Database"
    $restore.NoRecovery = $false
 
  # take most recent backup set if there are more than one
  $restore.FileNumber = $restore.ReadBackupHeader($server).Rows.Count
 
    Write-Progress -id 1 -activity "Restoring $dbname to $servername" -percentcomplete 0 -status ([System.String]::Format("Progress: {0} %", 0))
    $restore.sqlrestore($servername)
    Write-Progress -id 1 -activity "Restoring $dbname to $servername" -status "Complete" -Completed
 
    Write-Host "Restore complete!" -ForegroundColor Green
 
  exit 0
}
catch {
    $exception = $_.Exception.InnerException
  Write-Host $exception -ForegroundColor Red
  exit 1
}


Второй затрагивает параллельные дествия бекап + восстановления

Кликните здесь для просмотра всего текста
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
$ErrorActionPreference = "Stop" #stop when an error is encountered
#declare variables
$server = "YOURSERVER"
$database = "master"
$query = @"
sp_databases
"@
$querytimeout = 0 #0 means forever, change it as needed
$objectExclude = 'tempdb, northwind, pubs' -split ", " #databases to not backup
$objectNameField = "DATABASE_NAME" #this one is returned by sp_databases
$objectSortExpression = @{Expression={$_[1]}} #DATABASE_SIZE returned by sp_databases, add Ascending=$false to start with the largest
$SleepTimer = 1000 #after X milliseconds, check if the jobs have finished. 1000 is every second.
$MaxResultTime = 7200 #after X seconds, all jobs are killed. 7200 is two hours.
$tasks = @(# taskOrder, taskName, maxThreads, scriptToRun) args0=databaseName. Only one command.
    ,@(1, 'backup', 1, 'sqlcmd -Q "BACKUP DATABASE [$args0] TO DISK=N''C:\${args0}.bak'' WITH INIT" -r0 -b')
    ,@(2, 'store', 1, 'Copy-Item -Path "C:\${args0}.bak" -Destination "\\archive\c$\${args0}.bak"')
    ,@(3, 'delete', 1, 'Remove-Item "C:\${args0}.bak"')
)
$startAtTask = 1 #i.e. if the network was unavailable, you may need to re-run starting from that task
#import modules
Import-Module SqlPs -DisableNameChecking #uncomment for running it directly in a ps command prompt
$error.clear() #clear error generated by last command
#get list of databases and sort
$objects = @((Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $query -querytimeout $queryTimeout) | where {$objectExclude -notcontains $_.$objectNameField} | sort $objectSortExpression )
#environment setup
$RunspacePools = @()
$Jobs = @()
$ISS = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$taskInfo = @{} # key=taskOrder; value=nextTaskOrder
$maxTaskOrder = -1
$objectInfo = @{} # key=taskId; values=each database
$objectInfoArr = @(0) * $objects.length
$output = ""
$errors = ""
$errorCount = @{}
for ($i=0; $i -lt $tasks.length; $i++) {
    $RunspacePools += [runspacefactory]::CreateRunspacePool(1, $tasks[$i][2] <# maxThreads #>, $ISS, $Host)
    $RunspacePools[$i].Open()
    if ($taskInfo.Count -eq 0 -Or -Not $taskInfo.ContainsKey($tasks[$i][0])) { #taskOrder
        $taskInfo.Add($tasks[$i][0], -1)
        if ($tasks[$i][0] -gt $maxTaskOrder) { $maxTaskOrder = $tasks[$i][0] }
    }
    $objectInfo.Add($i, $objectInfoArr.clone())
    $tasks[$i][3] = '$ErrorActionPreference = "Stop"; $args0 = $args[0]; try { $output = ' + $tasks[$i][3] + ' 2>&1 } catch { $err = $_.Exception; $errors = $err.Message; while($err.InnerException) { $err = $err.InnerException; $errors += "|" + $err.Message } } $LastExitCode; $errors | where { $_ } | Out-String; $output | where { $_ } | Out-String'
    $errorCount.Add($i, 0)
}
foreach ($key in @($taskInfo.Keys)) { $taskInfo[$key] = ($taskInfo.Keys | where {$_ -gt $key} | sort | select -First 1) }
#function to create thread and start processing
function CreateThread() {
    param ([string]$objectName, [int]$objectIndex, [int]$taskIndex, [int]$taskOrder, [ref]$Jobs)
    $PowershellThread = [powershell]::Create().AddScript($tasks[$taskIndex][3]) #scriptToRun
    $PowershellThread.AddArgument($objectName) | out-null
    $PowershellThread.RunspacePool = $RunspacePools[$taskIndex]
    $Handle = $PowershellThread.BeginInvoke()
    $Job = "" | select Handle, Thread, ObjectName, ObjectIndex, TaskIndex, TaskOrder, object
    $Job.Handle = $Handle; $Job.Thread = $PowershellThread
    $Job.ObjectName = $objectName; $Job.ObjectIndex = $objectIndex; $Job.TaskIndex = $taskIndex; $Job.TaskOrder = $taskOrder
    $Jobs.value += $Job
}
$ResultTimer = Get-Date
#start processing first task for each database
for ($i=0; $i -lt $objects.length; $i++) {
    $object = $objects[$i].$objectNameField
    $tasks | where {$_[0] -eq $startAtTask} | foreach { CreateThread $object $i ([array]::IndexOf($tasks, $_)) $_[0] ([ref]$Jobs) }
}
while (@($Jobs | where {$_.Handle -ne $Null}).count -gt 0) {
    #update completed jobs and dispose them
    foreach ($Job in @($Jobs | where {$_.Handle -ne $Null -and $_.Handle.IsCompleted -eq $True})) {
        #update status
        $objectInfo[$Job.TaskIndex][$Job.ObjectIndex] = 1
        #get results. 0=LastExitCode (must be 0 or null), 1=$errors (must be empty), 2=$output (may be empty)
        $results = $Job.Thread.EndInvoke($Job.Handle)
        $errors += $results[1] + "`r`n"
        $output += $results[2] + "`r`n"
        if (($results[0] -and $results[0] -ne 0) -or $results[1] -ne "") { $errorCount[$Job.TaskIndex] += 1; $objectInfoArr[$Job.ObjectIndex] = 1; }
        #launch next task
        if ($Job.TaskOrder -lt $maxTaskOrder -and #there are pending tasks
            (@($Jobs | where {$_.TaskOrder -eq $Job.TaskOrder -and #same taskOrder
                                 $_.ObjectName -eq $Job.ObjectName -and #same database
                                 $_.Handle.IsCompleted -eq $False}).count -eq 0) -and #no active threads
            $objectInfoArr[$Job.ObjectIndex] -eq 0) { #no errors so far
            $tasks | where {$_[0] -eq $taskInfo[$Job.TaskOrder]} | foreach { CreateThread $Job.ObjectName $Job.ObjectIndex ([array]::IndexOf($tasks, $_)) $_[0] ([ref]$Jobs) }
        }
        #end thread
        $Job.Thread.Dispose()
        $Job.Thread = $Null
        $Job.Handle = $Null
    }
    #show progress
    for ($i=0; $i -lt $tasks.length; $i++) {
        $inProgress = @($Jobs | where {$_.TaskIndex -eq $i -and $_.Handle.IsCompleted -eq $False}).count
        $failed = $errorCount[$i]
        Write-Progress `
            -Id $i `
            -Activity $tasks[$i][1] `
            -PercentComplete (($objectInfo[$i] | measure-object -Sum).Sum * 100 / $objects.length) `
            -Status "$inProgress in progress, $failed failed"
    }
    #exit on timeout
    $currentTime = Get-Date
    if (($currentTime - $ResultTimer).totalseconds -gt $MaxResultTime) {
        Write-Error "Child script appears to be frozen, try increasing MaxResultTime"
        break
    }
    #sleep
    Start-Sleep -Milliseconds $SleepTimer
}
#dispose thread pools
for ($i=0; $i -lt $tasks.length; $i++) {
    $RunspacePools[$i].Close() | Out-Null
    $RunspacePools[$i].Dispose() | Out-Null
}
if (($errors -replace "`r`n", "") -ne "") { throw $errors + " " + $output } else { $output }


Я сначала думал их подкоректировать под себя но не тут то было, у меня то ведь ображения к 2м. разным инстансам

(честно признаюсь от куда я их взял 1 .. Гитхаб) 2... Тык
Как-то так , я понимаю что материал комбинированный, но ваш опыт для меня важен..
с ув. Спасибо
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.01.2018, 16:13
Ответы с готовыми решениями:

Восстановление баз на резервном сервере SQL Server 2012
Добрый день, уважаемые форумчане. У меня возникла необходимость развернуть на резервном сервере копию crm-системы, которая используется у...

Восстановление баз
Здраствуйте!При восстановлении базы выдается ошибка: индекс находился вне границ массива. База была сделана на sql server 2005 , а...

Восстановление баз данных
При попытке восстановления базы данных выдается такое сообщение(рис).Захожу как администратор есть полный доступ.Причем восстанавливаю...

3
2 / 2 / 1
Регистрация: 28.02.2018
Сообщений: 2
28.02.2018, 14:00
Добрый день,

Очень рекомендую обратить ваш взор на модуль для администраторов БД - dbatools там есть более 380 различных командлетов облегчающих жизнь, плюс есть команды с отображением прогресса восстановления БД.

С уважением
Олег
1
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,148
Записей в блоге: 3
28.02.2018, 14:49
для бэкапа попробуйте бесплатную утилиту packDB (был обзор на хабре + мануал на сайте)
больше года использую - очень и очень нравится
0
2 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 185
06.03.2018, 15:59  [ТС]
Цитата Сообщение от Labradozavr Посмотреть сообщение
ваш взор на модуль для администраторов БД - dbatools
вот это подгон )))

буду смотреть. по предварительной инфе которую я посмотрел , это просто шедевр!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.03.2018, 15:59
Помогаю со студенческими работами здесь

Восстановление Лотусовых Баз
После сбоя двух(!) жёстких дисков в RAID5 на сервере образовалась куча NSF файлов с размером в 0 байт. Можно ли каким-то образом...

Перенос баз из Sql 2000 и 2005 в Sql 2012
Добрый день, возникла необходимость переехать на новый сервер SQL, но столкнулся с трудностями. Как правильно перетащить базу? ...

Восстановление баз с диска, развалился RAID
Позавчера произошло небольшое чп. Последствия которого разгребаю в выходные. История: Стоял когда-то сервак 1С: МП: Asus M5A97 EVO...

SQL SERVER Windows PowerShell
Добрый вечер! устанавливаю SQL SERVER 2008. всё делаю как написано здесь. при установке не хочет ставиться Windows PowerShell. подскажите...

PowerShell посчитать по строкам из файла и циклить на T-SQL
Звучит тема страшно на самом деле не хватает чуть чуть опыта, может кто подскажет. Есть файл, в нем логины подряд 1 логин=1 строка ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru