需要一些PowerShell脚本的帮助,该脚本会监视文件夹以创建扩展名为.csv的新文件 检测到创建新文件时,会执行以下操作...
这就是我现在所拥有的......
#Define watcher; Set path to watch; Set filter on file type
$filewatcher = New-Object System.IO.FileSystemWatcher
$filewatcher.Path = "\\MYSERVER\MYCOMPANY\MYFOLDER"
$filewatcher.Filter = "*.csv"
#Define "move to" and "copy to" paths
$moveTo = "\\MYSERVER\MYCOMPANY\MYFOLDER\MyHistory"
$copyTo = "\\MYSERVER\MYCOMPANY\MYFOLDER\1_ToBeProcessed\MyImport.csv"
#Define actions after an Event is Detected
$action = {$files = Get-ChildItem -Path $filewatcher.Path -Filter filewatcher.Filter
foreach ($file in $files)
{
#Define variables for log file
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $file"
#Actions to take
Add-Content "\\MYSERVER\MYCOMPANY\MYFOLDER\3_Log\MyImportLog.txt" -value $logline
Copy-Item $file.FullName -Destination $copyTo
Move-Item $file.FullName -Destination $moveTo -Force
Invoke-Expression "& '\\MYSERVER\MYCOMPANY\MYFOLDER\4_Scripts\PSscriptToRunBATfile.ps1'"
#Pause the script for 60 seconds to allow it to finish posting the import before going to the next record
Start-Sleep -Seconds 60
}
}
#Decide which events should be watched and set check frequency
$onCreated = Register-ObjectEvent -InputObject $filewatcher -EventName "Created" -SourceIdentifier FileCreated -Action $action
答案 0 :(得分:3)
我建议不要循环,而是在创建/更改文件时处理它们。也许如果你有很多文件开头,你可以:
(a)首先循环(仅一次循环)。然后启用文件观察程序,以便在此之后对文件进行更改。
(b)启用文件观察器,使用FileChanged& FileCreated,然后“触摸”所有文件以触发您的代码。
# based on the script by By BigTeddy 05 September 2011
# simplified by Andy Myatt, to use one script block
# https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b
param(
[string]$folderToWatch = "D:\Temp"
, [string]$filter = "*.*"
, [string]$logFile = "D:\Temp\Temp2\filewatcher.log"
)
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $folderToWatch, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
# This script block is used/called by all 3 events and:
# appends the event to a log file, as well as reporting the event back to the console
$scriptBlock = {
# REPLACE THIS SECTION WITH YOUR PROCESSING CODE
$logFile = $event.MessageData # message data is how we pass in an argument to the event script block
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "$timeStamp|$changeType|'$name'" -fore green
Out-File -FilePath $logFile -Append -InputObject "$timeStamp|$changeType|'$name'"
# REPLACE THIS SECTION WITH YOUR PROCESSING CODE
}
# Here, all three events are registered. You need only subscribe to events that you need:
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -MessageData $logFile -Action $scriptBlock
Register-ObjectEvent $fsw Deleted -SourceIdentifier FileDeleted -MessageData $logFile -Action $scriptBlock
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -MessageData $logFile -Action $scriptBlock
# To stop the monitoring, run the following commands:
# Unregister-Event FileDeleted ; Unregister-Event FileCreated ; Unregister-Event FileChanged
#This script uses the .NET FileSystemWatcher class to monitor file events in folder(s).
#The advantage of this method over using WMI eventing is that this can monitor sub-folders.
#The -Action parameter can contain any valid Powershell commands.
#The script can be set to a wildcard filter, and IncludeSubdirectories can be changed to $true.
#You need not subscribe to all three types of event. All three are shown for example.
答案 1 :(得分:1)
我认为您可能会遇到某种文件锁定问题,但如果不知道PSscriptToRunBATfile.ps1
文件中的内容,则很难说清楚。
您的filewatcher将在NotifyEvents
的默认LastWrite | FileName | DirectoryName
上触发,并在此时循环目录。但是,您的get-childitem
命令不一定按照复制它们的顺序返回文件。
更好的解决方案是让您根据$Event
对象执行操作并更改PS1文件,将导致事件的文件作为输入参数:
$action = {$file = $Event.SourceEventArgs.FullPath
#Define variables for log file
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $file"
#Actions to take
Add-Content "\\MYSERVER\MYCOMPANY\MYFOLDER\3_Log\MyImportLog.txt" -value $logline
Copy-Item $file -Destination $copyTo
Move-Item $file -Destination $moveTo -Force
Invoke-Expression "& '\\MYSERVER\MYCOMPANY\MYFOLDER\4_Scripts\PSscriptToRunBATfile.ps1' -InputFile $file"
}
注意:您可能希望将InternalBufferSize
提高到默认值8k以上,这样您就不会错过任何更改:
$filewatcher.InternalBufferSize = 32kb