Powershell-监视多个文件夹,使用文件运行多个进程

Powershell-监视多个文件夹,使用文件运行多个进程,powershell,foreach,hashtable,filesystemwatcher,multiple-instances,Powershell,Foreach,Hashtable,Filesystemwatcher,Multiple Instances,因此,我有一个脚本,用于以下目的: 如果某个文件出现在文件夹中,只需将其移动到该子文件夹上方的文件夹即可*例如:从c:\My\u Documents\a>c:\My\u Documents* 每次发生上述情况时,文件名和尝试次数都存储在哈希表中。同一个文件出现3次后,该文件将从结构移动到完全不同的文件夹,并向相应的接收者发送电子邮件*例如:c:\My\u Documents\a>c:\FailedFolder\* 然后删除哈希表中的文件记录。此外,每10分钟清除一次整个哈希表 这是可行的,我现

因此,我有一个脚本,用于以下目的:

  • 如果某个文件出现在文件夹中,只需将其移动到该子文件夹上方的文件夹即可*例如:从c:\My\u Documents\a>c:\My\u Documents*
  • 每次发生上述情况时,文件名和尝试次数都存储在哈希表中。同一个文件出现3次后,该文件将从结构移动到完全不同的文件夹,并向相应的接收者发送电子邮件*例如:c:\My\u Documents\a>c:\FailedFolder\*
  • 然后删除哈希表中的文件记录。此外,每10分钟清除一次整个哈希表
  • 这是可行的,我现在的问题是,我需要扩展它,以便脚本对以完全相同的方式设置但不重叠的多个文件夹执行此操作*例如:c:\My\u Documents\a>c:\My\u 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 
    

    没有必要自己实施这样的事情。你可以使用它,这是非常容易使用的。您也可以尝试RubyOriginalGuard,如果您与它兼容的话,它还附带了很多插件


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

    没有必要自己实施这样的事情。你可以使用它,这是非常容易使用的。您也可以尝试RubyOriginalGuard,如果您与它兼容的话,它还附带了很多插件


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

    由于不清楚自己想要实现什么目标,所以给你具体的指导可能有点困难!但是,您可能希望了解可以使用所需的任何参数调用的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
    

    由于不知道你想要实现什么,给你具体的指导可能有点困难!但是,您可能希望了解可以使用所需的任何参数调用的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只是变量名,这样做是为了允许您在脚本的稍后阶段停止查看文件夹(如果需要)。很抱歉,这些变量的名称可能会更好一些:)获取已注册filesystemwatcher的错误。我想你不能用这种方式传递多个文件夹。要确认我是否注释掉$f2,我可以让它编译。我现在要试试这个。阅读代码是否可以在我指定的$f格式的文件夹中使用?例如$f3、$f4、$f5等?使用函数的想法是可以监视任意数量的文件夹。上面的$f1和$f2只是变量名,这样做是为了允许您在脚本的稍后阶段停止查看文件夹(如果需要)。很抱歉,这些变量的名称可能会更好一些:)获取已注册filesystemwatcher的错误。我想你不能用这种方式传递多个文件夹。要确认我是否注释掉$f2,我可以让它编译。