【问题标题】:Powershell monitor multiple directoriesPowershell 监控多个目录
【发布时间】:2014-04-11 07:29:32
【问题描述】:

注意:运行 PowerShell v3

我有一个目录设置,目前是:

\ftproot\001\converted
\ftproot\001\inbound
\ftproot\001\pdf

\ftproot\002\converted
\ftproot\002\inbound
\ftproot\002\pdf

\ftproot\xxx\converted
\ftproot\xxx\inbound
\ftproot\xxx\pdf

每个 FTP 用户都映射到一个入站目录。如果这使解决方案更容易,则可以更改结构

\ftproot\converted\001
\ftproot\converted\002
\ftproot\converted\xxx

\ftproot\inbound\001
\ftproot\inbound\002
\ftproot\inbound\xxx

\ftproot\pdf\001
\ftproot\pdf\002
\ftproot\pdf\xxx

我需要监控 TIFF 文件的每个入站目录,并在添加新 FTP 用户和入站目录时获取它们(遵循相同的结构),因此我不打算为每个新用户修改脚本。

脚本目前是这样的:

$fileDirectory = "\ftproot";
$folderMatchString = "^[0-9]{3}$";
$inboundDirectory = "inbound";
$filter = "*.tif";

$directories = dir -Directory $fileDirectory | Where-Object {$_.Name -match $folderMatchString}

foreach ($directory in $directories) { 

  $sourcePath = "$fileDirectory\$directory\$inboundDirectory"

  if(Test-Path -Path $sourcePath -pathType container ) { 

        // Problem is here //
        $fsw = New-Object IO.FileSystemWatcher $sourcePath, $filter -Property @{
            IncludeSubdirectories = $false
            NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
        }

  }

}


$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {

 $path = $Event.SourceEventArgs.FullPath
 $name = $Event.SourceEventArgs.Name
 $changeType = $Event.SourceEventArgs.ChangeType
 $timeStamp = $Event.TimeGenerated

 Write-Host "The file '$name' was $changeType at $timeStamp"

}

我将 New-Object IO.FileSystemWatcher 包装在一个循环中,因此在上述示例的情况下,只会监视最后一个目录。

是否可以创建一个数组或列表或类似的 IO.FileSystemWatcher?如果是这样,我如何为每个实例编写 Register-ObjectEvent 代码?最终将有超过一百个目录需要监控(并且增长缓慢),但同样的操作适用于所有入站文件夹。

或者是否有更好的解决方案我应该研究?

每个 FTP 用户的过程都是相同的,文件需要在可以链接回用户的目录中说明。将监视入站目录中上传的 TIFF 文件,当检测到文件时,多页 TIFF 被拆分为单个文件并移动到转换后的目录中,当在转换中检测到新文件时,对 TIFF 文件执行另一个操作,然后它被转换为 PDF 并移动到 PDF 文件夹中。

谢谢

解决方案

$result = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {

$dir = $_;

$fsw = New-Object IO.FileSystemWatcher $dir, $filter -Property @{
            IncludeSubdirectories = $false
            NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
        };

$oc = Register-ObjectEvent $fsw Created -Action {

 $path = $Event.SourceEventArgs.FullPath;
 $name = $Event.SourceEventArgs.Name;
 $changeType = $Event.SourceEventArgs.ChangeType;
 $timeStamp = $Event.TimeGenerated;

 Write-Host "The file '$name' was $changeType at $timeStamp";

};

new-object PSObject -Property @{ Watcher = $fsw; OnCreated = $oc };

});

【问题讨论】:

    标签: powershell filesystemwatcher


    【解决方案1】:

    是否可以创建一个数组或列表或类似的 IO.FileSystemWatcher?

    是的。使用管道类似于:

    $fsws = $directoriesOfInterest | ? { Test-Path -Path $_ } | % {
              new-object IO.FileSystemWatcher …
            }
    

    如果创建了多个观察者,$fsws 将是一个数组(如果只有一个,那将是浪费,如果没有,$null)。要始终获取数组,请将管道放入@(…)

    $fsws = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {
              new-object IO.FileSystemWatcher …
            })
    

    如果是这样,我如何为每个实例编写 Register-ObjectEvent 代码?

    将对象注册放在同一个循环中,同时返回观察者和事件注册:

    $result = @($directoriesOfInterest | ? { Test-Path -Path $_ } | % {
                # $_ may have a different value in code in inner pipelines, so give it a
                # different name.
                $dir = $_;
                $fsw = new-object IO.FileSystemWatcher $dir, …;
                $oc =  Register-ObjectEvent $fsw Created …;
                new-object PSObject -props @{ Watcher = $fsw; OnCreated = $oc };
              })
    

    $result 将是这两个属性的对象数组。

    请注意,传递给Register-ObjectEvent-Action 代码可以引用$fsw$dir,从而知道哪个观察者触发了它的事件。

    【讨论】:

    • 谢谢,终于到了。我会用解决方案更新我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2010-10-05
    相关资源
    最近更新 更多