Michael
Michael

Reputation: 67

Using PowerShell to start batch file for secure wipe USB drive

I'm using PowerShell to start a bat file that wipes a USB drive that connected. If I use the script without Start-Process it works fine, but I'm wanting to connect multiple drives and have it wipe them simultaneously.

The script:

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

The bat file contents:

set arg1=%1
set arg2=%2

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

EDIT

To clarify: the script is to run continously on a specific PC where it should start the bat file (as in wipe the disk securely) every time it detects a disk being connected. If I use:

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

then it starts the wiping on 1 disk, and on 1 disk only.

I need it to detect multiple disks, that's why I used Start-Process, seeing as I thought it would run on the background and keep watching for new events.

EDIT2

I changed the code to avoid using -ArgumentList, see above.

If I put the echo command in my batch file as requested:

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

So I see the commands in the bat file, but it doesn't execute and goes straight for the copy command.

Upvotes: 0

Views: 1309

Answers (1)

colsw
colsw

Reputation: 3326

This is a slightly modified version of a Script I wrote a while back, I don't have time right now to confirm it works 100% but it should at least point you in the right direction, it just threads the actual wiping so it can handle other jobs in the background, then uses a global popup to warn when one is done to prevent having to block while the job is finishing.

Should be able to handle any number of devices at once, it uses PowerShell's Format-Volume command instead, but you could put a call to the BAT file inside the job instead.

$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

Upvotes: 2

Related Questions