Показать полную графическую версию : [решено] скрипт для выявления невыполненных ежедневных бэкапов
Друзья, помогите решить проблему, не могу сделать правильный вывод данных. Как вывести только названия тех папок, где не существуют файлы, которые будут заданы в условие (к примеру $_.LastWriteTime не являются вчерашней датой). Заранее спасибо.
Как пример,найти все папки в которых нет файлов,измененных сегодня:
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
Спасибо, все отлично отработало. Еще малюсенький вопрос: Я делаю вывод в таблицу "Format-Table -auto FullName, Length, LastWriteTime", а как мне вывести "Length" в мегабайтах, а не в байтах?
Format-Table -auto FullName, @{n="Length(MB)";e={"{0:N2}" -f ($_.Length/1mb)}}, LastWriteTime
Здорово! И последний вопрос:
Вот код:
$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)
Заранее спасибо!
Для начала разберитесь с логикой, а то тут странно получается:
1) Проверяем каталоги на условие
2) Если удовлетворяет условию, выводим каталоги
3) Не удовлетворяет условию,выводим -"Файлы за $Yesterday"
4) Получаем список файлов в пути,которых есть $YesterdayF
5) Если удовлетворяет условию,выводим "Каталоги с не обновленными файлами" и файлы
Зачем дважды гонять не быструю операцию,как Get-ChildItem -Path $Path -Recurse,проще сохранить результат один раз в переменную и в дальнейшем уже использовать.
Так как с PowerShell знаком только третий день, то мне самому сложно понять как это сделать ;)
Когда сохраняю весь результат в переменную и подставляю ее в $Body, то тело письма содержит весь код, а не результат. Как сделать правильно?
Будь по-вашему.
$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
Не вышло. Сформировалось письмо следующего соодержания:
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?
Скопируйте правильно,что я привел,там этой не возникает таких проблем и весь вывод в переменной $Body
Спасибо, велики Гуру! +++++ тебе в карму ;)
Я, наверное, очень сильно замучил тебя, но возникла еще одна потребность...
А можно как-то используя форматирование (Format-Table) вывести название папок в столбике отдельно? Т.е. чтобы помимо имени файла и размера (Format Table Name, Length) было еще название папки в которой лежат файлы? :)
Добавить свойство DirectoryName.
Здорово. А можно как-то сократить? А то выводит, например: "C:\Temp\1\2\", а надо только "2".
Format Table Name, Length, @{n="Parent";e={$_.Directory.Name}}
Все отлично отработало. Спасибо!
Жаль только что в письме или если выводить в файл, то вся таблица кривая становится, видимо это из за шрифтов. Есть какое-нибудь гуманное решение может быть?
rudimko, использовать моноширинный шрифт или делать вывод в таблице (для html).
Сделал вывод в таблицах 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. Если нет файла за вчера, выводит в строку за позавчера и так же воскл. знак в сл. графе
В общем задумка примерно такая, но не знаю как ее реализовать и возможно ли это вообще... Буду всем признателен, кто поможет в разработке данного скрипта. Спасибо заранее.
Почему-то выдает ошибку после Out-Strng:
Отсутствует закрывающая "}" в блоке инструкций.
строка:15 знак:1
+ <<<< ) | Out-String
+ CategoryInfo : ParserError: (CloseBraceToken:TokenId) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.