Лучший отвечающий
PowerShell Анализ объем дискового пространства для резервных копий БД.

Вопрос
-
Здравствуйте.
Поставили задачу написать скрипт, который будет определять необходимое дисковое пространство для резервных копий баз данных. В идеале он должен немного прогнозировать рост базы за определенное время, скажем, за 24 часа, на сколько база выростет и какой при этом потребуется объем дискового пространства. Расчет должен идти в совокупности со всех серверов СУБД.
Базы данных крутятся на MS SQL Server 2008 R2 и MS SQL Server 2012.
Бэкапы выполняются средствами Symantec Backup Exec 2012
Каким образом лучше оформить скрипт? Дело в том, что никогда не использовал ПОШ для работы с MS SQL сервером и Symantec'ом. По какому алгоритму он должен действовать?.
Хотелось бы наглядно увидеть принцип построения самого скрипта для данной задачи.
Заранее всем спасибо!
16 января 2018 г. 12:39
Ответы
-
Разобрался в чем была проблема.
В переменную $sum попадает пробел и я ума не приложу почему -replace " ", "" не срабатывает
Собственно вот рабочий код с "костылем":
$servers = "server1.com", "server2.com", "server3.com" $exportPath = "C:\export\export.txt" if ((Test-Path $exportPath) -eq $false) { Add-Content -Path $exportPath -Value "Date;Server;Size" } Foreach ($server in $servers) { Invoke-Command -ComputerName $server -ScriptBlock { $folderSize = Get-ChildItem "D:\DB" -Recurse | measure -Property length -Sum; $_size = ("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",","." $size = $_size.Split("")[0] + $_size.Split("")[1] + $_size.Split("")[2] + $_size.Split("")[3] $date = Get-Date -Format d $output = [string]$date + ";" + $server + ";" + $size Write-Output -InputObject $output } | Add-Content -Path $exportPath } $csv = Import-Csv $exportPath -Delimiter ";" $csv | ? {$_.Date -eq (Get-Date -Format d) -and $_.Server -ne "SUM"} | Foreach { $sum += [double]$_.Size } $outputSum = $(Get-Date -Format d) + ";SUM;" + $sum Add-Content -Path $exportPath -Value $outputSum
Не забудьте указать ваши сервера и путь до БД
- Помечено в качестве ответа KazunEditor 22 января 2018 г. 5:45
17 января 2018 г. 14:39
Все ответы
-
Написать скрипт - не проблема.
$servers = "server1.com", "server2.com", "server3.com" $exportPath = "C:\export\export.txt" Foreach ($server in $servers) { Invoke-Command -ComputerName $server -ScriptBlock { (Get-ChildItem -Path D:\DB | measure -Property Length -Sum).Sum / 1024Mb } | Add-Content -Path $exportPath } $exportContent = Get-Content $exportPath for ($i = 0; $i -le ($exportContent.length - 1); $i++) { $sum += [int]$exportContent[$i] } Write-Host $sum
Но кто как не вы должен проанализировать процент роста баз? Это же индивидуально :D
PS Скрипт выше получает общий объем баз со всех серверов.
- Изменено Sergey Ya 16 января 2018 г. 13:09
16 января 2018 г. 13:06 -
Визуально и статично это можно сделать. Только это нужно делать в процессе работы скрипта: что бы он сам анализировал рост одной базы или общий рост всех баз. Каким то образом возможно это оформить? Не хочется каждый раз менять в скрипте константы.16 января 2018 г. 13:21
-
Если я правильно понял, то вам нужна статистика за сутки с интервалом , предположим, 1 час?
11:00 - 1gb
12:00 - 1.3gb
13:00 - 2gb
и тд
Так?
16 января 2018 г. 13:25 -
(Get-ChildItem -Path D:\DB | measure -Property Length -Sum).Sum / 1024Mb
Свойство Length у меня почему то пустое выдается.
17 января 2018 г. 7:20 -
Можно даже интервал 24 часа, ровно сутки, не обязательно почасовая аналитика.
грубо говоря:
17.01.2018 - 1GB
18.01.2018 - 2GB
и т.д.
17 января 2018 г. 7:22 -
Немного поправил начальный скрипт. Старый вариант считал только файлы в папке, но не брал в расчет вложенные папки с файлами.
Вот рабочий вариант:$servers = "server1.com", "server2.com", "server3.com" $exportPath = "C:\export\export.txt" if ((Test-Path $exportPath) -eq $false) { Add-Content -Path $exportPath -Value "Date;Server;Size" } Foreach ($server in $servers) { Invoke-Command -ComputerName $server -ScriptBlock { $folderSize = Get-ChildItem "D:\DB" -Recurse | measure -Property length -Sum; $size = ("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",","." $date = Get-Date -Format d $output = [string]$date + ";" + $server + ";" + $size Write-Output -InputObject $output } | Add-Content -Path $exportPath } $csv = Import-Csv $exportPath -Delimiter ";" $csv | ? {$_.Date -eq (Get-Date -Format d) -and $_.Server -ne "SUM"} | Foreach { $sum += [double]$_.Size } $outputSum = $(Get-Date -Format d) + ";SUM;" + $sum Add-Content -Path $exportPath -Value $outputSum
Вывод с датой, как вы и хотели. Плюс после каждого запуска идет сложение с выводом текущей даты, на выходе мы получаем строчку в логе примерно в таком формате 17.01.2018;SUM;1024. То есть это сумма значений за 17,01,2018.
Это первая часть - сбор данных.
Осталось проанализировать лог, тут нужно немного подумать :D
17 января 2018 г. 9:12 -
Ругается на некоректный формат:
Cannot convert value "377�451.82" to type "System.Double". Error: "Input string was not in a correct format."
At line:20 char:5
+ $sum += [double]$_.Size
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToDoubleOrSingle17 января 2018 г. 9:48 -
Ругается на некоректный формат:
Cannot convert value "377�451.82" to type "System.Double". Error: "Input string was not in a correct format."
At line:20 char:5
+ $sum += [double]$_.Size
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToDoubleOrSingleСтранно, у меня работает..
Попробуйте заменить
$size = ("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",","."
На
$size = "{0:N2}" -f $($FolderSize.Sum/1MB)
Если это не поможет, то [double] поменяйте на [int] в этой строке $sum += [double]$_.Size
Проблема в типе данных, что мы получаем из импорта. По умолчанию он [string], следовательно арифметические операции мы не сможем совершать, поэтому нужно конвертировать
Можете дать вывод лога? У вас что-то с форматом, нужно понять что это такое �
Cannot convert value "377�451.82" to type "System.Double"- Изменено Sergey Ya 17 января 2018 г. 10:21
17 января 2018 г. 10:14 -
Часть вторая - обработка лога :D
$csv = Import-Csv $exportPath -Delimiter ";" | ? {$_.Server -eq "SUM"} for ($i = 0; $i -le ($csv.Count - 1); $i++) { if ($i -ne 0) { $sum += [double]$csv.Size[$i] - [double]$csv.Size[$i - 1] } } $result = $sum / $csv.Length
Поясняю:
Каждый раз мы получаем разницу (сегодня минус вчера = разница), далее разницу делим на количество элементов и получаем среднее значение на которое растет наша БД.
17 января 2018 г. 10:18 -
Изменил строку как Вы сказали на:
$size = {0:N2} -f $($FolderSize.Sum/1MB)
Результат тот же.
Так же меня [double] на [int] и [string] результата не дало, ошибка таже выходит.
Где можно вывод лога посмотреть? (Я еще не совсем силен в PowerShell))))
17 января 2018 г. 14:02 -
Изменил строку как Вы сказали на:
$size = {0:N2} -f $($FolderSize.Sum/1MB)
Результат тот же.
Так же меня [double] на [int] и [string] результата не дало, ошибка таже выходит.
Где можно вывод лога посмотреть? (Я еще не совсем силен в PowerShell))))
В папке куда вы сливаете лог. В моем примере это
$exportPath = "C:\export\export.txt"
Сдается мне, что там пробел стоит. Если так, то замените строку
$size = ("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",","."
на
$size = (("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",",".") -replace " ", ""
Для понимания:
Чтобы избавится от ошибки нужно исключить из лога все посторонние символы (включая пробелы), в противном случае не получится преобразовать строку в число.
- Изменено Sergey Ya 17 января 2018 г. 14:16
17 января 2018 г. 14:13 -
Разобрался в чем была проблема.
В переменную $sum попадает пробел и я ума не приложу почему -replace " ", "" не срабатывает
Собственно вот рабочий код с "костылем":
$servers = "server1.com", "server2.com", "server3.com" $exportPath = "C:\export\export.txt" if ((Test-Path $exportPath) -eq $false) { Add-Content -Path $exportPath -Value "Date;Server;Size" } Foreach ($server in $servers) { Invoke-Command -ComputerName $server -ScriptBlock { $folderSize = Get-ChildItem "D:\DB" -Recurse | measure -Property length -Sum; $_size = ("{0:N2}" -f $($FolderSize.Sum/1MB)) -replace ",","." $size = $_size.Split("")[0] + $_size.Split("")[1] + $_size.Split("")[2] + $_size.Split("")[3] $date = Get-Date -Format d $output = [string]$date + ";" + $server + ";" + $size Write-Output -InputObject $output } | Add-Content -Path $exportPath } $csv = Import-Csv $exportPath -Delimiter ";" $csv | ? {$_.Date -eq (Get-Date -Format d) -and $_.Server -ne "SUM"} | Foreach { $sum += [double]$_.Size } $outputSum = $(Get-Date -Format d) + ";SUM;" + $sum Add-Content -Path $exportPath -Value $outputSum
Не забудьте указать ваши сервера и путь до БД
- Помечено в качестве ответа KazunEditor 22 января 2018 г. 5:45
17 января 2018 г. 14:39 -
to Sergey: пробел может быть не пробелом, а например табом или еще чем, в таких случаях хорошо работают '\s*'
плюс если вы хотите убрать символ(ы) можно использовать -replace '\s*' без второй компоненты
The opinion expressed by me is not an official position of Microsoft
17 января 2018 г. 16:19Модератор -
to Sergey: пробел может быть не пробелом, а например табом или еще чем, в таких случаях хорошо работают '\s*'
плюс если вы хотите убрать символ(ы) можно использовать -replace '\s*' без второй компоненты
The opinion expressed by me is not an official position of Microsoft
Спасибо огромное, не знал.
17 января 2018 г. 17:02