2016-10-10 3 views
1

Я написал несколько PowerShell, который проверяет наличие новых файлов и когда создается новый файл, он запускает действие.File Monitor Archiver Powershell

Действие должно проверить имя файла и проверить предыдущую версию, если предыдущая версия перенесет предыдущую версию в папку архива. Предыдущей версии, определяется как, например: структура

имя файла: хххх-хххх-xx.pdf

Первый хххх может быть любое количество символов + чисел.

Второй xxxx может быть любым количеством символов + цифр.

Третья часть всегда имеет число от 00 до 99, например. 01 02 03

Так что если я закрою файл 85080-00-02.pdf и 85080-00-01.pdf, он переместит последний файл в папку архива, теперь все это работает ОК с кодом I есть на данный момент.

Эта система будет использоваться стандартными инженерными кадрами, поэтому я должен обеспечить, чтобы все ошибки пользователя удовлетворялись. Когда я запускаю свой код с символами в третьей части, например. 85080-00-0t (представьте, что кто-то случайно набрал t вместо 5, не спрашивайте меня, но я знаю, что это произойдет), он просто перестанет работать.

  1. Почему я не вижу ошибок нигде? Если я поместил Write-Host в код, я могу увидеть, что он отображает в ISE вывод, но я не вижу никаких ошибок, когда это происходит.

  2. Как я могу заставить это работать правильно? Я могу сказать, что ошибка связана с тем, что мой код пытается выполнить -1 из строки, что явно вызывает проблему.

Так как я могу сказать:

Если $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 

ответ

2

То, что вы есть яркий пример того, почему пути не должны никогда быть построены с использованием конкатенации. Что, скорее всего, происходит то, что вы определили $folder без завершающего (назад) слэш:

$folder = 'C:\some\folder' 

так, что заявление

$oldfilelocation = ($folder + $oldfilename) 

строит этот путь:

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

который Безразлично 't существует, поэтому 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" 
     } 
    } 
} 
+0

После обеда Ansgar перемещение файлов прекрасно работает. Я сказал, что в моем посте. Я жестко закодировал ссылки в моей, я только что изменил их для переменных в коде, чтобы их можно было легко прочитать. Вторая часть вашего кода работает именно так, как мне хотелось бы поблагодарить за ваш вклад. ($ Index -like '[0-9] [0-9]') был тем, что я искал! благодаря – bepster