【问题标题】:Powershell - Watch multiple folder, run multiple processes with filesPowershell - 监视多个文件夹,使用文件运行多个进程
【发布时间】:2016-08-10 07:23:44
【问题描述】:

所以我有一个为以下目的设置的脚本:

  1. 如果文件出现在文件夹中,只需将其移动到该子文件夹上方的文件夹中。 *例如:从 c:\My_Documents\a > c:\My_Documents* 移动
  2. 每次发生上述情况时,文件名和尝试次数都会存储在哈希表中。一旦相同的文件出现 3 次,该文件就会移动到与结构完全不同的文件夹中,并且会向相应的收款人发送一封电子邮件。 *例如:c:\My_Documents\a > c:\FailedFolder\ *
    1. 然后删除哈希表中文件的记录。此外,每 10 分钟清除一次整个哈希表。

这可行,我现在的问题是我需要扩展它,以便脚本对以完全相同的方式设置但不重叠的多个文件夹执行此操作。 *例如:c:\My_Documents\a > c:\My_Documents\ && c:\randomFolder\a > c:\randomFolder\ && c:\AnotherRandomFolder\a > c:\AnotherRandomFolder\ *

请有人帮我实现这个目标吗?

请看我当前的代码:

$global:folder = 'C:\Users\random\Documents\IUR Test\r' # Enter the root   path you want to monitor. 
$global:origin = 'C:\Users\random\Documents\IUR Test'
$filter = '*.*'  # You can enter a wildcard filter here. 
$global:Failedfolder = 'C:\Users\random\Documents\Failed' 
$global:Files = @{}
$timer = New-Object Timers.Timer
$timer.Interval = 600000     # fire every 10 minutes
$timer.AutoReset = $true  # Enable the event again after its been fired
$timer.Enabled = $true

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

Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier HashMapClear -Action {
    $global:Files.clear()
}

Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
    ForEach ($file in (gci $global:folder)) 
    {
        $fName = $file.Name

        if(-not $global:Files.ContainsKey($fName))
        {
            $global:Files.Add($fName,1)             
            Move-Item $File.Fullname $global:origin -force

        }
        Elseif($global:Files.Get_Item($fName) -lt 3)
        {
            $global:Files.Set_Item($fName,++$global:Files.Get_Item($fName))             
            Move-Item $File.Fullname $global:origin -force
        }
        Else
        {
            $global:Files.Remove($fName) 
            Move-Item $File.Fullname $global:Failedfolder -force

            #### Send error email
        }
    }
} 

# To stop the monitoring, run the following commands: 
# Unregister-Event FileCreated 
# Unregister-Event HashMapClear 

【问题讨论】:

    标签: powershell foreach hashtable filesystemwatcher multiple-instances


    【解决方案1】:

    没有必要自己实现这样的事情。您可以使用非常容易使用的PowershellGuard。你也可以试试 ruby​​ original Guard,如果你对它也有很多插件。

    PowershellGuard 基本上可以做您想做的事情,因此如果您想以自己的方式重新实现它,可以查看其源代码以获取详细信息。

    【讨论】:

      【解决方案2】:

      不知道您要达到的具体目标,给您具体的指导可能有点困难!但是,您可能想查看可以使用所需的任何参数调用的 Powershell 函数(见下文)

      警告:这尚未运行或测试:D

      $files = @{}
      
      $timer = New-Object Timers.Timer
      $timer.Interval = 600000     # fire every 10 minutes
      $timer.AutoReset = $true  # Enable the event again after its been fired
      $timer.Enabled = $true
      
      $email:From = 'thisisanexample@test.com'
      $email:to = 'thisisanexample@test.com'
      $email:Subject = 'Failed SJPM File'
      $email:SMTPServer = 'thisisatest.qa.test.com'
      $email:SMTPPort = 25
      
      function sendFailureEmail([string]$filename, [string]$folder)
      {
          $message = 'The file' + $filename + ' located in ' + $folder + ' has failed to process after 3 attempts, please review the file.'
          send-MailMessage -From $email:From -to $email:to -Subject $email:Subject -Body $message -SmtpServer $email:SMTPServer -port $email:SMTPPort -Cc $email:From
      }
      
      function monitorDirectory([string]$sourceDirectory, [string]$targetDirectory, [string]$failureDirectory, [string]$filter="*.*")
      {
          # In the following line, you can change 'IncludeSubdirectories to $true if required.                           
          $fsw = New-Object IO.FileSystemWatcher $sourceDirectory, $filter -Property @{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName,LastWrite'} 
      
          Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
              ForEach ($file in (gci $sourceDirectory)) 
              {
                  $fName = $file.FullName
      
                  if(-not $files.ContainsKey($fName))
                  {
                      # We have not seen this file before
                      $files.Add($fName, 1)               
                      Move-Item $File.Fullname $targetDirectory -force
      
                  }
                  Elseif($files.Get_Item($fName) -lt 3)
                  {
                      # We have seen this file once or twice before
                      $files.Set_Item($fName, ++$files.Get_Item($fName))              
                      Move-Item $File.Fullname $targetDirectory -force
                  }
                  Else
                  {
                      # This is the third time we've seen this file, there an error has occurred
                      $files.Remove($fName) 
                      Move-Item $File.Fullname $failureDirectory -force
      
                      sendFailureEmail $fName $failureDirectory
                  }
              }
          } 
      
          $fsw
      }
      
      Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier HashMapClear -Action {
          # Clear the file list every x minutes
          $files.clear()
      }
      
      $f1 = monitorDirectory 'C:\Users\random\Documents\IUR Test\r' 'C:\Users\random\Documents\IUR Test' 'C:\Users\random\Documents\Failed'
      $f2 = monitorDirectory 'C:\Users\random\Documents\Test2\z' 'C:\Users\random\Documents\Test2' 'C:\Users\random\Documents\Failed'
      
      # can unregister filewatching and timers if necessary
      

      【讨论】:

      • 我现在要试试这个。阅读代码是否适用于我使用 $f 格式指定的多个文件夹?即 $f3、$f4、$f5 等?
      • 使用函数的想法是可以监控任意数量的文件夹。上面的 $f1 和 $f2 只是变量名,这样做是为了让您在脚本的稍后位置停止查看文件夹(如果需要)。抱歉,这些变量的命名可以更好一些:)
      • 收到文件系统观察器已注册的错误。我认为您不能以这种方式传递多个文件夹。
      • 确认如果我注释掉 $f2 我可以让它编译。
      猜你喜欢
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      相关资源
      最近更新 更多