使用 PowerShell 启动批处理文件以安全擦除 USB 驱动器

Using PowerShell to start batch file for secure wipe USB drive

我正在使用 PowerShell 启动一个 bat 文件来擦除连接的 USB 驱动器。 如果我在没有 Start-Process 的情况下使用脚本,它工作正常,但我想连接多个驱动器并让它同时擦除它们。

剧本:

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 ($driveLabel -eq 'BBIFREE_01' -or $drivelabel -eq 'HD10') {
            Write-Host (Get-Date -Format s) " Starting task in 3 seconds..."
            Start-Sleep -Seconds 3
            Start-Process -FilePath D:\wipe.bat $driveLetter, $driveLabel
            Copy-Item -Path D:\Utilities1 -Destination $driveLetter -Recurse

            $driveEject = New-Object -ComObject Shell.Application
            $driveEject.Namespace(17).ParseName($driveLetter).InvokeVerb("Eject")
        }
    }
    Remove-Event -SourceIdentifier VolumeChange
} while (1 -eq 1) #Loop until next event
Unregister-Event -SourceIdentifier VolumeChange

bat文件内容:

set arg1=%1
set arg2=%2

format %args1% /FS:NTFS /p:1 /V:%args2%  /x /y

编辑

澄清一下:每次检测到连接的磁盘时,脚本都会在特定 PC 上连续 运行 启动 bat 文件(如安全擦除磁盘)。 如果我使用:

D:\wipe.bat -ArgumentList `"$driveLetter",`"$driveLabel"

然后开始擦除 1 个磁盘,并且仅擦除 1 个磁盘。

我需要它来检测多个磁盘,这就是我使用 Start-Process 的原因,因为我认为它会在后台 运行 并继续监视新事件。

EDIT2

我更改了代码以避免使用 -ArgumentList,见上文。

如果我按要求将 echo 命令放入我的批处理文件中:

set arg1=E:
set arg2=BBIFREE_01
ECHO ECHO IS ON
ECHO ECHO IS ON

所以我看到了bat文件中的命令,但是没有执行,直接复制命令。

这是我前段时间写的脚本的略微修改版本,我现在没有时间确认它 100% 有效,但它至少应该为您指明正确的方向,它只是线程实际擦除,以便它可以在后台处理其他作业,然后使用全局弹出窗口在完成时发出警告,以防止在作业完成时不得不阻塞。

应该能够同时处理任意数量的设备,它使用 PowerShell 的 Format-Volume 命令代替,但您可以改为调用作业中的 BAT 文件。

$USBWhiteList = @( #Add wildcard items here, if a USB matches one it will be wiped.
    "USB0*"
    "*WIPE"
)

Enum EventNames{ Changed = 1 ; Inserted = 2 ; Removed = 3 ; Docking = 4 } #Names for events
Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange -ErrorAction SilentlyContinue #register the event
do{
    Write-Host "Monitoring for Disk events..." -Fore Yellow
    $Event = Wait-Event -SourceIdentifier volumeChange #wait for a disk event
    $EventType = [EventNames]$Event.SourceEventArgs.NewEvent.EventType #get the type of the event
    Write-Host "Drive $($EventType), Processing..." -Fore Yellow -NoNewline
    $Volume = Get-Volume -DriveLetter $Event.SourceEventArgs.NewEvent.DriveName -ErrorAction SilentlyContinue #get the volume details
    $IsMatch = ($USBWhiteList|? {$Volume.FileSystemLabel -like $_}).Count -gt 0 #does it match our whitelist?
    if (($EventType -eq [EventNames]::Inserted) -and $IsMatch){ #if a disk was inserted which matches the whitelist...
        Write-Host "Volume $($Volume.DriveLetter): '$($Volume.FileSystemLabel)', Found, Wiping!" -Fore Green
        Start-Job -ScriptBlock { param ($Volume) #Perform the wipe inside a job
            $Disk = Get-Partition -DriveLetter $Volume.DriveLetter | Get-Disk
            Clear-Disk -Number $Disk.Number -RemoveData -Confirm:$false
            New-Partition -DiskNumber $Disk.Number -UseMaximumSize -IsActive -DriveLetter $Volume.DriveLetter
            Format-Volume -FileSystem NTFS -DriveLetter $Volume.DriveLetter -Confirm:$false
            Add-Type -AssemblyName 'System.Windows.Forms' #warn (globally) when it is finished, don't need to run wait/recieve job.
            [System.Windows.Forms.MessageBox]::Show("Finished Wiping Disk $($Volume.DriveLetter)","Please Remove Disk")
        } -ArgumentList $Volume | Out-Null
    } else {
        Write-Host "Ignoring" -Fore Red
    }
    Remove-Event -SourceIdentifier volumeChange
} while (1) #this should be modified to quit after x disks or something, the below commands won't get exec'd - could also use a Try/Finally and Ctrl+C the script.
Get-Job | Remove-Job -Force
Unregister-Event -SourceIdentifier volumeChange