使用 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
我正在使用 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