Powershell Folder монитор / пакетное исполнение


0

Я новичок в Powershell. Я нашел сценарий, который работает с тем, что мне нужно, вроде.

То, что я ищу, это скрипт для отслеживания папки для определенных имен файлов / типов. В зависимости от имени / типа файла, я хочу, чтобы он выполнял определенный командный файл для выполнения команды для утилиты сервера.

Как именно я бы этого достиг. Я нашел этот скрипт и добавил элемент invoke для запуска batfile файла, такого как PDF, который попадает в папку. Однако мне нужно отфильтровать его и запустить другой bat-файл в зависимости от имени файла. То, что у меня есть, вызывает файл bat для каждого файла, который попадает в папку, которую я не хочу. Мое знание минимально, и я знаю только достаточно, чтобы быть опасным.

Если XXXX.PDF, XXRX.PDF, XXLX.PDF попали в папку, мне нужно, чтобы он знал, если XXXX.PDF приземляется, запустите только XXXX.bat. Если приземляется XXRX.PDF, запускается только XXRX.BAT и т. Д. И т. Д.

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = "D:\XXXX\XXXX"
    $watcher.Filter = "*.PDF"
    $watcher.IncludeSubdirectories = $true
    $watcher.EnableRaisingEvents = $true 

### DEFINE ACTIONS AFTER A EVENT IS DETECTED

    $action = {Invoke-Item "D:\BATCH FILES\XXXXX.bat" -filter = "XXXXX.pdf"}    

### DECIDE WHICH EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY  
    $created = Register-ObjectEvent $watcher "Created" -Action $action
###    $changed = Register-ObjectEvent $watcher "Changed" -Action $action
###    $deleted = Register-ObjectEvent $watcher "Deleted" -Action $action
###    $renamed = Register-ObjectEvent $watcher "Renamed" -Action $action
    while ($true) {sleep 5}

Вы должны посмотреть файлы справки для «Test-Path» и «If». Создайте свой оператор IF: если test-path = true, выполните какое-либо действие (в этом случае вы используете bat-файл).
Qwilson

Ответы:


1

FileWatchers имеют причуды, в зависимости от того, как создаются файлы :

В некоторых ситуациях вы можете заметить, что одно событие создания   генерирует несколько созданных событий, которые обрабатываются вашим компонентом.   Например, если вы используете компонент FileSystemWatcher для мониторинга   создание новых файлов в каталоге, а затем проверить его с помощью   Блокнот для создания файла, вы можете увидеть два созданных события, созданные   хотя был создан только один файл. Это потому что блокнот   выполняет несколько действий файловой системы в процессе записи.   Блокнот записывает на диск пакетами, которые создают содержимое   файл, а затем атрибуты файла. Другие приложения могут выполнять в   таким же образом. Потому что FileSystemWatcher контролирует работающие   системные действия, все события, которые будут запускать эти приложения   взял.

Примечание. Блокнот также может вызывать другие интересные события. За   Например, если вы используете ChangeEventFilter, чтобы указать, что вы хотите   следите только за изменениями атрибутов, а затем вы записываете в файл в   каталог, который вы смотрите с помощью блокнота, вы будете вызывать событие.   Это связано с тем, что Блокнот обновляет атрибут Archived для файла   во время этой операции.

Так что в вашем случае я бы пошел с простым сравнением каталогов. Вот скрипт, который будет отслеживать каталог на наличие изменений и запускать файлы. Сохранить этот скрипт как MonitorAndExecute.ps1, Он принимает следующие аргументы:

  • Дорожка : папка для мониторинга. Если не указан, используется текущий каталог.
  • Фильтр : расширение файла для соответствия. По умолчанию *то есть сопоставить все файлы.
  • Бежать : расширение файла для запуска, когда новый файл найден. По умолчанию bat,
  • Recurse : исправлять каталоги или нет. По умолчанию установлено значение false.
  • интервал : время в секундах для сна между просмотром папки. По умолчанию 5 секунд.
  • Подробный : Сценарий расскажет вам, что происходит через Write-Verbose Сообщения.

Пример (запускается из консоли PowerShell).

монитор *.pdf файлы в папке D:\XXXX\XXXX, recurse, если новый файл найден, запустить файл с тем же базовым именем и расширением *.bat, будь многословен:

.\MonitorAndExecute.ps1 -Path 'D:\XXXX\XXXX' -Filter '*.pdf' -Run 'bat' -Recurse -Interval 10 -Verbose

MonitorAndExecute.ps1 сценарий:

Param
(
    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [ValidateScript({
        if(!(Test-Path -LiteralPath $_ -PathType Container))
        {
            throw "Input folder doesn't exist: $_"
        }
        $true
    })]
    [ValidateNotNullOrEmpty()]
    [string]$Path = (Get-Location -PSProvider FileSystem).Path,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]$Filter = '*',

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]$Run = 'bat',

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [switch]$Recurse,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [int]$Interval = 5
)

# Scriptblock that gets list of files
$GetFileSet = {Get-ChildItem -LiteralPath $Path -Filter $Filter -Recurse:$Recurse | Where-Object {!($_.PSIsContainer)}}

Write-Verbose 'Getting initial list of files'
$OldFileSet = @(. $GetFileSet)
do
{
    Write-Verbose 'Getting new list of files'
    $NewFileSet = @(. $GetFileSet)

    Write-Verbose 'Comaparing two lists using file name and creation date'
    Compare-Object -ReferenceObject $OldFileSet -DifferenceObject $NewFileSet -Property Name, CreationTime -PassThru |
        # Select only new files
        Where-Object { $_.SideIndicator -eq '=>' } |
            # For each new file...
            ForEach-Object {
                Write-Verbose "Processing new file: $($_.FullName)"
                # Generate name for file to run
                $FileToRun = (Join-Path -Path (Split-Path -LiteralPath $_.FullName) -ChildPath ($_.BaseName + ".$Run"))

                # If file to run exists
                if(Test-Path -LiteralPath $FileToRun -PathType Leaf)
                {
                    Write-Verbose "Running file: $FileToRun"
                    &$FileToRun
                }
                else
                {
                    Write-Verbose "File to run not found: $FileToRun"
                }
            }

    Write-Verbose 'Setting current list of files as old for the next loop'
    $OldFileSet = $NewFileSet

    Write-Verbose "Sleeping for $Interval seconds..."
    Start-Sleep -Seconds $Interval
}
while($true)

Как жаль, место для ответа, и оно не принято и не проголосовано ... позор ... Спасибо за ответ, выручил меня.
Emil Borconi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.