Запуск запланированного задания по обнаружению подключения USB-устройства

24

Я знаю, что уже обсуждалось, что невозможно запустить приложение с USB-накопителя при подключении из-за ограничений автозапуска (или автозапуска ??) в Win 7. Но возможно создать запланированное задание с триггером типа события , Конечно, должно происходить событие, когда диск - или любое USB-устройство, в этом отношении - подключен.

Кто-нибудь имеет хоть малейшее представление о том, какой идентификатор события следует использовать? Или хотя бы какой тип мероприятия? Где я могу найти событие в программе просмотра событий?

gemisigo
источник

Ответы:

17

Планировщик заданий темы: Как автоматически синхронизировать флэш-накопитель USB? имеет этот ответ от пользователя с именем monotone, который использует PowerShell вместе с планировщиком задач:

У меня был такой же вопрос, как и у вас, и я кое-что проработал с 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), а затем создайте задачу в планировщике задач, чтобы ваш скрипт работал в фоновом режиме. Моя выглядит так:

  • Триггер: при входе в систему
  • Действие: запустить программу
  • Программа / скрипт: powershell
  • Добавьте аргументы: -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"

5) Вуаля!

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» в диспетчере задач.

Единственным недостатком является то, что ничего не запустится, когда вы загрузите свой компьютер с уже подключенным диском. (Хотя сценарий может быть изменен, чтобы сначала выполнить первую проверку, но на сегодня хватит!)

harrymc
источник
Я думаю, что это будет отлично работать. Позвольте мне возиться с этим, и я вернусь к вам
GiantDuck
1
Это работает для дисков. Как я могу изменить это, чтобы обнаружить любое USB-устройство, вставленное, а не только диски?
GiantDuck
EventType 2 обнаружит любое прибытие устройства. Для получения подробностей потребуется еще немного покопаться в мероприятии. Проще всего напечатать членов $newEvent.SourceEventArgs.NewEventдля интересующих вас событий.
harrymc
Приятно видеть многообещающий ответ спустя почти 4 года :) Большое спасибо, GiantDuck & harrymc.
Gemisigo
@harrymc Можете ли вы предоставить контекст для этого? Я никогда раньше не использовал PowerShell. Благодарность!
GiantDuck
6

Как я уже объяснял в этом обсуждении (но речь шла о запуске программы при извлечении USB-накопителя), USB Safely Remove , хотя и не свободная, может запускать программу при возникновении некоторых событий на USB-устройствах:

Другая функция безопасного удаления USB, которая отличает его от аналогичного программного обеспечения, запускает любые приложения не только после подключения устройства , но и перед его удалением. Функция автозапуска позволяет настроить резервное копирование данных перед отсоединением съемного жесткого диска, запустить Total Commander с содержимым флешки, автоматически отключить зашифрованный диск TrueCrypt перед отключением USB-носителя и т. Д.

введите описание изображения здесь

Конечно, это не полностью отвечает на вопрос, поскольку речь идет не об использовании запланированных задач, но я думаю, что цель та же, что и запуск конкретной программы при подключении USB-накопителя.

Снарк
источник
Большое спасибо, хороший обходной путь, это так. Я попробовал это, но, несмотря на то, что это работает должным образом, я все еще пытаюсь достичь своей первоначальной цели (то есть, используя изначально доступное и бесплатное решение). До сих пор я выяснил, что с помощью событий Event ID 2006 из DriverFrameworks-UserMode я могу инициировать действие. Это все еще не идеально, хотя. Необходимая информация доступна в сведениях о событии, но я не могу отфильтровать ее для конкретного USB-накопителя, поэтому при подключении любого USB-накопителя срабатывает триггер.
Gemisigo
5

Это должно быть довольно легко, используя EventVwr.

  1. Найдите нужное событие. Когда я подключил запоминающее устройство USB, оно вызвало следующие события (в категории приложений): 20001, 20003, 7036 и некоторые другие, менее важные. Убедитесь, что вы проверяете эти события с событиями других USB-устройств, чтобы избежать ложных срабатываний.

  2. щелкните правой кнопкой мыши по событию и нажмите «Прикрепить задачу к этому событию» (актуально только в Windows Vista или более поздней версии - для XP есть CLI EventTrigger), выберите «Запустить программу» и укажите на сценарий, который вы хотите запустить.

  3. Чтобы передать в сценарий параметры события, нужно заглянуть в эту статью . Под событиями 20001 и 20003 вы можете найти UNC-путь к новому хранилищу. С помощью утилиты Sysinternals Junction вы можете создавать ссылки на пути UNC.

EliadTech
источник
Мне нравится идея этого, но это не достаточно подробно; Я не могу заставить его работать.
GiantDuck
@GiantDuck Для меня это выглядит довольно просто, что бы вы хотели, чтобы я уточнил?
EliadTech
Я не могу найти указанные события в Event Viewer. (На Win8 на данный момент) Какой точный путь? Спасибо!
GiantDuck
Я написал, он находится в «журнале приложений» с номерами событий, упомянутыми выше. Но я проверял это на Win7, поэтому, возможно, на Win8 номера событий разные. Как я уже сказал, вам все равно нужно провести некоторое тестирование, чтобы убедиться, что оно будет работать с любым подключаемым устройством.
EliadTech
1
В Win10 ничего не появилось в категории приложений. Мне нужно было зайти в System и подключиться к Event ID 98. Это нормально для меня, потому что у меня когда-нибудь будет только одно это устройство, но другие могут не работать
dbinott
2

Мне удалось заставить это работать: я обнаружил событие 1003 в журналах приложений и служб, Microsoft-Windows-DriverFrameworks-UserMode для телефона, подключенного к USB

Полный 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>

Похоже, что событие 2101 происходит 3 раза с немного другими "<request>"тегами, когда я подключаю USB-накопитель:

<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;

garbb
источник
1

Как уже упоминалось, кажется, что Событие 7036 системного журнала от Service Control Manager является единственным событием, которое надежно связано с подключаемым USB-накопителем. Я проверил это, вставив USB-накопитель и выполнив следующую команду powershell, чтобы вывести список всех записей журнала событий из всех источников за последний час:

get-winevent | where {$_.timecreated -ge (get-date) - (new-timespan -hour 1)}

К сожалению, событие 7036 генерируется каждый раз, когда диспетчер управления службами успешно запускает или останавливает какую-либо службу, поэтому требуется дополнительная фильтрация.

Фильтрация, доступная в графическом интерфейсе Event Viewer / Task Scheduler, довольно проста и не позволяет выполнять какую-либо фильтрацию данных события - она ​​позволяет фильтровать только метаданные, которые в этом случае ничего не говорят о том, какая служба имеет изменилось состояние и в каком состоянии оно изменилось. Это содержится в «param1» и «param2» EventData. Поэтому следующий фильтр 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-накопитель, который был вставлен, является тем, который вас интересует.

sahmeepee
источник
0

Я нашел лучшее (IMO) событие из журнала событий, расположенного в разделе Журналы приложений и служб-Microsoft-Windows-Ntfs_Operational. Eventid 4. Это выглядит так:

Код события 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). Может быть событие только для сервера ....

рианг
источник