Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Сравнение файла с оригиналом, создание отчета

Ответить
Настройки темы
PowerShell - Сравнение файла с оригиналом, создание отчета

Старожил


Сообщения: 173
Благодарности: 4

Профиль | Отправить PM | Цитировать


Добрый день,

Есть папка, в которую люди выкладывают файлы.
Необходимо проверить все ли люди выложи файлы, если нет - записть в отчет - забыли.txt
Затем все файлы проверяются на соответствие определенным атрибутам(все атрибуты закодированы в имени файла), если всё верно - файлы перемещаются в папку с именем сегодняшней даты
Если атрибуты файлов не верные - запись в отчет - неверно.txt
Как планируется проверять все ли люди выложили файлы в папку.
Есть файл - сотрудники.txt вот такого вида:
Код: Выделить весь код
33-1:Отдел1:Иванов:555
22:Отдел2:Петров:333
Файлы, которые выкладывают люди имеет имя:sr_33-1_20120926.rar.enc
Надо создать проверку одного массива данных
Код: Выделить весь код
get-content .\сотрудники.txt -replace ":.*",""
другому массиву - массиву файлов:
Код: Выделить весь код
$files = (get-childitem).Basename
В случае если совпадение есть - то выполнять проверку дальше
В случае если совпадения нет формировать отчет забыли.txt или ошибки.txt
Отчеты такого вида:
Код: Выделить весь код
33-1   Отдел1   Иванов   555   Ошибка
22     Отдел2   Петров   333   Ошибка
Под ошибкой понимается тип ошибки - отсутствие атрибута
Для отчета забыли отчет:
Код: Выделить весь код
33-1   Отдел1   Иванов   555
22     Отдел2   Петров   333
Создал распихивание файлов по папкам с датой в папки - правильные и не правильные.
Не могу создать отчеты, потому что не понятно как сравнить два массива.
Делаю так.
Код: Выделить весь код
cls
$BASE = Get-Content сотрудники.txt
$BASEName = $BASE -replace ":.*",""
cd y:\TableReports
ForEach ($a in Get-ChildItem)
	{
	$b=0
	if (($a.BaseName -replace "^S_","" -replace "_.*","") -like $BASEName[$b])
		{
		'Move-item $a.Basename'
		}
	else
		{
		"Write to log-file"
		}
	$b=$b+1
	}
Вот постоянно выдает, что не верно (то есть выполняет команду else)
Хотя одно значение должно совпадать точно
А если просто из строки выполнить
Код: Выделить весь код
($a[1].BaseName -replace "^S_","" -replace "_.*","") -like $BASEName[$b]
Говорит True - То есть должен был бы выполнить условие до else - или другими словами одно совпадение найдено (правда здесь конкретная проверка - одно значение с другим.
Кстати только что понял, что я ожидал ответ от одиночной команды вида:
33-1 (я ведь написал -like а не -contains)
а он выдает True или False

Отправлено: 17:25, 26-09-2012

 

Ветеран


Сообщения: 1259
Благодарности: 861

Профиль | Отправить PM | Цитировать


Такого формата имя:sr_33-1_20120926.rar.enc файл не может быть.

Файл должен быть в кодировке Unicode
Код: Выделить весь код
$base = Import-Csv сотрудники.txt -Delimiter ":" -Header "O","T",TH","F"
$files = Get-ChildItem D:\ | Where {!$_.PsIsContainer} | Select-Object -Expand FullName

foreach($name in $base)
{
	$find = $files -match $name.th
	if($find)
	{
		'Move-item $find'
	}
	else 
	{
		'Write to log-file'
	}
}
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:42, 26-09-2012 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Старожил


Сообщения: 173
Благодарности: 4

Профиль | Отправить PM | Цитировать


Благодарю за помощь.
Теперь не могу скопировать данные.
Код: Выделить весь код
cls
cd y:\
$base = Import-Csv DATA.txt -Delimiter ":" -Header "N","Отдел","Контактный номер"
$files = Get-ChildItem Y:\TableReports | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
$DayFolder = New-item -Path Y:\week -name "$(Get-Date -uformat '%Y%m%d')" -type directory
$DayFolder2 = New-item -Path Y:\markdelete -name "$(Get-Date -uformat '%Y%m%d')" -type directory
cd Y:\TableReports
foreach($name in $base)
{
	$findFile = $files -match $name.N
	if($findFile)
	{
	Write-Host "Файл прислали"
	$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
		if($findAtr)
		{
		Write-Host "Атрибуты верны"
		Copy-Item -Path $findAtr -Destination $DayFolder.FullName
		}
		else
		{
		Write-Host "Атрибуты НЕ верны"
		$name.N
		Copy-Item -Path $findAtr -Destination $DayFolder2.FullName
		}
	}
	else 
	{
	Write-Host "Файл НЕ прислали"
	}
}
В базе DATA.txt содержится список контактов. Начинается с номера. Есть номера вида: 53-1
Вот на них и ругается.
Код: Выделить весь код
...
Атрибуты НЕ верны
33-1
Copy-Item : Не удается привязать аргумент к параметру "Path", так как он представляет собой пустой массив.
C:\Dropbox\VFTP_подписиЧУЖОЙ.ps1:24 знак:18
+         Copy-Item -Path <<<<  $findAtr -Destination $DayFolder2.FullName
    + CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyArrayNotAllowed,Microsoft.PowerShell.Commands. 
   CopyItemCommand
 
Файл прислали
...
Я так понимаю, что вот эта конструкция:
Код: Выделить весь код
$findFile = $files -match $name.N
	if($findFile)
{}
else
{}
В случае отрицательного значение (переход в else) в $findfile = ничего не возвращает. Как быть?

Отправлено: 18:08, 27-09-2012 | #3


Ветеран


Сообщения: 1259
Благодарности: 861

Профиль | Отправить PM | Цитировать


1) Зачем в скрипте команды?
cd y:\
cd Y:\TableReports

2) $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - Какие тут тестируются атрибуты?

3) Copy-Item -Path $findAtr должно быть Copy-Item -Path $findFile

Отправлено: 18:28, 27-09-2012 | #4


Старожил


Сообщения: 173
Благодарности: 4

Профиль | Отправить PM | Цитировать


1.
cd y:\ так как в команде не было полного пути до файла. указываю диск (исправил)
cd y:\tablereports - не могу объяснить - удалил

2. Атрибуты - не в привычном смысле слова. То есть это не атрибуты файловый системы (архивный, скрытый, acl, что там ещё...) - эти атрибуты закодированы в имени файла.
$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - мне нужны файлы, которые оканчиваются на rar.sig.enc и в имени содержат большую букву S.

3. Исправил работает.

Вот такой отчет получился.
Код: Выделить весь код
Write-Host "Файл НЕ прислали"
	$name | Out-File не_прислали.txt -Append
	$report = get-content не_прислали.txt
	$encoding = [System.Text.Encoding]::UTF8
	$body = $report | Where-Object {$_ -ne "" -and $_ -match "[0-9]"}
	Send-MailMessage -encoding $encoding -From ftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru
В результате имеем:
HTML код: Выделить весь код
22 Number1Номер 1 22-1 Number1Номер 1 44-1 Number2Номер3 222-333 52 NUMBER5 555 53-1 Number2 22223333444

Не очень хорошо читаемо. Что можете посоветовать? Кроме того, я создаю отчет через создание промежуточного файла. Как можно этого избежать?
На всякий случай весь код:
Код: Выделить весь код
cls
$base = Import-Csv y:\data.txt -Delimiter ":" -Header "N","Отдел","Контактный номер"
$files = Get-ChildItem y:\TableReports | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
$DayFolder = New-item -Path y:\TableReports\week -name "$(Get-Date -uformat '%Y%m%d')" -type directory
$DayFolder2 = New-item -Path y:\TableReports\markdelete -name "$(Get-Date -uformat '%Y%m%d')" -type directory
foreach($name in $base)
{
	$findFile = $files -match $name.N
	if($findFile)
	{
	Write-Host "Файл прислали"
	$name.N
	$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
		if($findAtr)
		{
		Write-Host "Атрибуты верны"
		$name.N
		Copy-Item -Path $findFile -Destination $DayFolder.FullName
		}
		else
		{
		Write-Host "Атрибуты НЕ верны"
		$name.N
		Copy-Item -Path $findFile -Destination $DayFolder2.FullName
		}
	}
	else 
	{
	Write-Host "Файл НЕ прислали"
	$name | Out-File не_прислали.txt -Append
	$report = get-content не_прислали.txt
	$encoding = [System.Text.Encoding]::UTF8
	$body = $report | Where-Object {$_ -ne "" -and $_ -match "[0-9]"}
	Send-MailMessage -encoding $encoding -From vftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru
	}
}

Отправлено: 12:15, 28-09-2012 | #5


Ветеран


Сообщения: 1259
Благодарности: 861

Профиль | Отправить PM | Цитировать


$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - Попробуйте узнать результат выполнения,может отработать только в случае массива,что врятли,для скалярного значения всегда выражение будет FALSE.


Добавить перед foreach переменную notfound:


Код: Выделить весь код
$notfound = @()
foreach($name in $base)
{
	$findFile = $files -match $name.N
	if($findFile)
	{
	Write-Host "Файл прислали $($name.N)"
	$name.N
	$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
		if($findAtr)
		{
		Write-Host "Атрибуты верны"
		$name.N
		Copy-Item -Path $findFile -Destination $DayFolder.FullName
		}
		else
		{
		Write-Host "Атрибуты НЕ верны"
		$name.N
		Copy-Item -Path $findFile -Destination $DayFolder2.FullName
		}
	}
	else 
	{
		$notfound += $name
		Write-Host "Файл не прислали $($name.N)"
	}
}

if($notfound)
{
	$body = $notfound | Format-Table -auto | Out-String
	Send-MailMessage -encoding ([System.Text.Encoding]::UTF8) -From vftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru
}
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:32, 28-09-2012 | #6


Старожил


Сообщения: 173
Благодарности: 4

Профиль | Отправить PM | Цитировать


Не сколько видоизменил ТЗ.
Один скрипт будет работать как служба.
Служба:
Код: Выделить весь код
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'C:\FTP'
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
 
while($TRUE){
 $result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::All, 1000);
 if($result.TimedOut){
 continue;
}
C:\Scripts\S-files\S-FilesCheck.ps1
}
В случае обнаружения изменений в папке - скрипт будет пинать второй.
Второй скрипт проверяет:
есть ли папка за сегодняшнее число. Если нет, то создает и проверяет файлы на вшивость.
Если файл нормальный, то копируется в папку - нормальные
Если файл не нормальный. копируется в папку не правильные и пишется сообщение на почту, что файл не верный (отображаются контакты накосячивших)
Второй - проверка файлов:
cls
Код: Выделить весь код
$Checkfolder = Test-Path -Path "c:\Reports\$(Get-Date -uformat '%Y%m%d')"
if($checkfolder -eq $False)
	{	
	New-item -Path "C:\Reports\" -name "$(Get-Date -uformat '%Y%m%d')" -type directory
	$DayOK = New-item -Path "C:\Reports\$(Get-Date -uformat '%Y%m%d')" -name 'OK' -type directory
	$DayNoOK = New-item -Path "C:\Reports\$(Get-Date -uformat '%Y%m%d')" -name 'NoOK' -type directory
	Write-Host "Create folder DATA, NoOK, OK"
	}
$base = Import-Csv C:\Scripts\S-files\data.txt -Delimiter ":" -Header "N","Отдел","Контактное лицо", "Телефон"
$files = Get-ChildItem c:\ftp | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
foreach($name in $base)
{
	$findFile = $files -match $name.N
	if($findFile)
	{
	Write-Host "Файл прислали $name.N"
	$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
		if($findAtr)
		{
		Write-Host "Атрибуты верны"
#		Move-Item -Path $($findFile) -Destination $DayOK.FullName
		}
		else
		{
		Write-Host "Атрибуты НЕ верны"
#		Copy-Item -Path $($findFile) -Destination $DayNoOK.FullName
		}
	}
}
Третий скрипт в одно время формирует список тех, кто не прислал файл вообще и отправляет отчет на почту

Второй вообще не отрабатывает. Причем как с @(notfound) так и без неё (я не до конца понял, как это работает).
А то что отрабатывает вообще не понятно как отрабатывает
Скажем по факту два файла. Один нормальный, второй нет.
А скрипт говорит, что:
- все атрибуты верны
- что прислали файл не два человек, а скажем 5

Отправлено: 16:25, 02-10-2012 | #7


Ветеран


Сообщения: 1259
Благодарности: 861

Профиль | Отправить PM | Цитировать


Я уже третий раз спрашиваю про условие "$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"" - ЧТО ЭТО?

Отправлено: 16:46, 02-10-2012 | #8


Старожил


Сообщения: 173
Благодарности: 4

Профиль | Отправить PM | Цитировать


Извиняюсь. Я вроде как ответил.
$findFile = $files -match $name.N
if($findFile)
Это первая проверка - ищем файл. Если нашли, то:
$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
весь путь, который нам возвращает вот эта команда
$files = Get-ChildItem c:\ftp | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
Например,
C:\ftp\S_11_20121002.rar.sig.enc

проверяем на содержание - есть ли в строчке - S, rar.sig.enc
$files.GetType().Name - возвращает string.
$findatr - возвращает boolean
Поэтому путь не подставлялся (boolean никак не подставишь), а отчет выдает больше вхождения - потому что files по символам разбирается.
Но как сделать правильно?

Нужно вот это изменить:
"$findAtr = $files -match "rar.sig.enc$" -cmatch "S"

Последний раз редактировалось tarasov.evgeny, 02-10-2012 в 17:02.


Отправлено: 16:52, 02-10-2012 | #9


Ветеран


Сообщения: 1259
Благодарности: 861

Профиль | Отправить PM | Цитировать


Тогда еще разок(в 6 посте я это описал,но читать конечно же не обязательно):
PS Z:\> "C:\ftp\S_11_20121002.rar.sig.enc" -match "rar.sig.enc$" -cmatch "S"
False
PS Z:\> "C:\ftp\S_11_20121002.rar.sig.enc" -match "rar.sig.enc$"
True

$findAtr = $findFile -match "\\S.+\.rar\.sig\.enc$"

Последний раз редактировалось Kazun, 02-10-2012 в 17:10.


Отправлено: 16:57, 02-10-2012 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Сравнение файла с оригиналом, создание отчета

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Поиск файла в 2х дерикториях, сравнение версии и принятие решения i-Lex Скриптовые языки администрирования Windows 15 09-12-2012 17:02
CMD/BAT - [решено] Сравнение файлов и замена значения из одного файла в другой. Aleks911tat Скриптовые языки администрирования Windows 12 25-08-2012 22:27
Учет компьютеров, создание отчета для бухгалтерии salamandra Сетевые технологии 5 22-01-2004 17:03
Создание отчета в Билдере Crazy Wolf Программирование и базы данных 2 07-10-2002 11:21




 
Переход