Skip to content

Instantly share code, notes, and snippets.

@jonthysell
Created September 23, 2021 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonthysell/ef3f149ae8f6564925fd3943a7ad3701 to your computer and use it in GitHub Desktop.
Save jonthysell/ef3f149ae8f6564925fd3943a7ad3701 to your computer and use it in GitHub Desktop.
SCSI2SD manage.cmd script
@@echo off
@@setlocal
:RunPowerShellScript
@@pushd %~dp0
@@set POWERSHELL_BAT_ARGS=%*
@@if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
@@PowerShell -ExecutionPolicy RemoteSigned -Command Invoke-Expression $('$args=@(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join([Environment]::NewLine,$((Get-Content '%~f0') -notmatch '^^@@^|^^:'))) & goto :EXIT
{
# Start PowerShell
param ()
function DD($InputFile, $OutputFile, $BlockSize="", $Skip=0, $Seek=0, $Count=0)
{
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "dd.exe"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.Verb = "runas"
[string] $ddargs = "if=`"$InputFile`" of=`"$OutputFile`""
if ($BlockSize -ne "")
{
$ddargs = $ddargs + " bs=$BlockSize"
}
if ($Skip -gt 0)
{
$ddargs = $ddargs + " skip=$Skip"
}
if ($Seek -gt 0)
{
$ddargs = $ddargs + " seek=$Seek"
}
if ($Count -gt 0)
{
$ddargs = $ddargs + " count=$Count"
}
$ddargs = $ddargs + " --progress"
$ProcessInfo.Arguments = $ddargs
Write-Host "dd.exe" $ProcessInfo.Arguments
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
$Process.WaitForExit()
}
function Get-OpenPath($Title, $FilePath, $Filter)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$FileDialog = New-Object System.Windows.Forms.OpenFileDialog
$FileDialog.Title = $Title
$FileDialog.FileName = Split-Path -Path $FilePath -Leaf
$FileDialog.Filter = $Filter + "|All Files (*.*)|*.*"
$result = $FileDialog.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
return $FileDialog.FileName
}
return ""
}
function Get-SavePath($Title, $FilePath, $Filter)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$FileDialog = New-Object System.Windows.Forms.SaveFileDialog
$FileDialog.Title = $Title
$FileDialog.FileName = Split-Path -Path $FilePath -Leaf
$FileDialog.Filter = $Filter + "|All Files (*.*)|*.*"
$result = $FileDialog.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
return $FileDialog.FileName
}
return ""
}
function Get-FriendlySize([double]$Bytes)
{
switch($Bytes)
{
{$_ -gt 1PB}{"{0:0.##} PB" -f ($_ / 1PB);break}
{$_ -gt 1TB}{"{0:0.##} TB" -f ($_ / 1TB);break}
{$_ -gt 1GB}{"{0:0.##} GB" -f ($_ / 1GB);break}
{$_ -gt 1MB}{"{0:0.##} MB" -f ($_ / 1MB);break}
{$_ -gt 1KB}{"{0:0.##} KB" -f ($_ / 1KB);break}
default {"{0:0.##} Bytes" -f $_}
}
}
[string] $RootPath = Get-Location
[string] $ConfigPath = Join-Path $RootPath "scsi2sd.xml"
if (-not (Test-Path $ConfigPath))
{
$ConfigPath = Get-OpenPath -Title "Select SCSI2SD config file..." -FilePath $ConfigPath -Filter "XML (*.xml)|*.xml"
}
Write-Host "==================="
Write-Host " SCSI2SD Manager"
Write-Host " v1.0"
Write-Host "==================="
Write-Host
Write-Host " Using SCSI2SD configuration at $ConfigPath"
Write-Host
Write-Host " 1: Write SCSI disk(s) to image file(s) (Backup)"
Write-Host " 2: Write image file(s) to SCSI disk(s) (Restore)"
Write-Host
Write-Host " x: Exit"
Write-Host
Write-Host "Make a selection [1]: " -NoNewLine
$option = Read-Host
if ($option -eq "")
{
$option = "1"
}
elseif ($option -eq "x" -or ($option -ne "1" -and $option -ne "2" ))
{
Exit;
}
[string] $DriveLetter = $ConfigPath[0]
[int] $DiskNumber = (Get-Partition -DriveLetter $DriveLetter).DiskNumber
[string] $InputDevice = "\\?\Device\Harddisk$DiskNumber\Partition0"
[xml] $config = Get-Content $ConfigPath
Write-Host "Scanning config file for enabled SCSI disks..."
$config.SCSI2SD.SCSITarget | ForEach-Object {
if ($_.enabled -eq "true") {
[int] $id = $_.id
[int] $sdSectorStart = $_.sdSectorStart
[int] $scsiSectors = $_.scsiSectors
[bigint] $count = (($scsiSectors * 512) / 1024 / 1024)
[string] $friendlySize = Get-FriendlySize -Bytes ($scsiSectors * 512)
Write-Host "SCSI ID #${id} is enabled: ${friendlySize}"
if ($option -eq "1")
{
[bigint] $skip = (($sdSectorStart * 512) / 1024 / 1024)
[string] $outputFile = Get-SavePath -Title "Save SCSI ID #${id} (${friendlySize}) to image..." -FilePath "scsi${id}.img" -Filter "IMG (*.img)|*.img"
if ($outputFile -ne "")
{
Write-Host "Writing SCSI ID #${id} to ${outputFile}..."
DD -InputFile $InputDevice -OutputFile $outputFile -BlockSize "1M" -Skip $skip -Count $count
}
}
else
{
[bigint] $seek = (($sdSectorStart * 512) / 1024 / 1024)
[string] $inputFile = Get-OpenPath -Title "Open image for SCSI ID #${id} (${friendlySize})..." -FilePath "scsi${id}.img" -Filter "IMG (*.img)|*.img"
if ($inputFile -ne "")
{
Write-Host "Restoring SCSI ID #${id} from ${inputFile}..."
DD -InputFile $inputFile -OutputFile $OutputDevice -BlockSize "1M" -Seek $seek -Count $count
}
}
}
}
Write-Host "All enabled disks processed!"
pause
# End PowerShell
}.Invoke($args)
:EXIT
@@popd
@@endlocal
@@exit /b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment