Answers:
线程任务计划程序:如何自动同步我的USB闪存驱动器? 用户名为monotone的用户给出了以下答案,该用户将PowerShell与Task Scheduler结合使用:
我和您有相同的问题,并使用此处和此处的Scripting Guy Blog的技术使用powershell(Windows内置脚本)解决了一些问题。该脚本作为后台进程连续运行,您可以使用任务计划程序从系统登录开始。每当插入新驱动器然后执行某项操作(在此配置脚本而不是任务)时,脚本都会收到通知。由于它在等待下一个插入的驱动器时基本上已暂停,因此您不应发现它占用了很多资源。我来啦:
1)启动Powershell ISE,可以在“附件/ Windows Powershell”下的“开始”菜单中找到它。2)将以下内容复制粘贴到Powershell中:
#Requires -version 2.0 Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange write-host (get-date -format s) " Beginning script..." do{ $newEvent = Wait-Event -SourceIdentifier volumeChange $eventType = $newEvent.SourceEventArgs.NewEvent.EventType $eventTypeName = switch($eventType) { 1 {"Configuration changed"} 2 {"Device arrival"} 3 {"Device removal"} 4 {"docking"} } write-host (get-date -format s) " Event detected = " $eventTypeName if ($eventType -eq 2) { $driveLetter = $newEvent.SourceEventArgs.NewEvent.DriveName $driveLabel = ([wmi]"Win32_LogicalDisk='$driveLetter'").VolumeName write-host (get-date -format s) " Drive name = " $driveLetter write-host (get-date -format s) " Drive label = " $driveLabel # Execute process if drive matches specified condition(s) if ($driveLetter -eq 'Z:' -and $driveLabel -eq 'Mirror') { write-host (get-date -format s) " Starting task in 3 seconds..." start-sleep -seconds 3 start-process "Z:\sync.bat" } } Remove-Event -SourceIdentifier volumeChange } while (1-eq1) #Loop until next event Unregister-Event -SourceIdentifier volumeChange
3)您需要修改上面的脚本,以告知脚本要查找的驱动器以及要执行的驱动器。更改的两行是:
if ($driveLetter -eq 'Z:' -and $driveLabel -eq 'Mirror')
我的USB硬盘驱动器名为“ Mirror”设置为Z:驱动器。
if ($driveLabel -eq 'MyDiskLabel')
如果您不在乎这封信,就可以使用。start-process "Z:\sync.bat"
您想执行的任何任务的路径。在我的示例中,我在USB驱动器上创建了一个批处理文件,该文件可启动3-4个备份任务命令行。
4)完成后,将脚本保存在某个地方(扩展名
.ps1
),然后在Task Scheduler中创建任务以使脚本在后台运行。我的看起来像这样:
- 触发条件:登录时
- 行动:启动程序
- 程序/脚本:Powershell
- 添加参数:
-ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"
5)Voilà!
6)额外的东西:
如果要隐藏脚本窗口,请使用以下参数:
- 添加参数:
-WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"
如果要将脚本消息输出到日志文件(每次脚本启动时即登录时都会被覆盖),请使用以下任务操作:
- 程序/脚本:cmd
- 添加参数:
/c powershell -WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1" > "D:\Stuff\script
log.txt”任何时候要结束正在运行的隐藏脚本,都可以在任务管理器中结束“ Powershell”过程。
唯一的缺点是,在已插入驱动器的情况下引导计算机时,什么也不会运行。(虽然可以将脚本更改为最初执行第一次检查,但今天我已经受够了!)
$newEvent.SourceEventArgs.NewEvent
对你所感兴趣的事件。
正如我在此讨论中已经解释的那样(但是它是关于在删除USB驱动器时运行程序的),“ USB安全删除 ”虽然不是免费的,但在触发有关USB设备的某些事件时可以运行程序:
另一个USB安全删除功能将其与类似软件区分开来,不仅在连接设备之后而且在删除设备之前都启动任何应用程序。自动运行功能允许您在断开可移动硬盘驱动器之前设置数据备份,使用笔式驱动器的内容运行Total Commander,在断开USB介质连接之前自动卸载加密的TrueCrypt驱动器等。
当然,这并不能完全回答问题,因为这与使用计划任务无关,但我认为目标是相同的,即插入USB记忆棒后运行特定程序。
使用EventVwr应该很容易。
查找您想要的事件-当我插入USB大容量存储设备时,它触发了以下事件(在应用程序类别下):20001、20003、7036和其他一些无关紧要的事件。确保针对其他USB设备事件测试这些事件,以避免误报。
右键单击该事件,然后单击“将任务附加到此事件”(仅在Windows Vista或更高版本中-对于XP,具有CLI EventTrigger),选择“启动程序”,然后将其指向要运行的脚本。
要将事件参数传递给脚本,请参见本文。在事件20001和20003下,您可以找到新存储的UNC路径。使用Sysinternals Junction实用程序,您可以创建指向UNC路径的链接。
我能够使它正常工作:我在应用程序和服务日志,插入到USB的电话的Microsoft-Windows-DriverFrameworks-UserMode中找到了事件1003
事件的完整xml:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-DriverFrameworks-UserMode" Guid="{2E35AAEB-857F-4BEB-A418-2E6C0E54D988}" />
<EventID>1003</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>17</Task>
<Opcode>1</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2016-08-19T01:42:06.292278900Z" />
<EventRecordID>17516</EventRecordID>
<Correlation />
<Execution ProcessID="456" ThreadID="2932" />
<Channel>Microsoft-Windows-DriverFrameworks-UserMode/Operational</Channel>
<Computer>5CG6070VFK-W7.nikonprecision.com</Computer>
<Security UserID="S-1-5-18" />
</System>
- <UserData>
- <UMDFDriverManagerHostCreateStart lifetime="{AFEC92AD-6015-4AB4-86AE-F34CEE06A977}" xmlns:auto-ns2="http://schemas.microsoft.com/win/2004/08/events" xmlns="http://www.microsoft.com/DriverFrameworks/UserMode/Event">
<HostGuid>{193a1820-d9ac-4997-8c55-be817523f6aa}</HostGuid>
<DeviceInstanceId>USB.VID_04E8&PID_6860&MS_COMP_MTP&SAMSUNG_ANDROID.6&3400EB54&1&0000</DeviceInstanceId>
</UMDFDriverManagerHostCreateStart>
</UserData>
</Event>
以及针对我的任务的自定义事件过滤器:
<QueryList>
<Query Id="0" Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">
<Select Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">*[System[Provider[@Name='Microsoft-Windows-DriverFrameworks-UserMode'] and EventID=1003]] and *[UserData[UMDFDriverManagerHostCreateStart[DeviceInstanceId="USB.VID_04E8&PID_6860&MS_COMP_MTP&SAMSUNG_ANDROID.6&3400EB54&1&0000"]]]</Select>
</Query>
</QueryList>
同样,对于USB驱动器,事件2100、2101、2105、2106
对于特定的USB驱动器:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-DriverFrameworks-UserMode" Guid="{2E35AAEB-857F-4BEB-A418-2E6C0E54D988}" />
<EventID>2101</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>37</Task>
<Opcode>2</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2016-08-19T01:52:37.922289600Z" />
<EventRecordID>17662</EventRecordID>
<Correlation />
<Execution ProcessID="10956" ThreadID="11892" />
<Channel>Microsoft-Windows-DriverFrameworks-UserMode/Operational</Channel>
<Computer>5CG6070VFK-W7.nikonprecision.com</Computer>
<Security UserID="S-1-5-19" />
</System>
- <UserData>
- <UMDFHostDeviceRequest instance="WPDBUSENUMROOT\UMB\2&37C186B&0&STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_SANDISK&PROD_SANDISK_CRUZER&REV_8.02#0774230A28933B7E&0#" lifetime="{4493DBFB-81E8-4277-933D-955C4DDDD482}" xmlns:auto-ns2="http://schemas.microsoft.com/win/2004/08/events" xmlns="http://www.microsoft.com/DriverFrameworks/UserMode/Event">
- <Request major="27" minor="20">
<Argument>0x0</Argument>
<Argument>0x141b</Argument>
<Argument>0x0</Argument>
<Argument>0x0</Argument>
</Request>
<Status>0</Status>
</UMDFHostDeviceRequest>
</UserData>
</Event>
"<request>"
当我插入USB驱动器时,看起来事件2101发生了3次,并且标签略有不同:
<Request major="27" minor="20">
<Request major="27" minor="9">
<Request major="27" minor="0">
我不知道这意味着什么,但是这里只有一个过滤器,可以避免多次触发:(这只会针对该特定的USB驱动器触发)
<QueryList>
<Query Id="0" Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">
<Select Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">*[System[Provider[@Name='Microsoft-Windows-DriverFrameworks-UserMode'] and EventID=2101]] and *[UserData[UMDFHostDeviceRequest[@instance="WPDBUSENUMROOT\UMB\2&37C186B&0&STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_SANDISK&PROD_SANDISK_CRUZER&REV_8.02#0774230A28933B7E&0#" and Request[@major="27" and @minor="20"]]]]</Select>
</Query>
</QueryList>
请注意,“&”号必须以 &
正如其他人提到的那样,似乎服务控制管理器中的系统日志事件7036是唯一与插入的USB驱动器可靠相关的事件。我通过插入USB驱动器并运行以下powershell命令以列出最近一个小时中来自所有来源的所有事件日志条目来进行检查:
get-winevent | where {$_.timecreated -ge (get-date) - (new-timespan -hour 1)}
不幸的是,每次服务控制管理器成功启动或停止任何服务时都会生成事件7036,因此需要其他过滤。
Event Viewer / Task Scheduler的GUI中可用的过滤是非常基本的,不允许对事件数据进行任何过滤-它仅允许您过滤元数据,在这种情况下,它不会告诉您有关哪个服务具有更改状态以及更改为什么状态。这被保存在EventData的“ param1”和“ param2”中。因此,以下XPath筛选器可用于仅捕获相关的启动服务:
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Service Control Manager'] and (Level=4 or Level=0) and (band(Keywords,36028797018963968)) and (EventID=7036)]]
and
*[EventData[
Data[@Name="param1"]="Portable Device Enumerator Service" and
Data[@Name="param2"]="running"
]
]
</Select>
</Query>
</QueryList>
从那里可以运行脚本,理想情况下,可以使用一些附加逻辑来检查所插入的USB驱动器是否是您感兴趣的驱动器。
我从“应用程序和服务日志-Microsoft-Windows-Ntfs_Operational”下的事件日志中找到了一个更好的(IMO)事件。Eventid4。看起来像这样:
事件ID 4 NTFS卷已成功安装。
Volume GUID: {55bf0ee3-d507-4031-a60a-22e5892ebf37}
Volume Name: E:
Volume Label: AirGapDrive A
Device Name: \Device\HarddiskVolume51
从中,您可以创建计划任务触发器,并按卷名和/或标签进行过滤。在Windows Server 2019机器上发现此事件,但是由于某些原因,我在Windows 10(1809)桌面上看不到该事件。可能是仅服务器事件。