You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell磁盘信息采集脚本问题:USB接入重复显示所有磁盘信息

Fix: Show Only New USB Device on Arrival in PowerShell Script

Got it, let's tackle this problem. The core issue with your current script is that when a USB arrives, you're pulling all disk drives via Get-WmiObject win32_diskdrive and looping through every single one—hence why you see all existing disks every time. Instead, we need to target only the device that triggered the arrival event.

Why This Happens

The Win32_VolumeChangeEvent already gives us the drive letter of the new device via its DriveName property. We can use that to trace back to the specific disk drive, partition, and serial number without scanning every connected drive.

Modified Script

Here's the adjusted version that only shows the newly inserted USB device, plus fixes the removal event logging (your original code had undefined variables there):

Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange
Write-Host (Get-Date -Format s) " Beginning script..."

do {
    $newEvent = Wait-Event -SourceIdentifier volumeChange
    $eventDetails = $newEvent.SourceEventArgs.NewEvent
    $eventType = $eventDetails.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) {
        # Get the drive letter from the event (e.g., "D:")
        $targetDriveLetter = $eventDetails.DriveName
        if ($targetDriveLetter) {
            # Trace from the logical volume back to the disk drive
            $volume = Get-WmiObject -Class Win32_Volume | Where-Object { $_.Name -eq "$targetDriveLetter\" }
            if ($volume) {
                $partition = Get-WmiObject -Query "ASSOCIATORS OF {Win32_Volume.DeviceID=`"$($volume.DeviceID.Replace('\','\\'))`"} WHERE AssocClass = Win32_LogicalDiskToPartition"
                if ($partition) {
                    $diskDrive = Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($partition.DeviceID.Replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"
                    if ($diskDrive) {
                        # Display only the new USB device info
                        Write-Host "`nNew USB Device Detected:"
                        Write-Host "Device ID: $($diskDrive.DeviceID.Substring(4))"
                        Write-Host "Model: $($diskDrive.Model)"
                        Write-Host "Drive Letter: $targetDriveLetter"
                        Write-Host "Serial Number: $($volume.SerialNumber)"

                        # Log the event
                        Write-EventLog -LogName Application -Source 'usb2.ps1' -EntryType Information -EventId 1 -Category 0 -Message "Date:$(Get-Date -Format s) Event detected:$eventTypeName Serial:$($volume.SerialNumber) Name:$($diskDrive.Model) Drive:$targetDriveLetter"
                    }
                }
            }
        }
    }

    if ($eventType -eq 3) {
        # Get the drive letter being removed
        $removedDriveLetter = $eventDetails.DriveName
        if ($removedDriveLetter) {
            # Try to get last known info (or adjust if you need to track previously seen devices)
            $lastVolume = Get-WmiObject -Class Win32_Volume | Where-Object { $_.Name -eq "$removedDriveLetter\" } -ErrorAction SilentlyContinue
            $logMessage = if ($lastVolume) {
                "Date:$(Get-Date -Format s) Event detected:$eventTypeName Drive:$removedDriveLetter Serial:$($lastVolume.SerialNumber)"
            } else {
                "Date:$(Get-Date -Format s) Event detected:$eventTypeName Drive:$removedDriveLetter (No serial number found)"
            }
            Write-EventLog -LogName Application -Source 'usb2.ps1' -EntryType Information -EventId 1 -Category 0 -Message $logMessage
        }
    }

    Remove-Event -SourceIdentifier volumeChange
} while ($true) # Loop until next event

Unregister-Event -SourceIdentifier volumeChange

Key Improvements

  • Targeted Querying: Instead of scanning all disks, we use the event's DriveName to trace directly to the new USB device, saving resources and avoiding duplicate output.
  • Fixed Removal Event: The original code tried to use $serial and $drive variables that weren't defined in the removal block—this version uses the event's drive letter to log relevant info.
  • Cleaner Output: Only the newly inserted device's details are displayed when an arrival event triggers.

Notes

  • Make sure your script has permission to write to the Application event log (you might need to run PowerShell as Administrator).
  • If you need to track multiple USB devices over time, you could add a variable to store previously seen devices, but for the core request of showing only the new device on arrival, this should work perfectly.

内容的提问来源于stack exchange,提问作者Sovakah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:27:58