文件监视器存档器 Powershell
File Monitor Archiver Powershell
我已经编写了一些检查新文件的 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,别问我怎么做,但我知道会发生)它会停止工作。
为什么我在任何地方都看不到任何错误?如果我在代码中放置 Write-Host
,我可以看到它在 ISE 中显示输出,但我没有看到上述情况发生时的任何错误。
如何让它正常工作?我可以说这个错误是因为我的代码试图从字符串中取 -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
你所拥有的是一个很好的例子,说明为什么路径应该 永远不会 使用字符串连接来构建。最有可能发生的情况是您定义 $folder
时没有尾随(反)斜杠:
$folder = 'C:\some\folder'
所以声明
$oldfilelocation = ($folder + $oldfilename)
构建这样的路径:
C:\some\folder85080-00-02.pdf
# ^^
# `- lack of backslash here!
不存在,所以 Test-Path
returns $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"
}
}
}
我已经编写了一些检查新文件的 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,别问我怎么做,但我知道会发生)它会停止工作。
为什么我在任何地方都看不到任何错误?如果我在代码中放置
Write-Host
,我可以看到它在 ISE 中显示输出,但我没有看到上述情况发生时的任何错误。如何让它正常工作?我可以说这个错误是因为我的代码试图从字符串中取 -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
你所拥有的是一个很好的例子,说明为什么路径应该 永远不会 使用字符串连接来构建。最有可能发生的情况是您定义 $folder
时没有尾随(反)斜杠:
$folder = 'C:\some\folder'
所以声明
$oldfilelocation = ($folder + $oldfilename)
构建这样的路径:
C:\some\folder85080-00-02.pdf # ^^ # `- lack of backslash here!
不存在,所以 Test-Path
returns $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"
}
}
}