Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] скрипт для выявления невыполненных ежедневных бэкапов (http://forum.oszone.net/showthread.php?t=242390)

rudimko 10-09-2012 20:54 1986307

[решено] скрипт для выявления невыполненных ежедневных бэкапов
 
Друзья, помогите решить проблему, не могу сделать правильный вывод данных. Как вывести только названия тех папок, где не существуют файлы, которые будут заданы в условие (к примеру $_.LastWriteTime не являются вчерашней датой). Заранее спасибо.

Kazun 11-09-2012 00:00 1986407

Как пример,найти все папки в которых нет файлов,измененных сегодня:
Код:

Get-ChildItem D:\Temp -Recurse | Where {$_.PsIsContainer} |
            Where {!($_.GetFiles()| Where {$_.LastWriteTime -ge [datetime]::Today})} | Format-Table FullName

Для версии V3 немного покороче:
Код:

Get-ChildItem D:\Temp -Recurse -Directory |
            Where {!($_.GetFiles().LastWriteTime -ge [datetime]::Today)} | Format-Table FullName


rudimko 11-09-2012 10:48 1986543

Спасибо, все отлично отработало. Еще малюсенький вопрос: Я делаю вывод в таблицу "Format-Table -auto FullName, Length, LastWriteTime", а как мне вывести "Length" в мегабайтах, а не в байтах?

Kazun 11-09-2012 11:05 1986546

Format-Table -auto FullName, @{n="Length(MB)";e={"{0:N2}" -f ($_.Length/1mb)}}, LastWriteTime

rudimko 11-09-2012 13:19 1986619

Здорово! И последний вопрос:
Вот код:
Код:

$Days = "-1"
$Date = Get-Date
$Yesterday = Get-Date $Date.AddDays($Days) -Format "dd/MM/yyyy"
$YesterdayF = Get-Date $Yesterday -Format "yyyyMMdd"
$Path = "C:\test"

$NotExist = Get-ChildItem -Path $Path -Recurse | Where-Object {$_.PsIsContainer} | Where-Object {!($_.GetFiles()| Where-Object {$_.LastWriteTime -lt $Yesterday})} | Format-Table FullName, LastWriteTime
if ($NotExist -gt $null) {
Write-Output $NotExist
}
else {
Write-Host "Файлы за $Yesterday"
Write-Host ""
}

$Exist = Get-ChildItem -Path $Path -Recurse -Include "*.*" | Where-Object {$_.FullName -like "*$YesterdayF*"} | Format-Table -auto FullName, @{n="Length(Mb)";e={"{0:N2}" -f ($_.Length/1mb)}}, LastWriteTime
if ($Exist -gt $null) {
Write-Host "Каталоги с не обновленными файлами"
Write-Output $Exist
}

Хочу вывести результат скрипта в сообщение, т.е. приравнять результат к $Body, никак не получается. Прошу помочь с этим справиться:

Код:

$EmailFrom = "test@test.ru"
$EmailTo = "test@test.ru>"
$Subject = "Заголовок"
$Body = "СООБЩЕНИЕ"
$SMTPServer = "mail.test.ru"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("LOGIN", "PASS");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

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

Kazun 11-09-2012 15:11 1986697

Для начала разберитесь с логикой, а то тут странно получается:
1) Проверяем каталоги на условие
2) Если удовлетворяет условию, выводим каталоги
3) Не удовлетворяет условию,выводим -"Файлы за $Yesterday"
4) Получаем список файлов в пути,которых есть $YesterdayF
5) Если удовлетворяет условию,выводим "Каталоги с не обновленными файлами" и файлы

Зачем дважды гонять не быструю операцию,как Get-ChildItem -Path $Path -Recurse,проще сохранить результат один раз в переменную и в дальнейшем уже использовать.

rudimko 11-09-2012 15:27 1986706

Так как с PowerShell знаком только третий день, то мне самому сложно понять как это сделать ;)
Когда сохраняю весь результат в переменную и подставляю ее в $Body, то тело письма содержит весь код, а не результат. Как сделать правильно?

Kazun 11-09-2012 15:40 1986720

Будь по-вашему.

Код:

$NotExist = Get-ChildItem -Path $Path -Recurse | Where-Object {$_.PsIsContainer} | Where-Object {!($_.GetFiles()| Where-Object {$_.LastWriteTime -lt $Yesterday})} | Format-Table FullName, LastWriteTime
$Exist = Get-ChildItem -Path $Path -Recurse -Include "*.*" | Where-Object {$_.FullName -like "*$YesterdayF*"} | Format-Table -auto FullName, @{n="Length(Mb)";e={"{0:N2}" -f ($_.Length/1mb)}}, LastWriteTime

$Body = @(
if ($NotExist -gt $null) {
        $NotExist
}
else {
        "Файлы за $Yesterday"
        ""
}



if ($Exist -gt $null) {
        "Каталоги с не обновленными файлами"
        $Exist
}
) | Out-String


rudimko 11-09-2012 15:55 1986729

Не вышло. Сформировалось письмо следующего соодержания:
Код:

Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
А можно как-то вывод всех данных назначить в переменную? Чтобы потом подставить в Body?

Kazun 11-09-2012 16:05 1986736

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

rudimko 11-09-2012 16:18 1986744

Спасибо, велики Гуру! +++++ тебе в карму ;)

rudimko 11-09-2012 19:47 1986871

Я, наверное, очень сильно замучил тебя, но возникла еще одна потребность...
А можно как-то используя форматирование (Format-Table) вывести название папок в столбике отдельно? Т.е. чтобы помимо имени файла и размера (Format Table Name, Length) было еще название папки в которой лежат файлы? :)

Kazun 11-09-2012 20:17 1986889

Добавить свойство DirectoryName.

rudimko 11-09-2012 20:37 1986907

Здорово. А можно как-то сократить? А то выводит, например: "C:\Temp\1\2\", а надо только "2".

Kazun 11-09-2012 21:05 1986928

Format Table Name, Length, @{n="Parent";e={$_.Directory.Name}}

rudimko 11-09-2012 22:11 1986994

Все отлично отработало. Спасибо!
Жаль только что в письме или если выводить в файл, то вся таблица кривая становится, видимо это из за шрифтов. Есть какое-нибудь гуманное решение может быть?

Iska 11-09-2012 22:16 1986997

rudimko, использовать моноширинный шрифт или делать вывод в таблице (для html).

rudimko 19-09-2012 09:13 1991310

Сделал вывод в таблицах HTML, все получилось. Теперь встала другая задача для усовершенствования скрипта.

Для начала распишу для чего все это делается и как:
1. Скрипт предназначен для выявления проблем хранения бэкапов
- находит файлы по маске созданные за вчерашний день
- находит каталоги в которых по маске не созданы файлы за вчерашний день
- записывает результаты в переменную и отправляет на эл. ящик

2. Сам скрипт:
читать дальше »

Код:

### Дата и пути ###
$Days = "-1"
$Date = Get-Date
$Yesterday = Get-Date $Date.AddDays($Days) -Format "dd/MM/yyyy"
$YesterdayF = Get-Date $Yesterday -Format "yyyyMMdd"
$Path = "Пусть к каталогу"
$Host1 = "Имя хоста"

### Стиль для HTML ###
$Style = "<style>"
$Style = $Style + "BODY{background-color:#FFFFFF; font-family: Geneva, Arial, Helvetica, sans-serif; font-size: 12px;}"
$Style = $Style + "TABLE{border-width: 3px; border-style: solid; border-color: white; border-collapse: collapse;}"
$Style = $Style + "TH{text-align:left; border-width: 3px; padding: 8px; border-style: solid; border-color: white; background-color:#BDBDBD}"
$Style = $Style + "TD{text-align:left; border-width: 3px; padding: 8px; border-style: solid; border-color: white; background-color:#DEDEDE}"
$Style = $Style + "</style>"

### Поиск несуществующих файлов с заданным фильтром ###
$NotExist = Get-ChildItem -Path $Path -Recurse |
Where-Object {$_.PsIsContainer} |
Where-Object {!($_.GetFiles()| Where-Object {".bak",".zip" -eq $_.Extension} | Where-Object {$_.Name -like "*$YesterdayF*"})}

### Поиск существующих файлов с заданным фильтром ###
$Exist = Get-ChildItem -Path $Path -Recurse -Include "*.*" |
Where-Object {".bak",".zip" -eq $_.Extension} |
Where-Object {$_.Name -like "*$YesterdayF*"}

$Body = @(
$Style

### Условие: если нет указанных файлов по заданному фильтру - выводит в таблицу каталог где их нет ###
if ($NotExist -gt $null) {
        "<font color=red>В каталогах нет обновлений</font>"
        $NotExist | ConvertTo-Html -Fragment @{Label="Каталог";e={$_.Name}}, @{Label="Последнее обновление";e={$_.LastWriteTime}}

### Условие: если все впорядке и файлы есть - выводит в таблицу список файлов и некоторые свойства файла ###
if ($Exist -gt $null) {
        "<br><font color=green>$Host1 - Файлы обновленных бэкапов за $Yesterday</font>"
        $Exist | ConvertTo-Html -Fragment @{Label="Тип";e={$_.Extension}}, @{Label="Каталог файла";e={$_.Directory.Name}}, @{Label="Имя файла";e={$_.BaseName}}, @{Label="Размер Мб";e={"{0:N0}" -f ($_.Length/1mb)}}
}
) | Out-String

### Почтовые переменные ###
$EmailTo = "backup@mail.ru"
$Subject = "Отчет о бэкапах за $Yesterday на $Host1"
$EmailFrom = "backup@mail.ru"

### Настройки SMTP на .NET  ###
$SMTPServer = "server.mail.ru"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("backup@mail.ru", "password");
$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
$Message.IsBodyHtml = $True
$SMTPClient.Send($Message)



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

Сравнение:
1. Размер файла (если он уменьшился на 0.5мб, то нужно как-то это отметить в таблице, например поставить воскл. знак в сл. столбце)
2. Если нет файла за вчера, выводит в строку за позавчера и так же воскл. знак в сл. графе

В общем задумка примерно такая, но не знаю как ее реализовать и возможно ли это вообще... Буду всем признателен, кто поможет в разработке данного скрипта. Спасибо заранее.

JumpDa 20-09-2012 15:06 1992055

Почему-то выдает ошибку после Out-Strng:


Отсутствует закрывающая "}" в блоке инструкций.
строка:15 знак:1
+ <<<< ) | Out-String
+ CategoryInfo : ParserError: (CloseBraceToken:TokenId) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace

Kazun 20-09-2012 16:34 1992100

Должно быть Out-String.

JumpDa 20-09-2012 17:04 1992122

там именно Out-String, опечатался в предыдущем сообщении...

читать дальше »
>> ### Условие: если все впорядке и файлы есть - выводит в таблицу список файлов и некоторые свойства файла ###
>> if ($Exist -gt $null) {
>> "<br><font color=green>$Host1 - Файлы обновленных бэкапов за $Yesterday</font>"
>> $Exist | ConvertTo-Html -Fragment @{Label="Тип";e={$_.Extension}}, @{Label="Каталог
>>
>> файла";e={$_.Directory.Name}}, @{Label="Имя файла";e={$_.BaseName}}, @{Label="Размер Мб";e={"{0:N0}" -f
>>
>> ($_.Length/1mb)}}
>>
>> ) | Out-String
>>
Отсутствует закрывающая "}" в блоке инструкций.
строка:14 знак:1
+ <<<< ) | Out-String
+ CategoryInfo : ParserError: (CloseBraceToken:TokenId) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace



Возможно нужен 3-й PowerShell? Пробую на 2-й версии

Kazun 20-09-2012 17:10 1992127

Не требуется PowerShell V3,тут скобка пропущена:
Код:

$Body = @(
$Style

### Условие: если нет указанных файлов по заданному фильтру - выводит в таблицу каталог где их нет ###
if ($NotExist -gt $null) {
        "<font color=red>В каталогах нет обновлений</font>"
        $NotExist | ConvertTo-Html -Fragment @{Label="Каталог";e={$_.Name}}, @{Label="Последнее обновление";e={$_.LastWriteTime}}

### Условие: если все впорядке и файлы есть - выводит в таблицу список файлов и некоторые свойства файла ###
if ($Exist -gt $null) {
        "<br><font color=green>$Host1 - Файлы обновленных бэкапов за $Yesterday</font>"
        $Exist | ConvertTo-Html -Fragment @{Label="Тип";e={$_.Extension}}, @{Label="Каталог файла";e={$_.Directory.Name}}, @{Label="Имя файла";e={$_.BaseName}}, @{Label="Размер Мб";e={"{0:N0}" -f ($_.Length/1mb)}}
}
}) | Out-String


JumpDa 20-09-2012 17:17 1992131

Спасибо!

rudimko 20-09-2012 20:03 1992215

Скобка не там пропущена, прошу прощения, неверно код вставил. Скобка пропущена в самом конце первого условия, на строчку выше второго условия.
Вот верный кусок:
Код:

### Условие: если нет указанных файлов по заданному фильтру - выводит в таблицу каталог где их нет ###
if ($NotExist -gt $null) {
        "<font color=red>В каталогах нет обновлений</font>"
        $NotExist | ConvertTo-Html -Fragment @{Label="Каталог";e={$_.Name}}, @{Label="Последнее обновление";e={$_.LastWriteTime}}
}

### Условие: если все впорядке и файлы есть - выводит в таблицу список файлов и некоторые свойства файла ###
if ($Exist -gt $null) {
        "<br><font color=green>$Host1 - Файлы обновленных бэкапов за $Yesterday</font>"
        $Exist | ConvertTo-Html -Fragment @{Label="Тип";e={$_.Extension}}, @{Label="Каталог файла";e={$_.Directory.Name}}, @{Label="Имя файла";e={$_.BaseName}}, @{Label="Размер Мб";e={"{0:N0}" -f ($_.Length/1mb)}}
}
) | Out-String


rudimko 21-09-2012 11:07 1992464

Еще раз о крике помощи

Имеем допотопный скрипт, который ищет файлы в каталогах по маске (за вчерашний день и за позавчерашний день):
Код:

$Date = Get-Date
$Yesterday = Get-Date $Date.AddDays(-1) -Format "dd/MM/yyyy"
$YesterdayF = Get-Date $Yesterday -Format "yyyyMMdd"
$BeforeYesterday = Get-Date $Date.AddDays(-2) -Format "dd/MM/yyyy"
$BeforeYesterdayF = Get-Date $BeforeYesterday -Format "yyyyMMdd"
$Path = "C:\test"

$Exist = Get-ChildItem -Path $Path -Recurse -Include "*.*" | Where-Object {$_.Name -like "*$YesterdayF*"}
$Exist = $Exist + (Get-ChildItem -Path $Path -Recurse -Include "*.*" | Where-Object {$_.Name -like "*$BeforeYesterdayF*"})

Если сделать вывод:
Код:

$Exist | Sort-Object -Property $_.Name | Format-Table @{Label="Каталог";e={$_.Directory.Name}}, @{Label="Имя";e={$_.Name}}, @{Label="Размер";e={"{0:N3}" -f ($_.Length/1mb)}}
Получается вот такая табличка (в Base_1 отсутствует файл за позавчера, в Base_4 файл за вчерашнюю дату отсутствует):
Цитата:

Каталог | Имя | Размер
------- | --- | ------
Base_1 | base_1_20120920.txt | 0,011
Base_2 | base_2_20120919.txt | 0,000
Base_2 | base_2_20120920.txt | 0,011
Base_3 | base_3_20120919.txt | 0,000
Base_3 | base_3_20120920.txt | 0,011
Base_4 | base_4_20120919.txt | 0,000
Base_5 | base_5_20120919.txt | 0,010
Base_5 | base_4_20120920.txt | 0,005
Теперь вопрос о том как сделать вывод таблички с следующими условиями:
1. Каталог
2. Имя файла (вчерашний файл, если его нет, тогда позавчерашний)
3. Размер Позавчерашнего файла если он есть)
4. Размер Вчерашнего файла (если он есть)
5. Вывод отметок по условиям
(ставить ОК: если имеется вчерашний файл и его размер не равен 0, если есть позавчерашний и вчерашний;
ставить FAIL: если есть позавчерашний файл, а вчерашнего нет, если вчерашний файл меньше по размеру чем позавчерашний)

Пример выходной таблички:
Цитата:

Каталог | Имя | Размер Позавчера | Размер Вчера | ОТМЕТКИ
------- | --- | ---------------- | ------------ | -------
Base_1 | base_1_20120920.txt | - | 0,011 | ОК
Base_2 | base_2_20120920.txt | 0,000 | 0,011 | ОК
Base_3 | base_3_20120920.txt | 0,000 | 0,011 | ОК
Base_4 | base_4_20120919.txt | 0,000 | - | FAIL
Base_5 | base_5_20120920.txt | 0,010 | 0,005 | FAIL
Друзья, понимаю, что одним спасибо не отделаюсь, поэтому с меня причитается за помощь. Заранее благодарствую...

Kazun 21-09-2012 12:30 1992496

Код:

$Date = Get-Date
$Yesterday = Get-Date $Date.AddDays(-1) -Format "dd/MM/yyyy"
$YesterdayF = Get-Date $Yesterday -Format "yyyyMMdd"
$BeforeYesterday = Get-Date $Date.AddDays(-2) -Format "dd/MM/yyyy"
$BeforeYesterdayF = Get-Date $BeforeYesterday -Format "yyyyMMdd"
$Path = "D:\test"


$files = Get-ChildItem -Path $Path -Recurse | Where {$_.Name -match "$YesterdayF|$BeforeYesterdayF" -and !$_.PsIsContainer} |
                Group-Object {$_.Directory.Name} -AsString -AsHashtable
               
$files.GetEnumerator() | Foreach {
        $value = $_.value
       
        if($value.Count -eq 1)
        {
                $size  = $value[0].Length
                $name  = $value[0].Name
                $fname = $_.Name
               
                if($name -match "$BeforeYesterdayF")
                {
                        $Status = "Fail"
                        $SizeBeforeYesterday = "{0:N3}" -f ($size/1mb)
                        $SizeYesterday = "-"
                }
               
                else
                {
                        if ($size)
                        {                               
                                $Status = "OK"
                        }
                        else
                        {
                                $Status = "Fail"
                        }
                        $SizeBeforeYesterday = "-"
                        $SizeYesterday = "{0:N3}" -f ($size/1mb)
                }
               
                New-Object PsObject -Property @{
                                "Каталог" = $fname
                                "Имя" = $name
                                "Размер Позавчера" = $SizeBeforeYesterday
                                "Размер Вчера" = $SizeYesterday
                                "ОТМЕТКИ" = $Status
                }
        }
       
        else {
                $FileBefore = ($value -match "$BeforeYesterdayF")[0]
                $FileYesterday = ($value -match "$YesterdayF")[0]
               
                if (($FileYesterday.Length - $FileBefore.Length) -gt 0)
                {
                        $Status = "OK"
                }
               
                else {
                        $Status = "Fail"
                }
               
                New-Object PsObject -Property @{
                                "Каталог" = $_.Name
                                "Имя" = $FileYesterday.Name
                                "Размер Позавчера" = $("{0:N3}" -f ($FileBefore.Length/1mb))
                                "Размер Вчера" = $("{0:N3}" -f ($FileYesterday.Length/1mb))
                                "ОТМЕТКИ" = $Status
                }
        }
} | Format-Table "Каталог","Имя","Размер Позавчера","Размер Вчера","ОТМЕТКИ"



Время: 20:24.

Время: 20:24.
© OSzone.net 2001-