Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Сценарии для Windows

Модерирует : KLASS, IFkO

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

YuS 2



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Код:
<# Garry Geller http://www.cyberforum.ru/powershell/thread1561433.html#post10781770
mod by YuS (скорректирована реакция кода на появление двойных и более событий по одному и тому же файлу)
29.05.2019
Набор функций-командлетов для наблюдения за изменениями файлов\директорий на основе
класса FileSystemWatcher. Для удобства использования можно поместить их в файл  
powershell профиля - тогда они будут доступны наравне с прочими командами сразу из
консоли, либо поместить файл модуля watchdog.ps1 в папку powershell модулей.
#>
# required -version 3.0
 
set-alias swatch Set-Watch  
function Set-Watch() {
<#
    .SYNOPSIS
        Запускает фоновый процесс отслеживания изменений файловой системы на основе класса FileSystemWatcher
    .DESCRIPTION
        Существующие фильтры отслеживаемых изменений:
        NotifyFilters.CreationTime
        NotifyFilters.LastAccess
        NotifyFilters.LastWrite
        NotifyFilters.FileName
        NotifyFilters.DirectoryName
        NotifyFilters.Security
        NotifyFilters.Size
        NotifyFilters.Attributes
    .EXAMPLE
        PS C:\> . .\watchdog.ps1
        PS C:\> swatch -path "d:\test" -filter "*.txt"  -event Created,Deleted  
    .EXAMPLE    
        PS C:\> swatch -path "d:\test" -filter "*.txt"  -event Created,Deleted  -command "start-process notepad.exe" -test
    .LINK  
        https://msdn.microsoft.com/ru-ru/library/system.io.filesystemwatcher(v=vs.110).aspx
    .LINK
        Remove-Watch
    .LINK
        Disable-Watch
    .LINK  
        Enable-Watch
    .LINK
        Get-Watch
#>
 
    [CmdletBinding()]  
    param(
        # путь до отслеживаемой директории
        [parameter(Mandatory=$true,Position=1)]
        [alias("p")][string]$path,
        [parameter(Mandatory=$true,Position=2)]
        # фильтр типов отслеживаемых файлов
        [alias("f")][string]$filter="*.*",
        # задает тип отслеживаемых изменений
        [alias("n")][string]$notify='FileName, LastWrite',
        # нужно ли рекурсивно отслеживать субдиректории  
        [alias("r")][switch]$recurse,
         # событи(e|я) на котор(ое|ые) нужно реагировать
        [parameter(Mandatory=$true,Position=3)]
        [ValidateSet("Created","Deleted","Renamed","Changed")]
        [alias("e")][string[]]$events,
        [parameter(Mandatory=$false)]
        # строковые идентифкаторы событий
        [alias("name")][string[]]$id=@(),
        # действие которое нужно выполнить - передается одной строкой вместе с аругментами
        [string]$command,
        # вывод переданных аргументов
        [switch]$test
    )
 
    $fsw = New-Object IO.FileSystemWatcher -Property @{
        Path = $path
        Filter = $filter
        IncludeSubdirectories = $recurse
        NotifyFilter = [IO.NotifyFilters]$notify
    }
 
    Set-Variable __watcher -Value $fsw -Scope Script
    Set-Variable command -Value $command -Scope Script
    
    $action = {
        $fullPath   = $event.SourceEventArgs.FullPath
        $fileName   = $event.SourceEventArgs.Name
        $changeType = $event.SourceEventArgs.ChangeType
        $timeStamp  = $event.TimeGenerated
        if (!$tmptime){$tmptime = $timeStamp}
        $dif = ((get-date($timeStamp)) - (get-date($tmptime))).totalseconds
        #write-host $dif -for red
        if ($dif -gt 1.0 -or $changeType -ne $tmpType -or $fileName -ne $tmpName){
            #$command  = Get-Variable command -valueOnly -Scope Global
            Write-Host $('The file "{1}" was {2} at {0:dd.MM.yyyy HH:mm:ss,ffff}' -f $timeStamp,$fileName,$changeType) -for green
            if ($command) {
                Invoke-Expression $command  
            }
            $tmptime,$tmpType,$tmpName = $timeStamp,$changeType,$fileName
        }
    }
 
    $calls = [Collections.ArrayList]::new()
 
    for ($i=0; $i -lt $events.length; $i++) {
        if ($id.Length -eq $events.Length){
            $jobname = $id[$i]
        } else {
            $jobname = $events[$i]
        }
 
        $params = @{SourceIdentifier = $jobname; Action = $action}
        if ((get-job).Name -ccontains $jobname) {
            Write-Host "Задание $jobname уже существует" -f Red
        } else {
            $regEvent = Register-ObjectEvent $fsw $events[$i] @params
            $calls.Add($regEvent)|Out-Null  
        }
    }
 
    # выводим аргументы функции
    if ($test) {
        $MyInvocation.BoundParameters.GetEnumerator() | Foreach {  
            echo "-$($_.Key): $($_.Value)"
        }
        $MyInvocation.UnboundArguments
        '----------------------------'
    }
    return $calls
}
 
set-alias unwatch Disable-Watch
function Disable-Watch() {
<#
    .SYNOPSIS
        Временно отключает обработку событий
    .LINK  
        Enable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch
    .LINK
        Set-Watch
#>
    if ($__watcher) {
        $__watcher.EnableRaisingEvents = $false
        Write-Host "Отслеживание событий отключено" -f Yellow -b DarkGray
    }
}
 
set-alias watch Enable-Watch
function Enable-Watch() {
<#
    .SYNOPSIS
        Включает обработку событий
    .LINK
        Disable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch
    .LINK
        Set-Watch
#>
    if ($__watcher) {
        $__watcher.EnableRaisingEvents = $true
        Write-Host "Отслеживание событий включено" -f Green -b DarkGray
    }
}
 
set-alias gwatch Get-Watch
function Get-Watch() {
<#
    .SYNOPSIS
        Получает сторожевой объект для установки новых свойств (если указаны)
        и возвращает его  
    .EXAMPLE
        PS C:\> (gwatch).filter = "*.*"     # установить новый файловый фильтр
        PS C:\> gwatch -Filter *.*
    .EXAMPLE
        PS C:\> (gwatch).path= "c:\windows" # установить новую директорию для отслеживания
        PS C:\> gwatch -Path "c:\windows"  
    .EXAMPLE
        PS C:\> gwatch -NotifyFilter "Filename,LastWrite,LastAccess" -Filter "*.*"
    .EXAMPLE
        PS C:\> gwatch -IncludeSubdirectories
        PS C:\> gwatch -IncludeSubdirectories:$false
    .OUTPUTS
        FileSystemWatcher  
    .LINK
        Set-Watch
    .LINK
        Disable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch  
#>
    param(
        [string]$Path,
        [string]$Filter,
        [switch][Boolean]$IncludeSubdirectories,
        [string]$NotifyFilter
    )
 
    if ($__watcher -eq $null) {
        Write-Host "Объект FileSystemWatcher не определен" -f Red
    } else {  
        $type_watcher = $__watcher.gettype()
        $MyInvocation.BoundParameters.GetEnumerator() | %{  
            $key = $_.Key
            $value = $_.Value
            if ($key -eq "NotifyFilter") {
                $value = [IO.NotifyFilters]$value
            }
            if ($key -eq "IncludeSubdirectories") {
                [Boolean]$value = $value
            }
            $prop = $type_watcher.GetProperty($key)
            $prop.SetValue($__watcher, $value)
        }
        return $__watcher
    }
}
 
set-alias rwatch Remove-Watch  
function Remove-Watch() {
<#
    .SYNOPSIS
        Удаляет задание по списку имен, либо все
    .EXAMPLE
        PS C:\> rwatch Created,Deleted    # удалить задания по именам  
    .EXAMPLE
        PS C:\> rwatch                    # удалить все задания
    .LINK  
        Set-Watch
#>
 
    [CmdletBinding()]
    param(
        [string[]]$names
    )
    
    if ($names.Length -eq 0) {  
        $names = (get-job).Name
    }
 
    foreach ($jobname in $names) {
        if ((get-job).Name -ccontains $jobname) {
            Unregister-Event $jobname -Force
            Remove-Job -Name $jobname -Force
            Write-Host "Задание $jobname удалено" -f Green -b DarkGray
        } else {
            Write-Host "Задание $jobname не найдено" -f Yellow -b DarkMagenta
        }
    }
    Set-Variable __watcher -Value $null -Scope Script
}

Всего записей: 3218 | Зарегистр. 03-02-2009 | Отправлено: 19:54 24-11-2020
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Сценарии для Windows


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru