2016-09-08 12 views
0

拡張子が.csvの新しいファイルを作成するフォルダを監視するPowerShellスクリプトのサポートが必要です。
新規ファイルの作成は、次のアクションが行わ検出され ...ファイルのSystem.IO.FileSystemWatcherを使用した後でPowershellでファイルをループする

  1. 詳細は、ファイルのコピーが1_ToBeProcessed \」という名前の別のフォルダに送信されるログファイル
  2. に送られ、 MyImport.csv」(ファイルを注意してくださいMyImport.csvに変更されます)
  3. ファイルがディレクトリに移動し、 『(元のファイル名で)\ MYSERVER \ MyCompanyの\ MYFOLDER \ MyHistory』
  4. 式がに呼び出されます"\ MYSERVER \ MYCOMPANY \ MYFOLDER \ 1_ToBeProcessed"にあるファイルを取得してimporを実行する.batファイルを実行しますファイルをアプリケーションに挿入します。
  5. スクリプトは60秒間スリープして、次のファイルを処理する前にインポートが完了できるようにします。 このスクリプトは、スクリプトの実行中に別のファイルが作成されない限りうまくいきます。
    同じタイプの複数のファイルが同時にウォッチフォルダにヒットすることがあります。したがって、スクリプトは5つのファイルをループしていて、次に別のファイルがディレクトリに入る可能性があります。それが起きると、スクリプトがやり直され、ファイルをループし始めているように見えますが、同じファイルを何度も繰り返してループし続けます。 私は、このスクリプトで間違っていることについて、誰かが私に正しい方向を向けることを期待しています。新しいファイルが追加されたため、現在のループで作業中のファイルを完成させてから再開するにはどうすればよいですか? ご提供いただけるお手伝いをさせていただきますようお願い申し上げます。

これは私が現在持っているものです...私は、彼らが作成されると、むしろファイルを処理、ループしないことをお勧めしたい

#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

は/変更します。たぶん、たくさんのファイルがある場合は、

(a)ループが最初に(かつては1回のみ)です。その後、ファイルウォッチャーを有効にしてから、その後にファイルが変更されます。

(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. 
+0

感謝を!遅れた応答のために申し訳ありません...胃のバグを得ました!もともと私が解決策を研究していた時、私はBigTeddyのポストを走りました。私はPowershellを初めて使っていて、まだ学習しています。最終的に、私はそれが私が学び、理解したプロセスだったので、ループして行きました。私は日時順に行きたいと思っていましたが、私はそれをどうやって脳を包んでいませんでした。私は戻ってこれをもう少し調べて、私がそれを私のために働かせることができるかどうかを見ます。ありがとうございました! – mdgaw

+0

問題はありません、@ mdgaw、答えとしてマークするか、またはアップヴォートしてください。 – TechSpud

0

私はあなたがファイルロックの問題のいくつかの並べ替えを取得するかもしれないと思うが、それはあなたのPSscriptToRunBATfile.ps1ファイルに何があるかを知らずに言うのは難しいです。

ファイルウォッチャーがデフォルトのNotifyEventsLastWrite | FileName | DirectoryName)で起動し、その時点でディレクトリをループします。ただし、get-childitemコマンドでは、必ずコピーされるのと同じ順序でファイルが返されるわけではありません。

$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" 
} 

注:

より良い解決策は、あなたの$Eventオブジェクトに基づいて作業を行うと、あなたのPS1ファイルは、入力パラメータとしてイベントを発生させたファイルを取る変更するには、あなたのアクションを持っているでしょうあなたは増やすことをお勧めしますデフォルト8K上記InternalBufferSizeはあなたがすべての変更をお見逃しなく。

$filewatcher.InternalBufferSize = 32kb 
+0

まず、私がPowershellを初めて使ったと言いましょう。したがって、私はまだイベントについて学び、私はそれらと何ができるのですか? PSscriptToRunBATfile.ps1ファイルの内容は、あるプログラムで作成されたファイルを別のプログラムに自動的にインポートすることを目的としています。インポートを実行するシステム生成マクロを実行します。別のファイルがディレクトリにヒットしたときに "$ action"がやり直されたように見えるので、vbscriptを使用して5分ごとにファイルウォッチャーディレクトリにインポートファイルを移動しました。輸入は、次のバッチが来る前に完了しています。あなたの助けをありがとう! – mdgaw

関連する問題