Rozpoczęcie zaplanowanego zadania przez wykrycie połączenia urządzenia USB

24

Wiem, że zostało omówione, że nie można uruchomić aplikacji z napędu USB po połączeniu z powodu ograniczeń autorun (lub autoodtwarzania?) W Win 7. Ale możliwe jest utworzenie zaplanowanego zadania z wyzwalaczem typu zdarzenia . Z pewnością musi wystąpić zdarzenie, gdy napęd - lub dowolne urządzenie USB, w tym przypadku - jest podłączone.

Czy ktoś ma pojęcie, którego identyfikatora zdarzenia powinienem użyć? A przynajmniej jaki rodzaj wydarzenia? Gdzie mogę znaleźć wydarzenie w przeglądarce wydarzeń?

gemisigo
źródło

Odpowiedzi:

17

Wątek Harmonogram zadań: Jak automatycznie zsynchronizować pamięć flash USB? ma tę odpowiedź użytkownika o nazwie monotonia, który korzysta z programu PowerShell razem z Harmonogramem zadań:

Miałem to samo pytanie co ty i opracowałem coś z PowerShell (wbudowane skrypty systemu Windows), używając technik z blogu Scripting Guy tutaj i tutaj . Skrypt działa nieprzerwanie jako proces w tle, który można rozpocząć przy logowaniu systemowym za pomocą harmonogramu zadań. Skrypt zostanie powiadomiony za każdym razem, gdy nowy dysk zostanie podłączony, a następnie coś zrobi (tutaj konfigurujesz skrypt, a nie zadanie). Ponieważ jest zasadniczo wstrzymany podczas oczekiwania na następny podłączony dysk, nie powinieneś uważać, że zajmuje dużo zasobów. Teraz ja:

1) Uruchom program Powershell ISE, który można znaleźć w menu Start w obszarze Akcesoria / Windows Powershell. 2) Skopiuj następujące elementy do programu 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) Musisz zmodyfikować powyższy skrypt, aby wskazać skryptowi, którego dysku szukać i co wykonać. Dwie linie do zmiany to:

if ($driveLetter -eq 'Z:' -and $driveLabel -eq 'Mirror')

Mój dysk twardy USB o nazwie „Mirror” jest ustawiony jako dysk Z:. Możesz użyć, if ($driveLabel -eq 'MyDiskLabel')jeśli nie obchodzi cię list.

start-process "Z:\sync.bat"

Ścieżka do dowolnego zadania, które chcesz wykonać. W moim przykładzie utworzyłem plik wsadowy na dysku USB, który uruchamia 3-4 wiersze poleceń zadań tworzenia kopii zapasowych.

4) Po zakończeniu zapisz gdzieś skrypt (rozszerzenie .ps1), a następnie utwórz zadanie w Harmonogramie zadań, aby skrypt działał w tle. Mój wygląda następująco:

  • Wyzwalacz: przy logowaniu
  • Działanie: Uruchom program
  • Program / skrypt: powershell
  • Dodaj argumenty: -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"

5) Voilà!

6) Dodatkowe rzeczy:

Jeśli chcesz ukryć okno skryptu, użyj następujących argumentów:

  • Dodaj argumenty:
    -WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"

Jeśli chcesz wyprowadzić komunikaty skryptu do pliku dziennika (który jest nadpisywany przy każdym uruchomieniu skryptu, tj. Przy logowaniu), użyj następującej czynności zadania:

  • Program / skrypt: cmd
  • Dodaj argumenty:
    /c powershell -WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1" > "D:\Stuff\script log.txt ”

Za każdym razem, gdy chcesz zakończyć działający ukryty skrypt, możesz zakończyć proces „Powershell” w Menedżerze zadań.

Jedynym minusem jest to, że nic się nie uruchomi, gdy uruchomisz komputer z już podłączonym napędem. (Skrypt można zmienić, aby wykonać pierwszą kontrolę początkowo, ale mam dość na dziś!)

harrymc
źródło
Myślę, że to zadziała świetnie. Niech majstruję, a ja wrócę do ciebie
GiantDuck,
1
Działa dla napędów. Jak mogę to zmienić, aby wykryć każde podłączone urządzenie USB, a nie tylko napędy?
GiantDuck
EventType 2 wykryje każde przybycie urządzenia. Uzyskanie szczegółów będzie wymagało trochę głębszego zagłębienia się w wydarzenie. Najprostszym może być wydrukowanie członków $newEvent.SourceEventArgs.NewEventwydarzeń, którymi jesteś zainteresowany.
harrymc
Miło jest zobaczyć obiecującą odpowiedź po prawie 4 latach :) Dziękuję bardzo, GiantDuck & harrymc.
gemisigo
@harrymc Czy możesz podać jakiś kontekst? Nigdy wcześniej nie korzystałem z PowerShell. Dzięki!
GiantDuck
6

Jak już wyjaśniłem w tej dyskusji (ale chodziło o uruchomienie programu po odłączeniu napędu USB), Bezpieczne usuwanie USB , chociaż nie jest wolne, może uruchomić program, gdy zostaną uruchomione niektóre zdarzenia dotyczące urządzeń USB:

Kolejną funkcją bezpiecznego usuwania USB, która odróżnia ją od podobnego oprogramowania, jest uruchamianie dowolnych aplikacji nie tylko po podłączeniu urządzenia , ale także przed jego usunięciem. Funkcja autorun pozwala skonfigurować kopię zapasową danych przed odłączeniem wymiennego dysku twardego, uruchomić Total Commander z zawartością pendrive'a, automatycznie odmontować zaszyfrowany dysk TrueCrypt przed odłączeniem nośnika USB itp.

wprowadź opis zdjęcia tutaj

Oczywiście to nie w pełni odpowiada na pytanie, ponieważ nie chodzi o korzystanie z zaplanowanych zadań, ale myślę, że cel jest taki sam, a mianowicie uruchomienie określonego programu po podłączeniu pamięci USB.

Snark
źródło
Dziękuję bardzo, jest to dobre obejście. Próbowałem tego, ale pomimo prawidłowego działania, wciąż staram się osiągnąć mój pierwotny cel (to znaczy użyć natywnie dostępnego i bezpłatnego rozwiązania). Do tej pory zorientowałem się, że za pomocą zdarzeń Event ID 2006 z DriverFrameworks-UserMode mogę wyzwolić akcję. Jednak wciąż nie jest idealny. Niezbędne informacje są dostępne w szczegółach wydarzenia, ale nie mogę ich przefiltrować dla określonego napędu USB, więc podłączenie dowolnego napędu USB spowoduje uruchomienie wyzwalacza.
gemisigo
5

Korzystanie z EventVwr powinno być dość łatwe.

  1. Znajdź odpowiednie wydarzenie - kiedy podłączyłem urządzenie pamięci masowej USB, wywołało następujące zdarzenia (w kategorii aplikacji): 20001, 20003, 7036 i kilka innych mniej istotnych. Upewnij się, że testujesz te zdarzenia na zdarzeniach innych urządzeń USB, aby uniknąć fałszywych alarmów.

  2. kliknij prawym przyciskiem myszy zdarzenie i kliknij „Dołącz zadanie do tego zdarzenia” (dotyczy tylko systemu Windows Vista lub nowszego - w systemie XP istnieje CLI EventTrigger), wybierz „Uruchom program” i wskaż skrypt, który chcesz uruchomić.

  3. Aby przekazać do skryptu parametry zdarzenia, zajrzyj do tego artykułu . W ramach wydarzeń 20001 i 20003 można znaleźć ścieżkę UNC do nowego magazynu. Za pomocą narzędzia Sysinternals Junction można utworzyć łącza do ścieżek UNC.

EliadTech
źródło
Podoba mi się pomysł, ale nie jest on wystarczająco szczegółowy; Nie mogę zmusić go do pracy.
GiantDuck,
@ GiantDuck Dla mnie wygląda to dość prosto, na czym chciałbym, abym opracował?
EliadTech
Nie mogę znaleźć wspomnianych wydarzeń w Podglądzie zdarzeń. (W tej chwili na Win8) Jaka jest dokładna ścieżka? Dziękuję Ci!
GiantDuck,
Napisałem, że jest pod logiem „aplikacji” z numerami zdarzeń wspomnianymi powyżej. Ale przetestowałem to na Win7, więc może na Win8 numery wydarzeń są różne. Jak już powiedziałem, będziesz musiał przeprowadzić testy, aby upewnić się, że będzie działać z każdym podłączanym urządzeniem.
EliadTech,
1
W Win10 nic nie pojawiło się w kategorii Zastosowanie. Musiałem przejść do Systemu i dołączyć do Identyfikatora zdarzenia 98. Dla mnie to w porządku, bo będę mieć tylko to jedno urządzenie, ale inne mogą nie działać
dbinott
2

Udało mi się to uruchomić: znalazłem zdarzenie 1003 w dziennikach aplikacji i usług, Microsoft-Windows-DriverFrameworks-UserMode dla telefonu podłączonego do USB

Pełny plik XML wydarzenia:

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

A niestandardowy filtr zdarzeń dla mojego zadania:

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

Podobnie w przypadku napędu USB było to zdarzenie 2100, 2101, 2105, 2106
W przypadku konkretnego napędu 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>

Wygląda na to, że zdarzenie 2101 zdarza się 3 razy z nieco innymi "<request>"tagami po podłączeniu dysku USB:

<Request major="27" minor="20">
<Request major="27" minor="9">
<Request major="27" minor="0">

Nie mam pojęcia, co to oznacza, ale tutaj jest filtr tylko jednego z nich, aby uniknąć wielu wyzwalaczy: (uruchomi się tylko dla tego konkretnego napędu 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>

Pamiętaj, że znaki ampersands muszą być oznaczone jako &amp;

strój
źródło
1

Jak wspomnieli inni, wydaje się, że zdarzenie 7036 dziennika systemu z Menedżera sterowania usługami jest jedynym zdarzeniem, które niezawodnie koreluje z włożonym napędem USB. Sprawdziłem to, wkładając dysk USB i uruchamiając następującą komendę PowerShell, aby wyświetlić wszystkie wpisy dziennika zdarzeń ze wszystkich źródeł w ciągu ostatniej godziny:

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

Niestety zdarzenie 7036 jest generowane za każdym razem, gdy Menedżer kontroli usług pomyślnie uruchamia lub zatrzymuje dowolną usługę, dlatego wymagane jest dodatkowe filtrowanie.

Filtrowanie dostępne w interfejsie GUI Podglądu zdarzeń / Harmonogramu zadań jest dość proste i nie pozwala na żadne filtrowanie danych zdarzeń - pozwala jedynie filtrować metadane, które w tym przypadku nie mówią nic o tym, która usługa ma zmienił stan i do jakiego stanu się zmienił. Odbywa się to w „param1” i „param2” EventData. Dlatego można użyć następującego filtra XPath do przechwytywania tylko odpowiedniej usługi podczas uruchamiania:

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

Stamtąd możesz uruchomić skrypt, najlepiej z dodatkową logiką, aby sprawdzić, czy włożony dysk USB jest tym, który Cię interesuje.

sahmeepee
źródło
0

Znalazłem lepsze (IMO) zdarzenie z dziennika zdarzeń znajdującego się w obszarze Aplikacje i dzienniki usług-Microsoft-Windows-Ntfs_Operational. Eventid 4. Wygląda to tak:

Identyfikator zdarzenia 4 Wolumin NTFS został pomyślnie podłączony.

       Volume GUID: {55bf0ee3-d507-4031-a60a-22e5892ebf37}
       Volume Name: E:
       Volume Label: AirGapDrive A
       Device Name: \Device\HarddiskVolume51

Na tej podstawie możesz utworzyć zaplanowane wyzwalacz zadania i filtrować według nazwy woluminu i / lub etykiety. To wydarzenie zostało znalezione na pudełku Windows Server 2019, jednak z jakiegoś powodu nie widzę go na pulpicie Windows 10 (1809). Może to być wydarzenie tylko dla serwera ....

RyanG
źródło