Monitoramento de pasta Powershell/execução em lote

Monitoramento de pasta Powershell/execução em lote

Eu sou novo no Powershell. Eu encontrei um script que funciona com o que eu preciso, mais ou menos.

O que estou procurando é um script para monitorar uma pasta em busca de nomes/tipos de arquivos específicos. Dependendo do nome/tipo do arquivo, quero que ele execute um determinado arquivo em lote para executar um comando para um utilitário de servidor.

Como exatamente eu conseguiria isso? Encontrei este script e adicionei um invocar-item para iniciar um arquivo bat, um arquivo como PDF chega à pasta. No entanto, preciso filtrá-lo e fazer com que ele inicie um arquivo bat diferente, dependendo do nome do arquivo. O que tenho atualmente, ele invocará o arquivo bat para cada arquivo que cair na pasta que não quero. Meu conhecimento é mínimo e só sei o suficiente para ser perigoso.

Se XXXX.PDF, XXRX.PDF, XXLX.PDF atingir a pasta, preciso saber se XXXX.PDF chegar, execute apenas XXXX.bat. Se XXRX.PDF pousar, execute apenas XXRX.BAT, etc, etc.

### 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}

Responder1

FileWatchers têm peculiaridades,dependendo de como os arquivos são criados:

Você pode perceber em determinadas situações que um único evento de criação gera vários eventos Criados que são manipulados pelo seu componente. Por exemplo, se você usar um componente FileSystemWatcher para monitorar a criação de novos arquivos em um diretório e, em seguida, testá-lo usando o Bloco de Notas para criar um arquivo, poderá ver dois eventos Criados gerados mesmo que apenas um único arquivo tenha sido criado. Isso ocorre porque o Bloco de notas executa várias ações do sistema de arquivos durante o processo de gravação. O Bloco de notas grava no disco em lotes que criam o conteúdo do arquivo e, em seguida, os atributos do arquivo. Outros aplicativos podem funcionar da mesma maneira. Como o FileSystemWatcher monitora as atividades do sistema operacional, todos os eventos disparados por esses aplicativos serão detectados.

Nota: O bloco de notas também pode causar outras gerações de eventos interessantes. Por exemplo, se você usar ChangeEventFilter para especificar que deseja observar apenas alterações de atributos e, em seguida, gravar em um arquivo no diretório que está monitorando usando o Bloco de Notas, você gerará um evento. Isso ocorre porque o Bloco de Notas atualiza o atributo Arquivado do arquivo durante esta operação.

Então, no seu caso, eu usaria uma comparação simples de diretórios. Aqui está o script que monitorará alterações no diretório e executará arquivos. Salve este script como MonitorAndExecute.ps1. Aceita os seguintes argumentos:

  • Caminho:pasta a ser monitorada. Se não for especificado, o diretório atual será usado.
  • Filtro:extensão de arquivo correspondente. O padrão é *, ou seja, corresponder todos os arquivos.
  • Correr:extensão de arquivo para ser executada, quando um novo arquivo for encontrado. O padrão é bat.
  • Recurso:diretórios recursivos ou não. O padrão é falso.
  • Intervalo:tempo em segundos para dormir entre a varredura de pastas. O padrão é 5segundos.
  • Verboso:O script lhe dirá o que está acontecendo por meio de Write-Verbosemensagens.

Exemplo (executado no console do PowerShell).

Monitore *.pdfos arquivos na pasta D:\XXXX\XXXX, recurse, se o novo arquivo for encontrado, execute o arquivo com o mesmo nome base e extensão *.bat, seja detalhado:

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

MonitorAndExecute.ps1roteiro:

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)

informação relacionada