我正在使用PowerShell启动一个擦除连接的USB驱动器的bat文件。
如果我使用没有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
修改
澄清一下:该脚本将在每次检测到连接的磁盘时,在应该启动bat文件的特定PC上连续运行(如安全地擦除磁盘)。 如果我使用:
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文件中看到了命令,但它没有执行,直接用于复制命令。
答案 0 :(得分:2)
这是我稍后写过的一个稍微修改过的脚本版本,我现在没有时间确认它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