Monitor de pasta Powershell / execução em lote

0

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

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

Como exatamente eu conseguiria isso? Eu encontrei este script e adicionei um item de invocação para lançar um arquivo batfile um arquivo como o PDF aterra na pasta. No entanto, preciso filtrá-lo e iniciá-lo em um arquivo bat diferente, dependendo do nome do arquivo. O que eu tenho atualmente, ele irá invocar o arquivo bat para cada arquivo que cai na pasta que eu não quero. Meu conhecimento é mínimo e eu só sei o suficiente para ser perigoso.

Se XXXX.PDF, XXRX.PDF, XXLX.PDF acertar a pasta, eu preciso saber se XXXX.PDF é compatível, execute somente XXXX.bat. Se o terreno XXRX.PDF for executado somente 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}
    
por Richard W 11.03.2015 / 21:08

1 resposta

1

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

You may notice in certain situations that a single creation event generates multiple Created events that are handled by your component. For example, if you use a FileSystemWatcher component to monitor the creation of new files in a directory, and then test it by using Notepad to create a file, you may see two Created events generated even though only a single file was created. This is because Notepad performs multiple file system actions during the writing process. Notepad writes to the disk in batches that create the content of the file and then the file attributes. Other applications may perform in the same manner. Because FileSystemWatcher monitors the operating system activities, all events that these applications fire will be picked up.

Note: Notepad may also cause other interesting event generations. For example, if you use the ChangeEventFilter to specify that you want to watch only for attribute changes, and then you write to a file in the directory you are watching using Notepad, you will raise an event . This is because Notepad updates the Archived attribute for the file during this operation.

Então, no seu caso, eu iria com o diretório simples comparando. Aqui está o script que irá monitorar o diretório para mudanças e executar arquivos. Salve este script como MonitorAndExecute.ps1 . Aceita os seguintes argumentos:

  • Caminho : pasta a ser monitorada. Se não especificado, o diretório atual é usado.
  • Filtro : extensão de arquivo para correspondência. O padrão é * , ou seja, corresponde todos os arquivos.
  • Executar : extensão de arquivo para ser executada, quando um novo arquivo for encontrado. O padrão é bat .
  • Recurse : recurse diretórios ou não. O padrão é falso.
  • Intervalo : tempo em segundos para dormir entre a verificação de pastas. O padrão é 5 segundos.
  • Verbose : o script informará o que está acontecendo via Write-Verbose messages.

Exemplo (executado no console do PowerShell).

Monitore *.pdf 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.ps1 script:

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)
    
por 19.03.2015 / 14:58