通过检测USB设备的连接来启动计划任务


24

我知道已经讨论过,由于Win 7中自动运行(或自动播放?)的限制,无法在连接时从USB驱动器启动应用程序,但是可以创建具有事件类型触发器的计划任务。当连接驱动器或其他任何USB设备时,肯定会发生一个事件。

是否有人丝毫不建议我使用哪个事件ID?或者至少是什么类型的事件?在事件查看器中可以在哪里找到事件?

Answers:


17

线程任务计划程序:如何自动同步我的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”过程。

唯一的缺点是,在已插入驱动器的情况下引导计算机时,什么也不会运行。(虽然可以将脚本更改为最初执行第一次检查,但今天我已经受够了!)


我认为这会很好。让我修补一下,我会尽快回复您
-GiantDuck

1
它适用于驱动器。如何修改它以检测插入的任何 USB设备,而不仅仅是驱动器?
GiantDuck

EventType 2将检测任何设备到达。获取详细信息将需要对事件进行更多的挖掘。最简单的可能是打印的成员$newEvent.SourceEventArgs.NewEvent对你所感兴趣的事件。
harrymc

很高兴在将近4年后看到一个有希望的答案:)非常感谢GiantDuck和harrymc。
gemisigo 2014年

@harrymc您可以为此提供一些背景吗?我以前从未使用过powershell。谢谢!
GiantDuck

6

正如我在此讨论中已经解释的那样(但是它是关于在删除USB驱动器时运行程序的),“ USB安全删除 ”虽然不是免费的,但在触发有关USB设备的某些事件时可以运行程序:

另一个USB安全删除功能将其与类似软件区分开来,不仅在连接设备之后而且在删除设备之前都启动任何应用程序。自动运行功能允许您在断开可移动硬盘驱动器之前设置数据备份,使用笔式驱动器的内容运行Total Commander,在断开USB介质连接之前自动卸载加密的TrueCrypt驱动器等。

在此处输入图片说明

当然,这并不能完全回答问题,因为这与使用计划任务无关,但我认为目标是相同的,即插入USB记忆棒后运行特定程序。


非常感谢,这是一个不错的解决方法。我已经尝试过了,但是尽管它可以正常工作,但我仍在努力实现我的最初目标(即使用本地提供的免费解决方案)。到目前为止,我已经了解到,使用DriverFrameworks-UserMode中的事件ID 2006事件可以触发操作。它仍然不是完美的。活动详细信息中提供了必要的信息,但我无法为特定的USB驱动器过滤该信息,因此插入任何USB驱动器都会触发触发器。
gemisigo 2011年

5

使用EventVwr应该很容易。

  1. 查找您想要的事件-当我插入USB大容量存储设备时,它触发了以下事件(在应用程序类别下):20001、20003、7036和其他一些无关紧要的事件。确保针对其他USB设备事件测试这些事件,以避免误报。

  2. 右键单击该事件,然后单击“将任务附加到此事件”(仅在Windows Vista或更高版本中-对于XP,具有CLI EventTrigger),选择“启动程序”,然后将其指向要运行的脚本。

  3. 要将事件参数传递给脚本,请参见本文。在事件20001和20003下,您可以找到新存储的UNC路径。使用Sysinternals Junction实用程序,您可以创建指向UNC路径的链接。


我喜欢这个主意,但是不够详细。我无法正常工作。
GiantDuck

@GiantDuck对我而言,它看起来很简单,您想让我详细说明什么?
EliadTech

我在事件查看器中找不到所说的事件。(目前在Win8上)的确切路径是什么?谢谢!
GiantDuck

我写过,它在上面提到的事件编号的“应用程序”日志中。但是我已经在Win7上进行了测试,所以也许在Win8上,事件编号是不同的。正如我所说,您仍然需要进行一些测试,以确保它可以与您要插入的任何设备一起使用。
EliadTech

1
在Win10中,“应用程序”类别中没有任何内容。我必须进入系统并附加到事件
ID98

2

我能够使它正常工作:我在应用程序和服务日志,插入到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&amp;PID_6860&amp;MS_COMP_MTP&amp;SAMSUNG_ANDROID.6&amp;3400EB54&amp;1&amp;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&amp;37C186B&amp;0&amp;STORAGE#VOLUME#_??_USBSTOR#DISK&amp;VEN_SANDISK&amp;PROD_SANDISK_CRUZER&amp;REV_8.02#0774230A28933B7E&amp;0#" and Request[@major="27" and @minor="20"]]]]</Select>
  </Query>
</QueryList>

请注意,“&”号必须以 &amp;


1

正如其他人提到的那样,似乎服务控制管理器中的系统日志事件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驱动器是否是您感兴趣的驱动器。


0

我从“应用程序和服务日志-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)桌面上看不到该事件。可能是仅服务器事件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.