Inicio de la tarea programada detectando la conexión del dispositivo USB

24

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

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

gemisigo
fuente

Respuestas:

17

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

Tenía la misma pregunta que tú, y resolví algo con powershell (scripting integrado de Windows) usando técnicas del Scripting Guy Blog aquí y aquí . El script se ejecuta continuamente como un proceso en segundo plano, que puede comenzar en el inicio de sesión del sistema con el programador de tareas. El script será notificado cada vez que se conecte una nueva unidad y luego haga algo (aquí configura el script en lugar de la tarea). Dado que está básicamente en pausa mientras espera la próxima unidad conectada, no debería encontrar que ocupa muchos recursos. Aquí voy:

1) Inicie Powershell ISE, que se puede encontrar en su menú de inicio en Accesorios / Windows Powershell. 2) Copie y pegue lo siguiente en 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) Debe modificar la secuencia de comandos anterior para indicarle qué unidad debe 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 la unidad Z:. Podrías usarlo if ($driveLabel -eq 'MyDiskLabel')si no te importara la carta.

start-process "Z:\sync.bat"

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

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 que su script se ejecute en segundo plano. El mío se ve así:

  • Activador: al iniciar sesión
  • Acción: iniciar un programa
  • Programa / script: powershell
  • Añadir 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:

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

Si desea enviar los mensajes de script a un archivo de registro (que se sobrescribe cada vez que se inicia el script, es decir, al iniciar sesión), utilice la 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 el proceso "Powershell" en el Administrador de tareas.

El único inconveniente es que no se ejecutará nada cuando inicie su computadora con la unidad ya conectada.

harrymc
fuente
Creo que esto funcionará muy bien. Déjame jugar con eso y te
responderé
1
Está funcionando para las unidades. ¿Cómo puedo modificar esto para detectar cualquier dispositivo USB insertado, y no solo unidades?
GiantDuck
EventType 2 detectará la llegada de cualquier dispositivo. Obtener los detalles requerirá profundizar un poco más en el evento. Podría ser más simple para imprimir los miembros de $newEvent.SourceEventArgs.NewEventlos eventos de su interés en.
harrymc
Es bueno ver una respuesta prometedora después de casi 4 años :) Muchas gracias, GiantDuck & harrymc.
gemisigo
@harrymc ¿Puedes proporcionar algún contexto para eso? Nunca he usado PowerShell antes. ¡Gracias!
GiantDuck
6

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

Otra característica de USB Safely Remove que lo distingue de un software similar es iniciar cualquier aplicación no solo después de conectar un dispositivo , sino también antes de eliminarlo. La función de ejecución automática le permite configurar la copia de seguridad de datos antes de desconectar un disco duro extraíble, ejecutar Total Commander con el contenido del pen-drive, desmontar automáticamente una unidad cifrada TrueCrypt antes de desconectar el dispositivo USB, etc.

ingrese la descripción de la imagen aquí

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.

Snark
fuente
Muchas gracias, es una buena solución. Lo he intentado, pero a pesar de que funciona correctamente, todavía estoy tratando de lograr mi objetivo original (es decir, usar una solución disponible de forma nativa y gratuita). Hasta ahora he descubierto que usando los eventos de Event ID 2006 de 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 enchufar cualquier unidad USB hará que se dispare el gatillo.
gemisigo
5

Debería ser bastante fácil usar EventVwr.

  1. Encuentre el evento que desea: cuando conecté un dispositivo de almacenamiento masivo USB, se activaron los siguientes eventos (en la categoría de 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), elija "Iniciar un programa" y apúntelo al script que desea ejecutar.

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

EliadTech
fuente
Me gusta la idea de esto, pero no es lo suficientemente detallada; No puedo conseguir que funcione.
GiantDuck
@GiantDuck Para mí, parece bastante sencillo, ¿qué le gustaría que elaborara?
EliadTech
No puedo encontrar dichos eventos en el Visor de eventos. (En Win8 en este 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 he probado esto en Win7, así que tal vez en Win8 los números de evento son diferentes. Como dije, de todas formas necesitará hacer algunas pruebas para asegurarse de que funcionará con cualquier dispositivo que esté conectando.
EliadTech
1
En Win10 no apareció nada en la categoría Aplicación. Tuve que ir a Sistema y adjuntar a la multa de Evento ID 98. Es para mí porque yo te sólo tenga que un dispositivo, pero otros pueden no trabajo
dbinott
2

Pude hacer que esto funcionara: encontré el evento 1003 en registros de aplicaciones y servicios, Microsoft-Windows-DriverFrameworks-UserMode para un teléfono conectado a 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 eventos 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 una unidad 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 "<request>"etiquetas ligeramente diferentes cuando conecto 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 solo uno de ellos para evitar disparadores múltiples: (esto solo se disparará 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 símbolos de unión deben escapar como &amp;

atuendo
fuente
1

Como otros han mencionado, 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 inserta. Verifiqué esto insertando una unidad USB y ejecutando el siguiente comando powershell para enumerar todas las entradas del registro de eventos de todas las fuentes en la última hora:

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

Desafortunadamente, el Evento 7036 se genera cada vez que Service Control Manager inicia o detiene con éxito cualquier servicio, por lo que se requiere un filtrado adicional.

El filtrado disponible en la GUI del Visor de eventos / 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 a qué estado ha cambiado. Eso se lleva a cabo en "param1" y "param2" de EventData. Por lo tanto, el siguiente filtro XPath se puede utilizar para capturar solo el servicio relevante que se está iniciando:

<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 secuencia de comandos, idealmente con una lógica adicional para verificar que la unidad USB que se ha insertado es la que le interesa.

sahmeepee
fuente
0

Encontré un evento mejor (IMO) en el registro de eventos ubicado en Aplicaciones y registros de servicio-Microsoft-Windows-Ntfs_Operational. Eventid 4. Se ve así:

ID. De suceso 4 El volumen NTFS se ha montado correctamente.

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

A partir de eso, puede crear un activador de tareas programadas y filtrar por nombre de volumen o etiqueta. Este evento se encontró en un cuadro de Windows Server 2019, sin embargo, por alguna razón, no lo veo en mi escritorio de Windows 10 (1809). Puede ser un evento solo de servidor ...

RyanG
fuente