none
PowerShell. Скрипт бэкапа - нужна помощь

    Вопрос

  • Нужна помощь в написании скрипта бэкапа.

    Делать он должен следующее:

    проверять наличие папки для бэкапа;

    проверять наличие свободного места на жестком диске;

    архивировать файлы внешним архиватором;

    хранить в папке бэкапы последнего дня последних двух месяцев и за вчераний день, все остальное удалять;

    любой отчет об ошибке отправлять письмом. 

    Заранее спасибо.

     

    11 августа 2008 г. 11:43

Ответы

  •  Andrey_tka написано:

    не работает конкретно вот этот кусок:

     

    dir $dest | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

     

    причем, если запускать эту часть отдельно, выделяя ее (я использую Power GUI), то удаление файлов происходит.

    В связке же со всем кодом удаления не происходит, а все остальные действия выполняются успешно.

    ваша проблема вот в чём:

    Code Snippet

    error_mail backupsucsess archive; return 1

     

     

    видите, в конце стоит Return 1? Если бакуп выполниолся, то вызывается функция отправки письма об успешном бакупе и далее выполняется Return, который блокирует выполнение кода в пределах текущей функции, а в вашем случае это весь скрипт. Поэтому не используйте оператор Return без особой на то надобности, тем более вы этот Return никак не используете. Есть смысл заменить его на тот же exit, который я использую. И будет вам счастье.

     

    Enjoy.

    20 августа 2008 г. 17:55

Все ответы

  •  

    Вам нужна помощь в написании или, чтобы мы за вас его написали?
    12 августа 2008 г. 7:42
  •  

    Check for Files and Folders
    http://www.microsoft.com/technet/scriptcenter/resources/begin/ss0707.mspx#EGD
    Powershell script to check free disk spaces for servers
    http://www.myitforum.com/articles/40/view.asp?id=9651

    И т.д. в первых выдачах гугла. Возможно, автор очень занятой человек и не может тратить свое драгоценное время на самостоятельный поиск .

    12 августа 2008 г. 9:08
  •  Andrey_tka написано:

    Нужна помощь в написании скрипта бэкапа.

    Делать он должен следующее:

    проверять наличие папки для бэкапа;

    проверять наличие свободного места на жестком диске;

    архивировать файлы внешним архиватором;

    хранить в папке бэкапы последнего дня последних двух месяцев и за вчераний день, все остальное удалять;

    любой отчет об ошибке отправлять письмом. 

    Заранее спасибо.

     

    вот жеж, где лентяй, а?

     

    Вобщем, подпилил свой скрипт бэкапа баз 1С встроенным ntbackup. Скрипт написан под мои условия, поэтому перед бездумным копированием разберите на бумаге работу скрипта и внесите необходимые изменения, как пути к папкам и файлам, адрес почты и размер свободного места на диске, при котором разрешается делать бэкап. Для минимального размера диска взял 5ГБ. Если свободного места меньше 5ГБ, то бэкап выполняться не будет, а только отправлено уведомление на почту, что места нету.

     

    Code Snippet

    # создание, если нету, конечной и временных папок для бэкапа

    new-item -path F:\BaseBackups\1C -itemtype directory -ErrorAction SilentlyContinue

    new-item -path F:\BackupTemp -itemtype directory -ErrorAction SilentlyContinue

    if (test-path F:\BaseBackups\1C) {

    # создание переменной для пути к логам NTBackup иудаление старых логов

    $log=$env:userprofile + "\Local Settings\Application Data\Microsoft\Windows NT\NTBackup\data"

    remove-item $log\*.log -force

    # секция обработки даты

    $PrevMonth = (Get-Date -Month (Get-Date).month -Day 1).adddays(-1)

    $PrevMonth = (Get-Date) - $PrevMonth

    $2PrevMonth = (Get-Date -Month ((Get-Date).month -1) -Day 1).adddays(-1)

    $2PrevMonth = (Get-Date) - $2PrevMonth

    # удаление файлов старше вчерашнего дня, кроме тех, которые были созданы в последний день прошлого

    # и позапрошлого месяцев.

    dir F:\BaseBackups\1C | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

    # секция подсчёта свободного места

    $FreeSpace = gwmi Win32_LogicalDisk | Where {$_.DeviceId -Eq "F:"}

    if (-not ($FreeSpace.FreeSpace /1GB -ge 5)) {send-smtpmail -to example@domain.com -body "На диске F: не хватает места для записи бэкапа." -subject "Нет места на диске"

    exit}

    # секция внешнего архиватора NTBackup с проверкой папки, куда будет писаться архив

    if (test-path F:\BackupTemp) {

    C:\WINDOWS\system32\ntbackup.exe backup "@F:\WorkSpace\Jobs\1CDayly.bks" /a /d "Set created 27.11.2007 at 14:34" /v:no /r:no /rs:no /hc:off /m normal /j "BaseEveryDay" /l:s /f "F:\BackupTemp\1C_$date.bkf" | out-null}

    else {send-smtpmail -to example@domain.com -body "Не удалось создать временную папку для архива" -subject "Ошибка создания папки"

    exit

    }

    }

    else {send-smtpmail -to example@domain.com -body "Не удалось создать целевую папку для архива" -subject "Ошибка создания папки"}

    # парсер журнала Application на предмет ошибок ntbackup. При его использовании убрать комментарии

    #If (Get-EventLog -LogName Application -Newest 5 | Where-Object {$_.source -match "ntbackup|VSS"} | Where-Object {$_.message -match "Warnings or errors were encountered|error"})

    #{send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Error"

    #exit}

    #else {

    $logfile=[string]::join("`n",( get-content $log\*.log))

    # парсер лога NTBackup

    if ((gc $logfile) -contains "error|aborted|warning") {send-smtpmail -to example@domain.com -body "Во время создания архива были констатированы ошибки" -subject "Backup Internal Error"

    exit}

    if ((gi F:\BackupTemp\1C_$date.bkf -ea 0).length -le 2kb) {send-smtpmail -to example@domain.com -body "По причине ошибки Volume Shadow Copy архив не был сощдан" -subject "VSS Error"

    exit}

    copy-item F:\BackupTemp\1C_$date.bkf -destination F:\BaseBackups\1C

    # проверка копирования файла. Если первая попытка закончилась неудачно, то

    # делаем повторную попытку. Если снова копирование обрывается - констатируем отсутствие бэкапа.

    if (-not ($?)) {copy-item F:\BackupTemp\1C_$date.bkf -destination F:\BaseBackups\1C

    if (-not ($?)) {send-smtpmail -to example@domain.com -body "Не удалось завершить локальное копирование файла" -subject "Local Copy Error"

    exit

    }

    }

    # копирование архива в сеть.

    copy-item F:\BackupTemp\1C_$date.bkf -destination \\BackupServer\BackupShare\1C

    if (-not ($?)) {copy-item F:\BackupTemp\1C_$date.bkf -destination \\BackupServer\BackupShare\1C

    if (-not ($?)) {send-smtpmail -to example@domain.com -body "Не удалось завершить сетевое копирование файла" -subject "Network Copy Error"

    exit

    }

    }

    # последние проверки и удаление временных файлов.

    if ((test-path F:\BaseBackups\1C\1C_$date.bkf) -and (Test-Path \\BackupServer\BackupShare\1C\1C_$date.bkf)) {

    remove-item F:\BackupTemp\1C_$date.bkf -force

    send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Success"}

    else

    {send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Error"}

     

     

    Для работы почты необходимо заиметь функцию send-smtpmail, которую можно взять тут:
    http://xaegr.wordpress.com/2008/01/24/send-smtpmailps1/
    Ну и отказ от ответственности:
    This posting is provided "AS IS" with no warranties, and confers no rights.

    12 августа 2008 г. 11:04
  • Отлично, а я уж думал потом освобожусь напишу если ни кто не решится.

    12 августа 2008 г. 21:34
  • Еще один вопрос: как в данной строке прописать запуск архиватора не используя путь?

    c:\windows\RAR a -r $temp1\$date $path1\*.*| out-null

     

     

    чтоб получилось подобие этого

    {

    RAR a -r $temp1\$date $path1\*.*| out-null

    }
    20 августа 2008 г. 11:00
  •  

     

     

    # секция обработки даты

    $PrevMonth = (Get-Date -Month (Get-Date).month -Day 1).adddays(-1)

    $PrevMonth = (Get-Date) - $PrevMonth

    $2PrevMonth = (Get-Date -Month ((Get-Date).month -1) -Day 1).adddays(-1)

    $2PrevMonth = (Get-Date) - $2PrevMonth

    # удаление файлов старше вчерашнего дня, кроме тех, которые были созданы в последний день прошлого

    # и позапрошлого месяцев.

    dir dir F:\BaseBackups\1C | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

     
    Можно ли эту часть кода разместить в низу? Чтоб файлы удалялись в самую последнюю очередь?
     
    Пробовал это сделать, но почему то без успешно.
     
     
    20 августа 2008 г. 11:14
  • Да, можно вот так:

    Code Snippet

    # создание, если нету, конечной и временных папок для бэкапа

    new-item -path F:\BaseBackups\1C -itemtype directory -ErrorAction SilentlyContinue

    new-item -path F:\BackupTemp -itemtype directory -ErrorAction SilentlyContinue

    if (test-path F:\BaseBackups\1C) {

    # создание переменной для пути к логам NTBackup иудаление старых логов

    $log=$env:userprofile + "\Local Settings\Application Data\Microsoft\Windows NT\NTBackup\data"

    remove-item $log\*.log -force

    # секция подсчёта свободного места

    $FreeSpace = gwmi Win32_LogicalDisk | Where {$_.DeviceId -Eq "F:"}

    if (-not ($FreeSpace.FreeSpace /1GB -ge 5)) {send-smtpmail -to example@domain.com -body "На диске F: не хватает места для записи бэкапа." -subject "Нет места на диске"

    exit}

    # секция внешнего архиватора NTBackup с проверкой папки, куда будет писаться архив

    if (test-path F:\BackupTemp) {

    C:\WINDOWS\system32\ntbackup.exe backup "@F:\WorkSpace\Jobs\1CDayly.bks" /a /d "Set created 27.11.2007 at 14:34" /v:no /r:no /rs:no /hc:off /m normal /j "BaseEveryDay" /l:s /f "F:\BackupTemp\1C_$date.bkf" | out-null}

    else {send-smtpmail -to example@domain.com -body "Не удалось создать временную папку для архива" -subject "Ошибка создания папки"

    exit

    }

    }

    else {send-smtpmail -to example@domain.com -body "Не удалось создать целевую папку для архива" -subject "Ошибка создания папки"}

    # парсер журнала Application на предмет ошибок ntbackup. При его использовании убрать комментарии

    #If (Get-EventLog -LogName Application -Newest 5 | Where-Object {$_.source -match "ntbackup|VSS"} | Where-Object {$_.message -match "Warnings or errors were encountered|error"})

    #{send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Error"

    #exit}

    #else {

    $logfile=[string]::join("`n",( get-content $log\*.log))

    # парсер лога NTBackup

    if ((gc $logfile) -contains "error|aborted|warning") {send-smtpmail -to example@domain.com -body "Во время создания архива были констатированы ошибки" -subject "Backup Internal Error"

    exit}

    if ((gi F:\BackupTemp\1C_$date.bkf -ea 0).length -le 2kb) {send-smtpmail -to example@domain.com -body "По причине ошибки Volume Shadow Copy архив не был сощдан" -subject "VSS Error"

    exit}

    copy-item F:\BackupTemp\1C_$date.bkf -destination F:\BaseBackups\1C

    # проверка копирования файла. Если первая попытка закончилась неудачно, то

    # делаем повторную попытку. Если снова копирование обрывается - констатируем отсутствие бэкапа.

    if (-not ($?)) {copy-item F:\BackupTemp\1C_$date.bkf -destination F:\BaseBackups\1C

    if (-not ($?)) {send-smtpmail -to example@domain.com -body "Не удалось завершить локальное копирование файла" -subject "Local Copy Error"

    exit

    }

    }

    # копирование архива в сеть.

    copy-item F:\BackupTemp\1C_$date.bkf -destination \\BackupServer\BackupShare\1C

    if (-not ($?)) {copy-item F:\BackupTemp\1C_$date.bkf -destination \\BackupServer\BackupShare\1C

    if (-not ($?)) {send-smtpmail -to example@domain.com -body "Не удалось завершить сетевое копирование файла" -subject "Network Copy Error"

    exit

    }

    }

    # последние проверки и удаление временных файлов.

    if ((test-path F:\BaseBackups\1C\1C_$date.bkf) -and (Test-Path \\BackupServer\BackupShare\1C\1C_$date.bkf)) {

    remove-item F:\BackupTemp\1C_$date.bkf -force

    send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Success"}

    else

    {send-smtpmail -to example@domain.com -body $logfile -subject "1C Backup Error"}

    # секция обработки даты

    $PrevMonth = (Get-Date -Month (Get-Date).month -Day 1).adddays(-1)

    $PrevMonth = (Get-Date) - $PrevMonth

    $2PrevMonth = (Get-Date -Month ((Get-Date).month -1) -Day 1).adddays(-1)

    $2PrevMonth = (Get-Date) - $2PrevMonth

    # удаление файлов старше вчерашнего дня, кроме тех, которые были созданы в последний день прошлого

    # и позапрошлого месяцев.

    dir F:\BaseBackups\1C | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

     

    Но учтите, что если по каким либо причинам бэкап не выполнился (не прошла любая из проверок), то ротации архивов не произойдёт, а только при полностью успешном завершении бэкапа. И можно поподробнее, что именно у вас не вышло?

    20 августа 2008 г. 11:56
  • Вышеуказанный вариант я пробовал, но все равно не происходит удаления устаревших файлов.

    Само выполнения скрипта целиком идет и завершается без ошибок.

     

    20 августа 2008 г. 12:08
  •  Andrey_tka написано:

    Еще один вопрос: как в данной строке прописать запуск архиватора не используя путь?

    c:\windows\RAR a -r $temp1\$date $path1\*.*| out-null

     

     

    чтоб получилось подобие этого

    {

    RAR a -r $temp1\$date $path1\*.*| out-null

    }

    для этого нужно сделать:

    Code Snippet

    set path="C:\Windows"

    20 августа 2008 г. 12:13
  •  Andrey_tka написано:

    Вышеуказанный вариант я пробовал, но все равно не происходит удаления устаревших файлов.

    Само выполнения скрипта целиком идет и завершается без ошибок.

     

    прошу прощения, там дважды DIR написан. сотрите одну команду DIR из строки удаления.

    з.ы. пофиксил ошибку.

    20 августа 2008 г. 12:16
  • не помогло.

    вот код целиком - посмотрите что не так.

    #Creation of variables##################

    $date=Get-Date -UFormat %Y_%m_%d

    $Gb=5 # Limit of an empty seat on a hard disk

    ## Set e-mail vars[:#]#####################

    $sender = " andrey_tka@bast.ru"

    $recipient = " andrey_tka@bast.ru"

    $subj = "Attention please!"

    $body = "Alarm! Script not work!"

    $server = "svr002.bast.ru"

    ##########################################

    #####create directory#####################

    set path="c:\WINDOWS"

    $path1="c:\BaseBackups\1C\"

    $temp1="c:\BackupTemp\"

    $dest1="C:\BackupServer\BackupShare\1C\"

    #########################################

    $client = new-object System.Net.Mail.SmtpClient $server

    $client = new-object System.Net.Mail.SmtpClient $server

    function error_mail { #Send warning mail on oit@bast.ru

    param($reason, $who)

    switch ($reason) {

    freespace {

    $subj="$Shortage of an empty seat"

    $body="$date - $who dont create"

    }

    ntbackup {

    $subj="It was not possible to make reserve copying"

    $body="$date - #who dont create"

    }

    copyerror {

    $subj="Mistake of copying of archive"

    $body="$date - $who dont copy"

    }

    backupsucsess {

    $subj="Creation of archive is successfully completed"

    $body="$date - $who create sucsess"

    }

    backuperror {

    $subj="Creation of archive has passed with a mistake"

    $body="$date - $who create error"

    }

    }

    $msg = new-object System.Net.Mail.MailMessage $sender, $recipient, $subj, $body

    $client.Send($msg)

    }

     

    20 августа 2008 г. 12:25
  •  

    new-item -path $path1 -itemtype directory -ErrorAction SilentlyContinue # Creation final and temp folders for archive

    new-item -path $temp1 -itemtype directory -ErrorAction SilentlyContinue

     

    $FreeSpace = gwmi Win32_LogicalDisk | Where {$_.DeviceId -Eq "C:"} # Section of calculation of an empty seat

    if (-not ($FreeSpace.FreeSpace /1GB -ge $Gb)) {error_mail freespace archive; return 1}

    if (test-path $temp1)

    {

    RAR a -r $temp1\$date $path1\*.*| out-null}

    else {error_mail ntbackup archive; return 1}

    copy-item $temp1\*.rar -destination $dest1

     

     

    if (-not ($?)) {copy-item $temp1\*.rar -destination $dest1 if (-not ($?)){error_mail copyerror archive; return 1}

    }

     

    if ((test-path $temp1\*.rar) -and (Test-Path $dest1\*.rar)) # Last checks and removal of time files

    {

    remove-item $temp1\*.rar -force

    error_mail backupsucsess archive; return 1}

    else

    {error_mail backuperror archive; return 1}

    #Section of processing of date

    # секция обработки даты

    $PrevMonth = (Get-Date -Month (Get-Date).month -Day 1).adddays(-1)

    $PrevMonth = (Get-Date) - $PrevMonth

    $2PrevMonth = (Get-Date -Month ((Get-Date).month -1) -Day 1).adddays(-1)

    $2PrevMonth = (Get-Date) - $2PrevMonth

    # удаление файлов старше вчерашнего дня, кроме тех, которые были созданы в последний день прошлого

    # и позапрошлого месяцев.

    dir $dest | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

    20 августа 2008 г. 12:26
  •  

    расскажите конкретно, какие куски кода у вас не работают?
    20 августа 2008 г. 12:53
  • не работает конкретно вот этот кусок:

     

    dir $dest | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

     

    причем, если запускать эту часть отдельно, выделяя ее (я использую Power GUI), то удаление файлов происходит.

    В связке же со всем кодом удаления не происходит, а все остальные действия выполняются успешно.

    20 августа 2008 г. 13:05
  •  Andrey_tka написано:

    не работает конкретно вот этот кусок:

     

    dir $dest | where {$_.lastwritetime -le (Get-Date).AddDays(-1) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$PrevMonth.Days)) -and ($_.lastwritetime -ne (Get-Date).AddDays(-$2PrevMonth.Days))} | del -force

     

    причем, если запускать эту часть отдельно, выделяя ее (я использую Power GUI), то удаление файлов происходит.

    В связке же со всем кодом удаления не происходит, а все остальные действия выполняются успешно.

    ваша проблема вот в чём:

    Code Snippet

    error_mail backupsucsess archive; return 1

     

     

    видите, в конце стоит Return 1? Если бакуп выполниолся, то вызывается функция отправки письма об успешном бакупе и далее выполняется Return, который блокирует выполнение кода в пределах текущей функции, а в вашем случае это весь скрипт. Поэтому не используйте оператор Return без особой на то надобности, тем более вы этот Return никак не используете. Есть смысл заменить его на тот же exit, который я использую. И будет вам счастье.

     

    Enjoy.

    20 августа 2008 г. 17:55
  • Все работает. Огромное спасибо.

    Мой первый скрипт можно внедрять =)

    21 августа 2008 г. 5:18
  •  Andrey_tka написано:

    Все работает. Огромное спасибо.

    Мой первый скрипт можно внедрять =)

    только мелкие ошибки пофиксите, как тут:

     

    Code Snippet

    $body="$date - #who dont create"

     

     

    уберите решётку и поставьте знак доллара.
    21 августа 2008 г. 5:35
  • не  совсем корректна обработка дат, правильнее будет :
    # секция обработки даты
                                                                                 # последняя дата прошлого месяца
    $PrevMonth = ( Get-Date -Year ( Get-Date).year  -Month ( Get-Date ) .month -Day 1).adddays(-1)

                                                                                 # последняя дата 2 месяца назад
    $2PrevMonth = ( Get-Date -Year $PrevMonth.year -Month $PrevMonth .month -Day 1).adddays(-1)
    27 января 2010 г. 14:24
  • Коллеги подскажите есть аналогичное задание.

    1. Необходимо чтобы в папке c:\temp лежали архивы за текущий месяц.

    2. В конце месяца или в начале следующего из всех архивов оставались бы архивы только за 1 число месяца (прошедшего соответсвенно) если такого архива нет, то ближайший к нему с обеих сторон.

    3. сейчас есть архивы в этой папке аж за 2012 год.

    вот как бы мне их разформировать согласно задаче, можно даже создавать папки скажем с именем месяца и туда складывать именно 1 архив. вот не знаю

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

    16 апреля 2014 г. 7:16