Монитор папок Powershell/пакетное выполнение

Монитор папок Powershell/пакетное выполнение

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

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

Как именно я этого добьюсь. Я нашел этот скрипт и добавил invoke-item для запуска bat-файла, когда файл, такой как 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}

решение1

У FileWatchers есть свои странности,в зависимости от того, как создаются файлы:

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

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

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

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

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

Мониторинг *.pdfфайлов в папке D:\XXXX\XXXX, рекурсия, если найден новый файл, запуск файла с тем же базовым именем и расширением *.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)

Связанный контент