gpt4 book ai didi

powershell - 永久监控特定文件夹中文件创建的最有效、最可靠的方法

转载 作者:行者123 更新时间:2023-12-02 10:57:20 25 4
gpt4 key购买 nike

我需要监视文件夹并在每次创建文件时执行一些操作。我有 2 个解决方案 - 一个使用 WMI,我可以使用此过滤器(从 .MOF 文件或注册永久 MWI 事件绑定(bind)的 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 个选项中,其中之一在系统资源或潜在错误方面本质上是否更高效?

还有其他我没有考虑过的方法吗?

<小时/>

Jisaak 添加了一个使用 System.IO.FilesystemWatcher 的答案。不幸的是,这对于我的目的来说并不理想,因为这只在执行它的 shell 打开时才有效,而我想要一个更永久的解决方案(更新了问题的标题以反射(reflect)这一点)

最佳答案

您不想长时间轮询文件夹以查找文件更改,您应该使用一种机制,在创建文件时您会收到通知

因此您可以使用FileSystemWatcher类并使用 Register-ObjectEvent 注册到created 事件处理程序 cmdlet。

$folder = 'C:\test'
$filter = '*.*'
$fileSystemWatcher = New-Object IO.FileSystemWatcher $folder, $filter -Property @{
IncludeSubdirectories = $true # Set this according to your requirements.
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}

$onCreated = Register-ObjectEvent $fileSystemWatcher Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
Write-Host "File $Path was created".

}

运行此命令以取消注册:

Unregister-Event -SourceIdentifier FileCreated

关于powershell - 永久监控特定文件夹中文件创建的最有效、最可靠的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36887933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com