Я новичок в 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}

1 ответ1

1

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

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

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

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

  • Путь: папка для мониторинга.Если не указан, используется текущий каталог.
  • Фильтр: расширение файла для соответствия.По умолчанию * , то есть совпадать со всеми файлами.
  • Выполнить: расширение файла для запуска, когда новый файл найден.По умолчанию bat .
  • Recurse: рекурсивные каталоги или нет.По умолчанию установлено значение false.
  • Интервал: время ожидания в секундах между просмотром папки.По умолчанию 5 секунд.
  • Verbose: скрипт расскажет вам, что происходит через сообщения 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)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .