フォルダーを監視し、ファイルが作成されるたびに何らかのアクションを実行する必要があります。私には2つの解決策があります.1つはWMIを使用しており、このフィルター(.MOF
ファイルまたは永続的なMWIイベントバインディングを登録するPowershellスクリプトから呼び出されます)を使用して、毎秒フォルダーをポーリングできます:
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA "Cim_DirectoryContainsFile" AND TargetInstance.GroupComponent="Win32_Directory.Name='C:\\test'"
スクリプト例:
$query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA "Cim_DirectoryContainsFile" AND TargetInstance.GroupComponent="Win32_Directory.Name='C:\\test'"
"@
#Set up hash table for splatting
$wmiParams = @{
Computername = $env:COMPUTERNAME
ErrorAction = 'Stop'
NameSpace = 'root\subscription'
}
######################################################################################################################### Filter
#Creating a new event filter
$wmiParams.Class = '__EventFilter'
$wmiParams.Arguments = @{
Name = 'WatchFiles'
EventNamespace = 'root\CIMV2'
QueryLanguage = 'WQL'
Query = $query
}
$filterResult = Set-WmiInstance @wmiParams
######################################################################################################################### Consumer
$wmiParams.Class = 'ActiveScriptEventConsumer'
$wmiParams.Arguments = @{
KillTimeout = 0
MachineName = $env:COMPUTERNAME
ScriptingEngine = 'VBScript'
ScriptText =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\Log.log", 8, True)
objFile.WriteLine "hellohellohellohellohellohello"
objFile.Close
"@
ScriptFileName = $null
Name = 'ActiveScriptEventConsumer'
}
$consumerResult = Set-WmiInstance @wmiParams
######################################################################################################################### Binding
$wmiParams.Class = '__FilterToConsumerBinding'
$wmiParams.Arguments = @{
Filter = $filterResult
Consumer = $consumerResult
}
$bindingResult = Set-WmiInstance @wmiParams
MOF ファイルの例:
#PRAGMA AUTOREOVER
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
Name = "Event Filter Instance Name";
EventNamespace = "Root\\Cimv2";
Query = "Select * From __InstanceCreationEvent Within 1 "
"Where TargetInstance Isa \"Cim_DirectoryContainsFile\" "
"and TargetInstance.GroupComponent=\"Win32_Directory.Name=\'C:\\\\test\'\"";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "TestConsumer";
ScriptingEngine = "VBScript";
ScriptFileName = "C:\\test\\test.vbs"
};
instance of __FilterToConsumerBinding
{
Filter = $EventFilter;
Consumer = $Consumer;
};
自分で間隔を設定できるので、これは良い方法のように思えます。WMI は基本的に Windows の組み込みソリューションであるため、常に安全に作業できます。
これを行う別の方法は、次のようなスクリプトを作成することです。
$folderpath = 'C:\test'
$items = Get-ChildItem $folderpath
$currentdatetime = Get-Date
foreach($item in $items) {
If ($item.CreationTime > $currentdatetime.AddSeconds(-5)){
# Do some action
}
}
これは、システム上でスケジュールされたタスクとして実行できます。
私の質問は - これを行う最善の方法は何ですか? 私が示した 2 つのオプションのうちの 1 つは、システム リソースまたはエラーの可能性に関して本質的により効率的ですか?
私が考慮していないこれを行う他の方法はありますか?
Jisaak は、 を使用する回答を追加しましたSystem.IO.FilesystemWatcher
。残念ながら、これは私の目的には理想的ではありません.これは、それを実行したシェルが開いている間にのみ機能するためです.