Iniciando tarefa agendada, detectando a conexão do dispositivo USB

24

Eu sei que foi discutido que não é possível iniciar um aplicativo a partir de uma unidade USB durante a conexão devido a limitações de execução automática (ou reprodução automática ??) no Win 7. Mas é possível criar uma tarefa agendada com um gatilho do tipo de evento . Certamente deve haver um evento ocorrendo quando a unidade - ou qualquer outro dispositivo USB - está conectado.

Alguém tem a menor idéia de qual identificação de evento devo usar? Ou pelo menos que tipo de evento? Onde posso encontrar o evento no visualizador de eventos?

gemisigo
fonte

Respostas:

17

O thread Agendador de tarefas: Como sincronizar automaticamente minha unidade flash USB? tem esta resposta por um usuário chamado monótono, que usa o PowerShell junto com o Agendador de tarefas:

Eu tinha a mesma pergunta que você e resolvi algo com o PowerShell (script interno do Windows) usando técnicas do Scripting Guy Blog aqui e aqui . O script é executado continuamente como um processo em segundo plano, que você pode iniciar no logon do sistema com o planejador de tarefas. O script será notificado sempre que uma nova unidade for conectada e, em seguida, faça alguma coisa (aqui você configura o script em vez da tarefa). Como está basicamente em pausa enquanto aguarda a próxima unidade conectada, você não deve encontrar muitos recursos. Aqui vou eu:

1) Inicie o Powershell ISE, que pode ser encontrado no menu Iniciar em Acessórios / Windows Powershell. 2) Copie e cole o seguinte no 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) Você precisa modificar o script acima para informar ao script qual unidade procurar e o que executar. As duas linhas a serem alteradas são:

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

Meu disco rígido USB chamado 'Mirror' é definido como Z: drive. Você poderia usar if ($driveLabel -eq 'MyDiskLabel')se não se importasse com a carta.

start-process "Z:\sync.bat"

Caminho de qualquer tarefa que você deseja executar. No meu exemplo, criei um arquivo em lotes na minha unidade USB que inicia de 3 a 4 linhas de comando das tarefas de backup.

4) Quando terminar, salve seu script em algum lugar (extensão .ps1) e, em seguida, crie uma tarefa no Agendador de Tarefas para que seu script seja executado em segundo plano. O meu fica assim:

  • Disparador: no logon
  • Ação: iniciar um programa
  • Programa / script: powershell
  • Adicione argumentos: -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"

5) Voilà!

6) Coisas extras:

Se você deseja que sua janela de script fique oculta, use estes argumentos:

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

Se você deseja exibir as mensagens de script em um arquivo de log (que é substituído sempre que o script é iniciado, ou seja, no logon), use a seguinte ação da tarefa:

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

Sempre que você quiser finalizar o script oculto em execução, poderá finalizar o processo "PowerShell" no Gerenciador de Tarefas.

A única desvantagem é que nada será executado quando você inicializar o computador com a unidade já conectada. (O script pode ser alterado para executar uma primeira verificação inicialmente, mas eu já tive o suficiente por hoje!)

harrymc
fonte
Eu acho que isso vai funcionar muito bem. Deixe-me mexer com ela e eu vou voltar para você
GiantDuck
1
Está funcionando para drives. Como posso modificar isso para detectar qualquer dispositivo USB inserido e não apenas as unidades?
GiantDuck
O EventType 2 detectará qualquer chegada de dispositivo. Obter os detalhes exigirá um pouco mais de escavação no evento. Mais simples poderia ser a de imprimir os membros $newEvent.SourceEventArgs.NewEventpara os eventos que você está interessado.
harrymc
É bom ver uma resposta promissora após quase 4 anos :) Muito obrigado, GiantDuck & harrymc.
gemisigo
@harrymc Você pode fornecer algum contexto para isso? Eu nunca usei o PowerShell antes. Obrigado!
GiantDuck
6

Como já expliquei nesta discussão (mas tratava-se de executar um programa quando uma unidade USB é removida), o USB Safely Remove , embora não seja gratuito, pode executar um programa quando alguns eventos sobre dispositivos USB são acionados:

Outro recurso USB Safely Remove, que o distingue de um software semelhante, está iniciando qualquer aplicativo não apenas após a conexão de um dispositivo , mas também antes de removê-lo. O recurso de execução automática permite configurar o backup de dados antes de desconectar um disco rígido removível, executar o Total Commander com o conteúdo do pen-drive, desmontar automaticamente um drive TrueCrypt criptografado antes de desconectar a mídia USB, etc.

insira a descrição da imagem aqui

Obviamente, isso não responde totalmente à pergunta, pois não se trata de usar tarefas agendadas, mas o objetivo é o mesmo, eu acho, que é executar um programa específico quando um dispositivo USB estiver conectado.

Snark
fonte
Muito obrigado, é uma boa solução alternativa. Eu tentei, mas apesar de funcionar corretamente, ainda estou tentando alcançar meu objetivo original (ou seja, usar uma solução disponível e nativamente disponível). Até agora, descobri que o uso de eventos do Event ID 2006 no DriverFrameworks-UserMode posso desencadear a ação. Ainda não é perfeito. As informações necessárias estão disponíveis nos detalhes do evento, mas não posso filtrá-las para uma unidade USB específica, portanto, conectar qualquer unidade USB fará com que o gatilho seja acionado.
Gemisigo #
5

Deve ser bastante fácil usar o EventVwr.

  1. Encontre o evento que você deseja - Quando conectei um dispositivo de armazenamento em massa USB, ele acionou os seguintes eventos (na categoria de aplicativo): 20001, 20003, 7036 e alguns outros menos relevantes. Teste esses eventos com outros eventos de dispositivos USB para evitar falsos positivos.

  2. clique com o botão direito do mouse no evento e clique em "Anexar tarefa a este evento" (relevante apenas no Windows Vista ou superior - para XP existe o CLI EventTrigger), escolha "Iniciar um programa" e aponte-o para o script que deseja executar.

  3. Para passar para o script os parâmetros do evento, consulte este artigo . Nos eventos 20001 e 20003, você pode encontrar o caminho UNC para o novo armazenamento. Usando o utilitário Sysinternals Junction, você pode criar links para os caminhos UNC.

EliadTech
fonte
Eu gosto da ideia disso, mas não é suficientemente detalhada; Eu não posso fazê-lo funcionar.
GiantDuck 26/11
@GiantDuck Para mim, parece bem direto, sobre o que você gostaria que eu elaborasse?
EliadTech #
Não consigo encontrar esses eventos no Visualizador de Eventos. (No Win8 no momento) Qual é o caminho exato? Obrigado!
GiantDuck
Eu escrevi, está no log de 'aplicativo' com os números de eventos mencionados acima. Mas eu testei isso no Win7, então talvez no Win8 os números dos eventos sejam diferentes. Como eu disse, você precisará fazer alguns testes de qualquer maneira para garantir que funcione com qualquer dispositivo conectado.
EliadTech #
1
No Win10, nada apareceu na categoria Aplicativo. Eu tinha que ir para Sistema e anexar do evento ID 98. É bom para mim porque eu só vai ter que um dispositivo, mas outros podem não funcionar
dbinott
2

Consegui fazer isso funcionar: Encontrei o evento 1003 nos logs de aplicativos e serviços, Microsoft-Windows-DriverFrameworks-UserMode para um telefone conectado a usb

XML completo do 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>

E o filtro de evento personalizado para minha tarefa:

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

Da mesma forma, para uma unidade USB, foi o evento 2100, 2101, 2105, 2106.
Para uma unidade 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 o evento 2101 acontece 3 vezes com "<request>"tags ligeiramente diferentes quando eu conecto minha unidade USB:

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

Não tenho idéia do que isso significa, mas aqui está um filtro para apenas um deles evitar vários disparos: (isso só será acionado para esta unidade 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>

Observe que os e comerciais devem ser escapados como &amp;

garbb
fonte
1

Como já mencionado, parece que o evento 7036 do log do sistema do Service Control Manager é o único evento que se correlaciona de maneira confiável com a inserção de uma unidade USB. Verifiquei isso inserindo uma unidade USB e executando o seguinte comando powershell para listar todas as entradas do log de eventos de todas as fontes na última hora:

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

Infelizmente, o Evento 7036 é gerado toda vez que o Service Control Manager inicia ou interrompe com êxito qualquer serviço, portanto, é necessária uma filtragem adicional.

A filtragem disponível na GUI do Event Viewer / Task Scheduler é bastante básica e não permite nenhuma filtragem nos dados do evento - apenas permite filtrar os metadados que, nesse caso, não informam sobre o serviço. estado alterado e em que estado foi alterado. Isso é mantido em "param1" e "param2" do EventData. O seguinte filtro XPath pode, portanto, ser usado para capturar apenas o serviço relevante inicializado:

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

A partir daí, você pode executar seu script, idealmente com alguma lógica adicional para verificar se a unidade USB que foi inserida é a que você está interessado.

sahmeepee
fonte
0

Encontrei um evento (IMO) melhor no log de eventos localizado em Aplicativos e Logs de Serviço-Microsoft-Windows-Ntfs_Operational. Eventid 4. É assim:

Identificação do evento 4 O volume NTFS foi montado com êxito.

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

A partir disso, você pode criar um gatilho de tarefa agendada e filtrar por nome e / ou rótulo de volume. Este evento foi encontrado em uma caixa do Windows Server 2019, no entanto, por algum motivo, não o vejo na área de trabalho do Windows 10 (1809). Pode ser um evento apenas para servidor ....

RyanG
fonte