Pregunta Iniciar la tarea programada detectando la conexión del dispositivo USB


Sé que se ha discutido que no es posible iniciar una aplicación desde una unidad usb tras la conexión debido a las limitaciones de ejecución automática (o reproducción automática) en Win 7. Pero es posible crear una tarea programada que tenga un tipo de evento desencadenante . Seguramente debe haber un evento que ocurra cuando la unidad - o cualquier dispositivo USB, para el caso - esté conectado.

¿Alguien tiene la menor idea de qué ID de evento debería usar? ¿O al menos qué tipo de evento? ¿Dónde puedo encontrar el evento en el visor de eventos?


20


origen




Respuestas:


La amenaza Programador de tareas: ¿Cómo sincronizar automáticamente mi unidad flash USB? tiene esta respuesta de un usuario llamado monotone, que usa PowerShell junto con el Programador de tareas:

Tuve la misma pregunta que tú, y resolví algo con   powershell (guiones incorporados en Windows) usando técnicas del   Blog de Scripting Guy aquí y aquí. La secuencia de comandos se ejecuta   continuamente como un proceso en segundo plano, que puede comenzar en el sistema   inicio de sesión con el programador de tareas. El script será notificado cada vez que un nuevo   unidad está conectada y luego hacer algo (aquí configura la secuencia de comandos   en lugar de la tarea). Dado que básicamente está en pausa mientras espera   la próxima unidad conectada, no deberías encontrar que ocupa mucho   recursos. Aquí voy:

1) Inicie Powershell ISE, que puede encontrar en su menú de inicio en   Accesorios / Windows Powershell. 2) Copia y pega lo siguiente en   Potencia Shell:

#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) Debe modificar el script anterior para indicar al script qué unidad   buscar y qué ejecutar. Las dos líneas para cambiar son:

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

Mi disco duro usb llamado 'Mirror' está configurado como Z: drive. Tú podrías   Solo usa if ($driveLabel -eq 'MyDiskLabel') si no te importa   la carta.

start-process "Z:\sync.bat"

Ruta de cualquier tarea que quieras hacer. En mi ejemplo, he creado un   archivo por lotes en mi unidad USB que inicia el comando 3-4 tareas de copia de seguridad   líneas.

4) Cuando haya terminado, guarde su script en algún lugar (extensión .ps1),   luego vaya a crear una tarea en el Programador de tareas para ejecutar su secuencia de comandos   fondo. El mío se ve así:

  • Disparador: al iniciar sesión
  • Acción: Comience un programa
  • Programa / script: powershell
  • Agregar argumentos: -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"

5) ¡Voilà!

6) Cosas extra:

Si desea que su ventana de script esté oculta, use estos argumentos:

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

Si desea generar los mensajes del script en un archivo de registro (que obtiene   se sobrescribe cada vez que se inicia el script, es decir, al iniciar sesión), utilice el   siguiente acción de tarea:

  • Programa / script: cmd
  • Agregar argumentos:
    /c powershell -WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1" > "D:\Stuff\script   log.txt "

Cada vez que desee finalizar el script oculto en ejecución, puede finalizar   Proceso "Powershell" en el Administrador de tareas.

El único inconveniente es que nada se ejecutará cuando arranque su computadora   con la unidad ya conectada. (La secuencia de comandos podría cambiarse a   realizar un primer control inicialmente, pero he tenido suficiente para   ¡hoy!)


12



Creo que esto funcionará bien. Déjame jugar con eso y me pondré en contacto contigo - GiantDuck
Está funcionando para unidades. ¿Cómo puedo modificar esto para detectar alguna Dispositivo USB insertado, y no solo unidades - GiantDuck
EventType 2 detectará la llegada de cualquier dispositivo. Obtener los detalles requerirá más investigación sobre el evento. Lo más simple podría ser imprimir los miembros de $newEvent.SourceEventArgs.NewEvent para los eventos que te interesan - harrymc
Es bueno ver una respuesta prometedora después de casi 4 años :) Muchas gracias, GiantDuck y harrymc. - gemisigo
@harrymc ¿Puedes proporcionar un contexto para eso? Nunca he usado powershell antes. ¡Gracias! - GiantDuck


Como ya expliqué en esta discusión(pero se trataba de ejecutar un programa cuando se elimina una unidad USB), USB de forma segura, aunque no es gratuito, puede ejecutar un programa cuando se desencadenan algunos eventos sobre dispositivos USB:

Otra característica de USB Safely Remove que   lo distingue de un software similar   es iniciando cualquier aplicación no solo   después de conectar un dispositivo, pero también   antes de quitarlo La ejecución automática   característica le permite configurar datos   copia de seguridad antes de desconectar un   disco duro extraíble, para ejecutar Total   Comandante con los contenidos de la   pen-drive, desmontar automáticamente una   unidad cifrada TrueCrypt antes   desconectando los medios USB, etc.

enter image description here

Por supuesto, esto no responde completamente a la pregunta, ya que no se trata de usar tareas programadas, pero el objetivo es el mismo, creo, que es ejecutar un programa específico cuando se conecta una memoria USB.


6



Muchas gracias, una buena solución, lo es. Lo he intentado, pero a pesar de que funciona correctamente, todavía estoy tratando de lograr mi objetivo original (es decir, utilizando una solución nativa disponible y gratuita). Hasta ahora, he descubierto que al usar eventos de Event ID 2006 desde DriverFrameworks-UserMode, puedo activar la acción. Sin embargo, todavía no es perfecto. La información necesaria está disponible en los detalles del evento, pero no puedo filtrarla para una unidad USB específica, por lo que al conectar cualquier unidad USB se disparará el gatillo. - gemisigo


Debería ser bastante fácil usando EventVwr.

  1. Encuentre el evento que desea: cuando conecté un dispositivo de almacenamiento masivo USB, activó los siguientes eventos (en la categoría de la aplicación): 20001, 20003, 7036 y algunos otros menos relevantes. Asegúrese de probar esos eventos contra otros eventos de dispositivos USB para evitar falsos positivos.

  2. haga clic derecho en el evento y haga clic en "Adjuntar tarea a este evento" (relevante solo en Windows Vista o superior - para XP hay CLI EventTrigger), seleccione "Iniciar un programa" y apúntelo al script que desea ejecutar.

  3. Para pasar al script los parámetros del evento que necesita echar un vistazo a Este artículo. En los eventos 20001 y 20003, puede encontrar la ruta UNC al nuevo almacenamiento. Utilizando la utilidad Sysinternals Junction puede crear enlaces a las rutas UNC.


5



Me gusta la idea de esto, pero no es lo suficientemente detallado; No puedo conseguir que funcione. - GiantDuck
@GiantDuck Para mí, parece bastante sencillo, ¿qué te gustaría que elabore? - EliadTech
No puedo encontrar dichos eventos en el Visor de eventos. (En Win8 por el momento) ¿Cuál es el camino exacto? ¡Gracias! - GiantDuck
Escribí, está bajo el registro de 'aplicación' con los números de evento mencionados anteriormente. Pero probé esto en Win7, así que tal vez en Win8 los números de evento son diferentes. Como dije, necesitarás hacer algunas pruebas de todos modos para asegurarte de que funcione con cualquier dispositivo que estés conectando. - EliadTech
En Win10, nada apareció en la categoría de Aplicación. Tenía que ir al Sistema y adjuntarlo al Evento ID 98. Está bien para mí porque solo tendré ese dispositivo, pero otros pueden no funcionar - dbinott


Pude hacer que esto funcione: Encontré el evento 1003 en registros de aplicaciones y servicios, Microsoft-Windows-DriverFrameworks-UserMode para un teléfono conectado al usb

Xml completo del evento:

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

Y el filtro de evento personalizado para mi tarea:

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

Del mismo modo para un dispositivo USB, fue el evento 2100, 2101, 2105, 2106
Para una unidad USB específica:

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

Parece que el evento 2101 ocurre 3 veces con un poco diferente "<request>" etiquetas cuando enchufo mi unidad usb:

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

No tengo idea de lo que esto significa, pero aquí hay un filtro para que solo uno de ellos evite múltiples activadores: (esto solo se activará para esta unidad USB específica)

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

Tenga en cuenta que los signos y símbolos se deben escapar como &amp;


2





Como han mencionado otros, parece que el evento de registro del sistema 7036 del Administrador de control de servicios es el único evento que se correlaciona de manera confiable con una unidad USB que se está insertando. Lo comprobé insertando una unidad USB y ejecutando el siguiente comando de PowerShell para listar todas las entradas de registro de eventos de todas las fuentes en la última hora:

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

Lamentablemente, el Evento 7036 se genera cada vez que el Administrador de control de servicios inicia o detiene con éxito cualquier servicio, por lo que se requiere un filtrado adicional.

El filtrado disponible en la GUI del Visor de sucesos / Programador de tareas es bastante básico y no permite ningún filtrado en los datos del evento; solo le permite filtrar los metadatos que en este caso no le dicen nada sobre qué servicio tiene estado cambiado y en qué estado ha cambiado. Eso se lleva a cabo en "param1" y "param2" de EventData. El siguiente filtro XPath se puede usar para capturar solo el servicio relevante que se inicia:

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

Desde allí puede ejecutar su script, idealmente con alguna lógica adicional para verificar que la unidad USB que se ha insertado sea la que le interese.


1