web-dev-qa-db-ja.com

USBデバイスの接続を検出してスケジュールされたタスクを開始する

Win 7の自動実行(または自動再生??)の制限により、接続時にUSBドライブからアプリケーションを起動できないことが説明されていますが、イベントタイプトリガーを持つスケジュールされたタスクを作成することは可能です。 。確かに、ドライブ、またはUSBデバイスは、接続されているときにイベントが発生しているはずです。

どのイベントIDを使用すればよいか、だれでも簡単に理解できますか?または、少なくともどのような種類のイベントですか?イベントビューアのどこでイベントを見つけることができますか?

25
gemisigo

スレッド タスクスケジューラ:USBフラッシュドライブを自動的に同期する方法? は、PowerShellをタスクスケジューラと一緒に使用するモノトーンと呼ばれるユーザーがこの答えを持っています。

私はあなたと同じ質問をして、Scripting Guyのブログ herehere の手法を使用して、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)上記のスクリプトを変更して、どのドライブを検索し、何を実行するかをスクリプトに指示する必要があります。変更する2つの行は次のとおりです。

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

「ミラー」という名前のUSBハードドライブが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」プロセスを終了できます。

唯一の欠点は、ドライブが既に接続されているコンピューターを起動しても何も実行されないことです(ただし、スクリプトを変更して、最初のチェックを最初に実行することもできますが、今日は十分です)。

17
harrymc

この説明 ですでに説明したように(ただし、USBドライブが取り外されたときにプログラムを実行することについてでした)、 USBを安全に取り外します 無料ではありませんが、USBデバイスに関するいくつかのイベントがトリガーされたときにプログラムを実行できます。

同様のソフトウェアと区別する別のUSB安全な取り外し機能は、デバイスを接続した後だけでなく、削除する前にもアプリケーションを起動します。自動実行機能を使用すると、リムーバブルハードドライブを切断する前にデータバックアップを設定したり、ペンドライブの内容でTotal Commanderを実行したり、USBメディアを切断する前に暗号化されたTrueCryptドライブを自動的にマウント解除したりできます。

enter image description here

もちろん、これはスケジュールされたタスクの使用に関するものではないため、質問に完全に答えるものではありませんが、目的は同じで、USBスティックが接続されているときに特定のプログラムを実行することです。

6
Snark

EventVwrを使用すると、非常に簡単です。

  1. 必要なイベントを見つける-USB大容量ストレージデバイスを接続すると、(アプリケーションカテゴリの下で)次のイベントがトリガーされました:20001、20003、7036、およびその他の関連性の低いいくつかのイベント。これらのイベントを他のUSBデバイスイベントに対してテストして、誤検知を回避してください。

  2. イベントを右クリックし、[このイベントにタスクをアタッチ]をクリックします(Windows Vista以降のみに関連-XP CLI EventTriggerがある場合))、[プログラムの開始]を選択して、実行するスクリプト。

  3. スクリプトにイベントパラメータを渡すには、必要なイベントパラメータ この記事 を調べます。イベント20001および20003の下で、新しいストレージへのUNCパスを見つけることができます。 Sysinternals Junctionユーティリティを使用して、UNCパスへのリンクを作成できます。

5
EliadTech

これを機能させることができました。アプリケーションとサービスのログでイベント1003が見つかりました。USBに接続された電話のMicrosoft-Windows-DriverFrameworks-UserModeです。

イベントの完全な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>

USBドライブを接続すると、イベント2101がわずかに異なる"<request>"タグで3回発生するようです。

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

私はこれが何を意味するのかわかりませんが、複数のトリガーを回避するためにそのうちの1つだけのフィルターがあります(これはこの特定の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;としてエスケープする必要があることに注意してください

2
garbb

他の人が述べたように、サービスコントロールマネージャーからのシステムログイベント7036は、挿入されているUSBドライブと確実に相関する唯一のイベントのようです。これを確認するには、USBドライブを挿入し、次のpowershellコマンドを実行して、過去1時間のすべてのソースからのすべてのイベントログエントリを一覧表示します。

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

残念ながら、このイベント7036はサービスコントロールマネージャーがサービスを正常に開始または停止するたびに生成されるため、追加のフィルタリングが必要です。

イベントビューア/タスクスケジューラの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ドライブが目的のものであることを確認するための追加のロジックを配置します。

1
sahmeepee

アプリケーションとサービスログ-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)デスクトップに表示されません。サーバーのみのイベントである可能性があります...

0
RyanG