- PowerShell allows you to detect connections and disconnections USB in real time and send them to a central server via an API.
- Enabling event channels and using WEF brings enterprise scale and forensic context alongside SIEM.
- Production deployment combines Task Scheduler, endpoint security, and backend hardening.

Connecting memory cards, disks and peripherals via USB can open more doors than it seems: from data leaks to infections by malware without anyone noticing. Monitor and log USB devices entering and leaving the teams is therefore a key measure of ciberseguridad that many organizations already consider basic.
The good news is that the ecosystem Windows offers several approaches, from commercial tools to native methods such as PowerShell and Windows Event Forwarding (WEF). With a well thought out design, USB events can be detected in real time, recorded, sent to a central server and correlated. with other safety signals, all without friction for the user.
Overview and tools for tracking USB devices
In regulated companies (finance, health, etc.), control and traceability are required. The goal is to quickly identify unauthorized devices, prevent exfiltrations and detect attempts to introduce malware from removable media.
If you're looking for something ready-made, there are specific utilities. USB Device Tracker facilitates continuous inventory and auditing, saving identifiers, device type and connection/disconnection times, as well as useful reports to identify patterns or threats.
There are also lightweight utilities. USBDeview (NirSoft) shows present and past USB devices; doesn't send data to a server on its own, but integrates well with scripts to automate exports or notifications in your infrastructure.
In large-scale scenarios, endpoint suites help consolidate. Microsoft Endpoint Manager, ManageEngine Endpoint Central or Ivanti They allow USB device policies and logs at the corporate level, with reports or sending to centralized repositories.
For correlation and alerts, a SIEM like Splunk or Elastic Stack It can ingest USB events and trigger detections in real time. These platforms identify suspicious behavior (connections outside of business hours, unauthorized devices, etc.) and They fit perfectly with a pipeline that feeds data from PowerShell or WEF..

Detection and Response with PowerShell: USB Events and Sending to Server
If you prefer flexibility, a script own in PowerShell is very powerful. You can detect connections and disconnections in real time, enrich with metadata and publish to a REST API for your backend.
First, list USB devices connected at a given time. The Win32_DiskDrive class with InterfaceType USB is a good starting point, although it is advisable to supplement with PnP data for the serial number when available:
# Enumerar almacenamiento USB actual
$usb = Get-CimInstance Win32_DiskDrive | Where-Object { $_.InterfaceType -eq 'USB' }
$enriquecido = foreach ($d in $usb) {
$serial = (Get-CimInstance Win32_PhysicalMedia | Where-Object { $_.Tag -eq $d.DeviceID }).SerialNumber
[PSCustomObject]@{
DeviceID = $d.DeviceID
Model = $d.Model
Interface = $d.InterfaceType
Serial = ($serial -replace '\s+', '').Trim()
}
}
$enriquecido | Format-Table -AutoSize
In addition to inventory, the key is There real. PowerShell can subscribe to system events to react instantly when connecting or removing a device:
# Monitorizar llegada y retirada de volúmenes (EventType 2=arrive, 3=remove)
Unregister-Event -SourceIdentifier USBMonitor -ErrorAction SilentlyContinue
$null = Register-WmiEvent -Class Win32_VolumeChangeEvent -Action {
$e = $Event.SourceEventArgs.NewEvent
$tipo = if ($e.EventType -eq 2) { 'Insert' } elseif ($e.EventType -eq 3) { 'Remove' } else { 'Other' }
$payload = [PSCustomObject]@{
Hostname = $env:COMPUTERNAME
TimeUtc = (Get-Date).ToUniversalTime().ToString('o')
Action = $tipo
Drive = $e.DriveName
}
try {
$json = $payload | ConvertTo-Json -Depth 5
Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -Body $json -ContentType 'application/json'
} catch {
Write-Warning ("Error enviando evento USB: {0}" -f $_.Exception.Message)
}
} -SourceIdentifier USBMonitor
If you also want to capture details of the hardware from the newly inserted USB disk, combines Win32_VolumeChangeEvent with a refresh of Win32_DiskDrive and cross-reference by volume/mounted letter as appropriate. You can also monitor Win32_DeviceChangeEvent for generic device events:
# Alternativa: evento genérico de dispositivo
Unregister-Event -SourceIdentifier USBGeneric -ErrorAction SilentlyContinue
$null = Register-WmiEvent -Class Win32_DeviceChangeEvent -Action {
$e = $Event.SourceEventArgs.NewEvent
$payload = [PSCustomObject]@{
Hostname = $env:COMPUTERNAME
TimeUtc = (Get-Date).ToUniversalTime().ToString('o')
EventType= $e.EventType # 2 insert, 3 remove
}
try {
Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -Body ($payload|ConvertTo-Json) -ContentType 'application/json'
} catch {}
} -SourceIdentifier USBGeneric
For a one-time dump and immediate JSON delivery to your server, the pipeline is direct. The following pattern collects current USB drives, transforms them to JSON and publishes them in an API:
Get-CimInstance Win32_DiskDrive | Where-Object { $_.InterfaceType -eq 'USB' } |
ForEach-Object {
$serial = (Get-CimInstance Win32_PhysicalMedia | Where-Object { $_.Tag -eq $_.DeviceID }).SerialNumber
[PSCustomObject]@{ DeviceID = $_.DeviceID; Model = $_.Model; Serial = ($serial -replace '\s+', '').Trim() }
} |
ConvertTo-Json |
Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -ContentType 'application/json'
Beyond inventory and insertions/removals, Windows logs user driver activity related to USB. Enable the Microsoft-Windows-DriverFrameworks-UserMode/Operational channel and reviews key events: connection (e.g., 2003, 2004, 2006, 2010) and disconnection (2102, 2105, 2106), with useful metadata such as manufacturer, model, or instance paths.
REST API in Flask to centralize logs
You need a simple receiver to store and exploit the data. With Flask you can launch an /api/usblog endpoint. to validate, save and prepare the material for subsequent analysis or sending to SIEM:
from flask import Flask, request, jsonify
from datetime import datetime
app = Flask(__name__)
API_TOKEN = 'cambia-este-token-seguro'
@app.route('/api/usblog', methods=['POST'])
def log_usb():
if request.headers.get('X-Api-Token') != API_TOKEN:
return jsonify({'error': 'Unauthorized'}), 401
data = request.get_json(silent=True)
if not data:
return jsonify({'error': 'No payload'}), 400
line = f"{datetime.utcnow().isoformat()}Z\t{data}\n"
with open('usb_log.txt', 'a', encoding='utf-8') as f:
f.write(line)
return jsonify({'status': 'ok'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
To get it started, Install Flask with pip, save the script (e.g., server.py) and run it. From there, your PowerShell script can send events to http://SERVER_IP:5000/api/usblog by adding an X-Api-Token header if you have enabled it.
Although here we write in a file for simplicity, You can send to a database or to your SIEM, or even fork: to a SIEM for online analytics and a data lake (Hadoop/HDInsight) for long-term retention and high-volume forensics.
Going live: Autostart, Security, WEF, and Analytics
So that you don't depend on anyone's hand after a restart, automates the Boot from the PowerShell script with Task Scheduler or the Startup folder, and protect the deployment with good security practices.
Automatic startup in Windows
With Task Scheduler: Create a task with maximum privileges and trigger at login or system startup. As an action, run powershell.exe with NoProfile and ExecutionPolicy Bypass pointing to your .ps1.
If you prefer the Home folder: Create a .bat file that launches the script and place it in %APPDATA%\Microsoft\Windows\Start Menu\Programs\StartupIt's simple and works well on user workstations.
Example of .bat: powershell.exe -NoProfile -ExecutionPolicy Bypass -File «C:\path\script.ps1», adjusting the path to your environment and ensuring the script is signed or comes from a trusted source.
Safety recommendations
Protect the API: Firewall filtering, require token or mTLS, and apply rate limitsAvoid exposing the endpoint beyond the necessary network and record the minimum amount of personal data required in detail.
Hardens the client: use service accounts with minimum privilegesRotate the token, validate TLS where applicable, and control the ExecutionPolicy with GPOs if applicable; if possible, sign the script and validate integrity.
Conduct regular audits: check the server and client logs, compares unusual patterns and cross-references with device control policies to detect unauthorized access or deviation.
Windows Event Forwarding (WEF) for corporate coverage
When you want scale and resilience in Windows, WEF forwards events to a Windows Event Collector (WEC) server without installing additional agents. It's passive with respect to logging: it doesn't enable channels or change audits; these settings must be applied via GPO.
Double subscription model: baseline (for all computers) and suspect (for a subset after an alert)The suspects list collects more signals for forensic context and can be updated without affecting the rest.
Recommended data destination: Baseline to SEM/SIEM or SQL; suspect to MapReduce/HDInsight/Data Lake due to its volume and lower signal-to-noise ratio. The SIEM correlates and alerts at machine speed; the data retains data for years and allows for complex analysis.
Indicative scalability: Up to 5.000 events/s in SQL/SEM; 5.000-50.000 in SEM; above that, data lakeOn standard WEC servers, the practical figure is around 3.000 events/s in total depending on hardware and disks.
Push vs Pull: The most flexible is subscription initiated by the origin (push) configured by GPO. Pull requires predefining clients in WEC and remote event reading permissions (adding the credential to the Event Log Readers group).
Encryption and authentication: In domain, Kerberos encryption by default (NTLM optional); HTTPS is used with certificate authentication when Kerberos is not available. Authentication is mutual in both cases.
Format and frequency: Default “Rendered Text”; alternative “Events” (XML binary) is more compactDelivery modes: Normal, Minimize bandwidth (push, batches every ~6h), Minimize latency (push, batches ~30s), or custom via WECUTIL with DeliveryMaxItems and DeliveryMaxLatencyTime.
Practical limits of WEC: EVTX log disk (I/O), simultaneous TCP connections and log size (persistent keys per source). For large volumes, wecutil.exe is preferable to the Event Viewer console.
Enable key channels and size logs: DriverFrameworks-UserMode/Operational (enable and expand to ~50 MB), CAPI2/Operational (100 MB and permissions for Event Log Readers), AppLocker (EXE/DLL and MSI/Script, ~100 MB). Use GPO with wevtutil for scripting:
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-DriverFrameworks-UserMode/Operational /e:true
%SystemRoot%\System32\wevtutil.exe sl "Microsoft-Windows-DriverFrameworks-UserMode/Operational" /ms:52432896
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /e:true
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /ms:102432768
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /ca:"O:BAG:SYD:(A;;0x7;;;BA)(A;;0x2;;;AU)(A;;0x1;;;S-1-5-32-573)"
%SystemRoot%\System32\wevtutil.exe sl "Microsoft-Windows-AppLocker/EXE and DLL" /ms:102432768
USB and Device Activity Relevant Events: DriverFrameworks-UserMode: 2003, 2004, 2006, 2010, 2100, 2101, 2105, 2106, and 2102 (disconnected). In the Security and System channel, expand auditing for process creation (4688), registry changes (4657), RDP sessions (4778/4779), shared resources (5140, 5142, 5144), system time (4616), starts/stops (12/13/1074), and others collected in baseline and suspicious subscriptions.
Predefined WEF Subscriptions: “baseline” with security events, AppLocker, Sysmon/Operational (if applicable), SMBClient/Operational, Error Reporting, TaskScheduler/Operational, etc.; and “suspicious” with network (logon type 3), DNS Client/Operational (3008, filtering gaps), CAPI2 (11/70/90), PowerShell/Operational (4103-4106), DriverFrameworks-UserMode/Operational (2004) and more. Set “read existing events” to true on the suspects to scan history.
Advanced Options: force “Events” format with WECUTIL To double capacity and customize latency/batch size:
wecutil ss "NombreSuscripcion" /cf:Events
wecutil ss "NombreSuscripcion" /cm:Custom
wecutil ss "NombreSuscripcion" /dmi:1
wecutil ss "NombreSuscripcion" /dmlt:10
PowerShell Logging and Forensics
PowerShell since v5.0 enables the script block log (4104) by default, with fragmentation into multiple events when the content is large. This allows for the reconstruction of executed scripts, which is key in incident response.
For reconstructions, Filter by ScriptBlock ID and sort by sequence to concatenate the original content, even if you only recover part of it by log rotation:
# Extraer eventos 4104 con un ScriptBlockID concreto
$evts = Get-WinEvent -FilterHashtable @{ Path='C:\Ruta\Microsoft-Windows-PowerShell%4Operational.evtx'; ProviderName='Microsoft-Windows-PowerShell'; Id=4104 } |
Where-Object { $_.Message -like '*51baf005-40a5-4878-ab90-5ecc51cab9af*' }
$sorted = $evts | Sort-Object { $_.Properties[0].Value }
$sorted | Select-Object TimeCreated, ActivityId, Id, Message
# Unir el contenido del script si tuvieras todos los segmentos
# ($sorted | ForEach-Object { $_.Properties[2].Value }) -join '' | Out-File script_reconstruido.ps1 -Encoding UTF8
Golden Rule: Increases log sizes and enables channels that are not active. to avoid losing artifacts due to rotation. In modern environments, increasing channel and EVTX sizes typically doesn't significantly impact performance.
ADAudit Plus and other integrations
For a file server-centric view, ADAudit Plus includes USB Storage Auditing reports with details of “file read,” “file modified,” “copy/paste,” and “removable device plug-in.” It also offers searching by server, path, author of the change, and message.
In broader ecosystems, Microsoft Endpoint Manager, ManageEngine Endpoint Central and Ivanti set policies and consolidate removable device signals, and a SIEM (Splunk/Elastic) collects events and alerts based on rules and machine learning. This framework covers both compliance and early detection.

With all the above, you have a complete route: Real-time inventory and events with PowerShell, central API with Flask, startup automation, end-to-end security, and WEF for scalingIf you also power a SIEM and strengthen security auditing (baseline + suspect), you'll gain granular visibility, forensic context, and the ability to react to unauthorized access or USB infection attempts.
Passionate writer about the world of bytes and technology in general. I love sharing my knowledge through writing, and that's what I'll do on this blog, show you all the most interesting things about gadgets, software, hardware, tech trends, and more. My goal is to help you navigate the digital world in a simple and entertaining way.

