การเริ่มงานที่กำหนดเวลาไว้โดยตรวจจับการเชื่อมต่อของอุปกรณ์ USB


24

ฉันรู้ว่ามีการพูดกันว่ามันเป็นไปไม่ได้ที่จะเริ่มต้นแอปพลิเคชันจากไดรฟ์ usb เมื่อเชื่อมต่อเนื่องจากข้อ จำกัด ของการทำงานอัตโนมัติ (หรือเล่นอัตโนมัติหรือไม่) ใน Win 7 แต่มันเป็นไปได้ที่จะสร้างงานตามกำหนดเวลา . แน่นอนจะต้องมีเหตุการณ์ที่เกิดขึ้นเมื่อเชื่อมต่อไดรฟ์ - หรืออุปกรณ์ USB ใด ๆ สำหรับเรื่องนั้น -

มีใครมีความคิดเพียงเล็กน้อยที่ฉันควรใช้รหัสกิจกรรม หรืออย่างน้อยเหตุการณ์ประเภทใด ฉันจะหาเหตุการณ์ได้ใน Event Viewer?

คำตอบ:


17

เธรดTask Scheduler: วิธีซิงโครไนซ์แฟลชไดรฟ์ USB ของฉันโดยอัตโนมัติ มีคำตอบนี้โดยผู้ใช้ชื่อโมโนโทนซึ่งใช้ PowerShell ร่วมกับ Task Scheduler:

ฉันมีคำถามเดียวกันกับคุณและทำงานออกอะไรกับ PowerShell (หน้าต่างในตัวสคริปต์) โดยใช้เทคนิคจากการเขียนสคริปต์ผู้ชาย Blog ที่นี่และที่นี่ สคริปต์ทำงานอย่างต่อเนื่องเป็นกระบวนการพื้นหลังซึ่งคุณสามารถเริ่มต้นด้วยการเข้าสู่ระบบด้วยตัวกำหนดตารางเวลางาน สคริปต์จะได้รับการแจ้งเตือนเมื่อใดก็ตามที่มีการเชื่อมต่อไดรฟ์ใหม่จากนั้นทำบางสิ่ง (ที่นี่คุณกำหนดค่าสคริปต์แทนภารกิจ) เนื่องจากโดยทั่วไปจะหยุดชั่วคราวขณะที่รอไดรฟ์ต่อไปคุณไม่ควรใช้ทรัพยากรมาก ไปเลย:

1) เริ่ม Powershell ISE ซึ่งสามารถพบได้ในเมนูเริ่มของคุณภายใต้ Accessories / 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

@harrymc คุณสามารถให้บริบทสำหรับสิ่งนั้นได้ไหม ฉันไม่เคยใช้ powershell มาก่อน ขอบคุณ!
GiantDuck

6

ตามที่ฉันได้อธิบายไปแล้วเกี่ยวกับการสนทนานี้ (แต่มันเกี่ยวกับการรันโปรแกรมเมื่อถอดไดรฟ์ USB), USB Safely Removeแม้ว่าจะไม่ว่างก็สามารถรันโปรแกรมได้เมื่อมีการทริกเกอร์เหตุการณ์บางอย่างเกี่ยวกับอุปกรณ์ USB:

คุณสมบัติ USB Safely Remove อื่นที่แยกความแตกต่างจากซอฟต์แวร์ที่คล้ายกันกำลังเริ่มต้นแอพพลิเคชั่นไม่เพียง แต่หลังจากเชื่อมต่ออุปกรณ์แต่ยังก่อนที่จะลบออก คุณสมบัติการทำงานอัตโนมัติช่วยให้คุณสามารถตั้งค่าการสำรองข้อมูลก่อนที่จะยกเลิกการเชื่อมต่อฮาร์ดไดรฟ์ที่ถอดออกได้เพื่อรัน 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


ฉันชอบความคิดนี้ แต่ไม่ละเอียดพอ ฉันไม่สามารถทำงานได้
GiantDuck

@GiantDuck สำหรับฉันมันดูค่อนข้างตรงไปตรงมาคุณต้องการให้ฉันทำอะไรอย่างละเอียด?
EliadTech

ฉันไม่พบกิจกรรมดังกล่าวใน Event Viewer (ใน Win8 ในขณะนี้) เส้นทางที่แน่นอนคืออะไร? ขอขอบคุณ!
GiantDuck

ฉันเขียนมันอยู่ภายใต้บันทึก 'แอปพลิเคชัน' พร้อมหมายเลขเหตุการณ์ที่กล่าวถึงข้างต้น แต่ฉันได้ทดสอบสิ่งนี้ใน Win7 ดังนั้นบางทีใน Win8 ตัวเลขเหตุการณ์อาจแตกต่างกัน อย่างที่ฉันบอกว่าคุณจะต้องทำการทดสอบบางอย่างเพื่อให้แน่ใจว่ามันจะทำงานได้กับอุปกรณ์ใด ๆ ที่คุณกำลังเสียบ
EliadTech

1
ใน Win10 ไม่มีอะไรปรากฏในหมวดหมู่แอปพลิเคชัน ฉันต้องไปที่ระบบและแนบไปกับรหัสเหตุการณ์ 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;


1

ดังที่คนอื่น ๆ ได้กล่าวไว้ดูเหมือนว่าบันทึกเหตุการณ์ระบบ 7036 จาก Service Control Manager เป็นเหตุการณ์เดียวที่สัมพันธ์กันอย่างน่าเชื่อถือเมื่อมีการเสียบไดรฟ์ USB ฉันตรวจสอบสิ่งนี้โดยการใส่ไดรฟ์ USB และเรียกใช้คำสั่ง powershell ต่อไปนี้เพื่อแสดงรายการบันทึกเหตุการณ์ทั้งหมดจากแหล่งที่มาทั้งหมดในชั่วโมงที่ผ่านมา:

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

น่าเสียดายที่เหตุการณ์ 7036 ถูกสร้างขึ้นทุกครั้งที่ตัวจัดการควบคุมบริการเริ่มต้นหรือหยุดให้บริการใด ๆ ได้สำเร็จจึงจำเป็นต้องมีการกรองเพิ่มเติม

การกรองที่มีอยู่ใน GUI ของตัวแสดงเหตุการณ์ / ตัวกำหนดเวลางานค่อนข้างง่ายและไม่อนุญาตให้มีการกรองข้อมูลเหตุการณ์ - มันช่วยให้คุณกรองข้อมูลเมตาเท่านั้นซึ่งในกรณีนี้ไม่ได้บอกอะไรคุณเกี่ยวกับบริการใดบ้าง เปลี่ยนสถานะและสถานะที่เปลี่ยนไป ที่จัดขึ้นใน "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 ที่ใส่เข้าไปนั้นเป็นสิ่งที่คุณสนใจ


0

ฉันพบเหตุการณ์ที่ดีขึ้น (IMO) จากบันทึกเหตุการณ์ที่อยู่ภายใต้ Applications and Service Logs-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) ของฉัน อาจเป็นเหตุการณ์เซิร์ฟเวอร์เท่านั้น ....

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.