文件监视器Archiver Powershell

时间:2016-10-10 16:45:44

标签: powershell filesystemwatcher

我编写了一些PowerShell来检查新文件,当创建新文件时,它会运行一个操作。

操作是检查文件名并检查以前的版本,如果以前的版本将先前版本移动到存档文件夹。以前的版本定义如下:

文件名结构:xxxx-xxxx-xx.pdf

首先xxxx可以是任意数量的字符+数字。

第二个xxxx可以是任意数量的字符+数字。

第三部分只是数字00到99,例如01 02 03

因此,如果我放入文件85080-00-02.pdf并且存在85080-00-01.pdf,它会将后一个文件移动到存档文件夹,现在这一切都正常,我现在拥有的代码

该系统将由标准工程人员使用,因此我需要确保满足所有用户错误。当我在第3部分中使用字符运行我的代码时,例如85080-00-0t(想象有人意外地输入了t而不是5,不要问我怎么但我知道会发生这种情况)它会停止工作。

  1. 为什么我在任何地方都没有看到任何错误?如果我在代码中加了一个Write-Host,我可以看到它在ISE中显示输出但我没有看到上述情况发生时的任何错误。

  2. 如何让它正常工作?我可以告诉错误是因为我的代码试图从字符串中得到-1,这显然会导致问题。

  3. 所以我该怎么说:

    如果$olddw = 00-99之间的任何数字继续执行代码,则不执行任何操作。

    # Enter the root folder you want to monitor
    $folder = **FOLDER LOCATION**
    $archivefolder = **ARCHIVE FOLDER LOCATION**
    
    # Enter the log file location
    $log = **LOG LOCATION**
    
    # You can enter a wildcard filter here. 
    $filter = '*.*'
    $fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{
        IncludeSubdirectories = $false;
        NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
    }
    
    #New file ObjectEvent
    Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
        #Get new filename and create log
        $name       = $Event.SourceEventArgs.Name 
        $changeType = $Event.SourceEventArgs.ChangeType 
        $timeStamp  = $Event.TimeGenerated  
        Out-File -FilePath $log -Append -InputObject "The file '$name' was $changeType at $timeStamp"
    
        #Set old filename 
        $oldname = $name.Substring(0, $name.Length-4)
        $olddw = "{0:D2}" -f (($oldname.Substring($oldname.Length - 2)) - 1)
        $oldfilename = ($oldname.Substring(0, $oldname.Length-2) + $olddw + ".pdf")
        $oldfilelocation = ($folder + $oldfilename)
    
        #Check if old filename exists if so move it to archive folder
        $FileExists = Test-Path $oldfilelocation
        if ($FileExists -eq $true) {
            Move-Item $oldfilelocation $archivefolder
            Out-File -FilePath $log -Append -InputObject "The file '$oldfilename' was Archived at $timeStamp"
        } else {
            # do nothing
        }
    }
    
    #To view current ObjectEvent's
    #Get-EventSubscriber
    
    #To stop current ObjectEvent
    #Unregister-Event FileCreated 
    

1 个答案:

答案 0 :(得分:2)

你所拥有的是一个主要的例子,为什么路径永远不会使用字符串连接来构建。最可能发生的是您定义$folder而没有尾随(后退)斜杠:

$folder = 'C:\some\folder'

这样的陈述

$oldfilelocation = ($folder + $oldfilename)

构造一个这样的路径:

C:\some\folder85080-00-02.pdf
#            ^^
#             `- lack of backslash here!

不存在,因此Test-Path会返回$false并且不会移动任何内容。

更改此行:

$oldfilelocation = ($folder + $oldfilename)

进入这个:

$oldfilelocation = Join-Path $folder $oldfilename

问题应该消失。

更好的解决方案是使用FileInfo对象(通过FullPath参数):

Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
    $name       = $Event.SourceEventArgs.Name
    $path       = $Event.SourceEventArgs.FullPath
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp  = $Event.TimeGenerated

    Out-File -FilePath $log -Append -InputObject "The file '$name' was $changeType at $timeStamp"

    $f = Get-Item $path

    $cutoff = $f.BaseName.Length - 2
    $olddw  = '{0:D2}' -f (($f.BaseName.Substring($cutoff)) - 1)
    $oldfilename = ($f.BaseName.Substring(0, $cutoff) + $olddw + $f.Extension)
    $oldfilelocation = Join-Path $f.Directory.FullName $oldfilename

    if (Test-Path $oldfilelocation) {
        Move-Item $oldfilelocation $archivefolder
        Out-File -FilePath $log -Append -InputObject "The file '$oldfilename' was Archived at $timeStamp"
    }
}

如果您还想在2位数索引中处理拼写错误,请执行以下操作:

Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
    $name       = $Event.SourceEventArgs.Name
    $path       = $Event.SourceEventArgs.FullPath
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp  = $Event.TimeGenerated

    Out-File -FilePath $log -Append -InputObject "The file '$name' was $changeType at $timeStamp"

    $f = Get-Item $path

    $cutoff = $f.BaseName.Length - 2
    $index  = $f.BaseName.Substring($cutoff)
    if ($index -like '[0-9][0-9]') {
        $oldindex = '{0:D2}' -f ([int]$index - 1)
        $oldfilename = ($f.BaseName.Substring(0, $cutoff) + $oldindex + $f.Extension)
        $oldfilelocation = Join-Path $f.Directory.FullName $oldfilename

        if (Test-Path $oldfilelocation) {
            Move-Item $oldfilelocation $archivefolder
            Out-File -FilePath $log -Append -InputObject "The file '$oldfilename' was Archived at $timeStamp"
        }
    }
}