Только Powershell Change Watcher Триггеры для каталогов - PullRequest
0 голосов
/ 02 октября 2018

Я создаю скрипт для просмотра файлов в powershell.Я манипулировал кодом из: https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b

Казалось, что все работает нормально, но когда я провел какое-то реальное тестирование, я заметил, что событие change было вызвано только в родительском каталоге, а не в самом файле.Ниже приведен код, который я выкинул и обновил:

$folder = 'C:\extended_attributes\testing\DesignerVistaReorganize' # Enter the root path you want to monitor. 
$filter = '*.*'  # You can enter a wildcard filter here. 

# In the following line, you can change 'IncludeSubdirectories to $true if required.                           
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

# Here, all three events are registerd.  You need only subscribe to events that you need: 

Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
    $name        = $Event.SourceEventArgs.Name 
    $changeType  = $Event.SourceEventArgs.ChangeType 
    $timeStamp   = $Event.TimeGenerated 
    $filePath    = -join($folder,"\",$name) | Out-String
    Write-Host "The file '$filePath' was $changeType at $timeStamp" -fore green 
    Out-File -FilePath C:\extended_attributes\testing\outlog.txt -Append -InputObject "The file '$filePath' was $changeType at $timeStamp"} 

Register-ObjectEvent $fsw Deleted -SourceIdentifier FileDeleted -Action { 
    $name        = $Event.SourceEventArgs.Name 
    $changeType  = $Event.SourceEventArgs.ChangeType 
    $timeStamp   = $Event.TimeGenerated 
    $filePath    = -join($folder,"\",$name) | Out-String
    Write-Host "The file '$filePath' was $changeType at $timeStamp" -fore red 
    Out-File -FilePath C:\extended_attributes\testing\outlog.txt -Append -InputObject "The file '$filePath' was $changeType at $timeStamp"} 

Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action { 
    $name        = $Event.SourceEventArgs.Name 
    $changeType  = $Event.SourceEventArgs.ChangeType 
    $timeStamp   = $Event.TimeGenerated 
    $filePath    = -join($folder,"\",$name) | Out-String
    Write-Host "The file '$filePath' was $changeType at $timeStamp" -fore white 
    Out-File -FilePath c:\scripts\filechange\outlog.txt -Append -InputObject "The file '$filePath' was $changeType at $timeStamp"} 

События удаления и создания работают, как и следовало ожидать (как показано ниже):

Создание файла:

The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Cart_Warnings\newFile.txt' Created at 10/01/2018 14:55:35

Изменение файла:

The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Cart_Warnings'

было изменено 10/01/2018 15: 01: 18

Удаление файла:

The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Cart_Warnings\newFile.txt' Deleted at 10/01/2018 14:56:47

Еще одна вещь, которую я заметил, это то, что событие изменения запускается только при первом изменении файла в корневом каталоге.Два других события запускаются всякий раз, когда файл создается или удаляется.Кто-нибудь сталкивался с этой проблемой раньше, и если да, то можете ли вы дать некоторое представление об обходном пути?

Work Around (хотя и не правильный ответ)

Я пробовал несколько разных вещейпытаясь заставить это событие постоянно срабатывать, и только один, кажется, работает.У меня есть два сценария для событий изменения файла.Они в значительной степени идентичны, за исключением того, что они вызывают друг друга после завершения мероприятия.Ключ не гарантирует, что вы убьете наблюдателя, отменив регистрацию события перед вызовом второго сценария.

Сценарий 1

$folder = 'C:\extended_attributes\testing\DesignerVistaReorganize' # Enter the root path you want to monitor. 
$filter = '*.*'  # You can enter a wildcard filter here. 

# In the following line, you can change 'IncludeSubdirectories to $true if required.                           
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action { 
        echo "Script 1"
        $name = $Event.SourceEventArgs.Name 
        $changeType = $Event.SourceEventArgs.ChangeType 
        $timeStamp = $Event.TimeGenerated 
        $filePath    = -join($folder,"\",$name) | Out-String
        Unregister-Event FileChanged
        Write-Host "The file '$filePath' was $changeType at $timeStamp" -fore white 
        Out-File -FilePath C:\extended_attributes\testing\outlog.txt -Append -InputObject "The file '$filePath' was $changeType at $timeStamp"
        .\change_watcher_2.ps1
} 

Сценарий 2

$folder = 'C:\extended_attributes\testing\DesignerVistaReorganize' # Enter the root path you want to monitor. 
$filter = '*.*'  # You can enter a wildcard filter here. 

# In the following line, you can change 'IncludeSubdirectories to $true if required.                           
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 


Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action { 
        echo "Script 2"
        $name = $Event.SourceEventArgs.Name 
        $changeType = $Event.SourceEventArgs.ChangeType 
        $timeStamp = $Event.TimeGenerated 
        $filePath    = -join($folder,"\",$name) | Out-String
        Unregister-Event FileChanged
        Write-Host "The file '$filePath' was $changeType at $timeStamp" -fore white 
        Out-File -FilePath C:\extended_attributes\testing\outlog.txt -Append -InputObject "The file '$filePath' was $changeType at $timeStamp"
        .\change_watcher_1.ps1
} 

вывод

PS C:\extended_attributes\testing> C:\extended_attributes\testing\change_watcher_1.ps1

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
2      FileChanged                     NotStarted    False                                 ...                     



PS C:\extended_attributes\testing> The file 'C:\extended_attributes\testing\DesignerVistaReorganize\BusinessPrinting
' was Changed at 10/02/2018 10:46:43
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Editor_Warnings
' was Changed at 10/02/2018 10:47:09
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Mobile\Mobile_Control_Panel_2015_05_14.dvf
' was Changed at 10/02/2018 10:49:50
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Mobile
' was Changed at 10/02/2018 10:49:58
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Mobile\Gradients_Panels_Colors_Menus_2015_03_01.dvf
' was Changed at 10/02/2018 10:51:49
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Mobile\Tablet_Editor_2015_03_31.dvf
' was Changed at 10/02/2018 10:52:46
The file 'C:\extended_attributes\testing\DesignerVistaReorganize\Mobile
' was Changed at 10/02/2018 10:52:57

Мне бы действительно хотелось лучшего решения, чем это, поскольку я могу предвидеть многие проблемы, возникающие из-за этого подхода.

1 Ответ

0 голосов
/ 04 октября 2018

Я нашел гораздо лучшее решение, чем опубликовал в обновлении моих первоначальных вопросов.Если вы используете атрибут EnableRaisingEvents, как показано ниже.Событие будет срабатывать при каждом изменении файловой системы:

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'C:\extended_attributes\testing\DesignerVistaReorganize'
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true


$changed = Register-ObjectEvent $watcher "Changed" -Action {
    write-host "Changed: $($eventArgs.FullPath)"
    $creation_time = gi -Path $eventArgs.FullPath    | get-itemproperty | select -ExpandProperty CreationTime | Get-date -Format s
    $file_extension = gi -Path $eventArgs.FullPath   | get-itemproperty | select -ExpandProperty Extension    
    $file_base_name = gi -Path $eventArgs.FullPath   | get-itemproperty | select -ExpandProperty BaseName     
    $last_access_time = gi -Path $eventArgs.FullPath | get-itemproperty | select -ExpandProperty LastAccessTime | Get-date -Format s
    $last_write_time = gi -Path $eventArgs.FullPath  | get-itemproperty | select -ExpandProperty LastWriteTime | Get-date -Format s

    Write-Host "Creation time: $($creation_time)"
    Write-Host "ex: $($file_extension)"
    Write-Host "Name: $($file_base_name)"
    Write-Host "access: $($last_access_time)"
    Write-Host "write: $($last_write_time)"

    $object = New-Object System.Object
    $object | Add-Member -type NoteProperty –Name Extension –Value  $file_extension
    $object | Add-Member -type NoteProperty –Name BaseName –Value $file_base_name
    $object | Add-Member -type NoteProperty –Name Createtime –Value $creation_time
    $object | Add-Member -type NoteProperty –Name Accesstime –Value $last_write_time
    $object | Add-Member -type NoteProperty –Name Writetime –Value $last_access_time

    Write-Host "After Object"

    # Load the module
    Import-Module Mdbc
    # Connect the new collection test.test
    Connect-Mdbc . test test -NewCollection
    # add the objects to the collection
    $object | Add-MdbcData
    # Get all data as custom objects and show them in a table
    Get-MdbcData -As PS | Format-Table -AutoSize | Out-String
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...