2016-01: Retroactive Updates

This commit is contained in:
Alan Mason 2017-11-24 20:50:41 -08:00
parent c7b5abb0bc
commit 41272c03ab
6 changed files with 263 additions and 111 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2015 Alan Mason
Copyright (c) 2016 Alan Mason
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -3,7 +3,7 @@
:Init
setlocal EnableDelayedExpansion
title Menu Launcher
color 0a
color 0b
pushd %~dp0
:Flags
@ -30,5 +30,7 @@ echo.
rem echo Press any key to exit...
rem pause>nul
popd
color
endlocal
endlocal
cls
echo Careful now...
echo.

View file

@ -1,5 +1,6 @@
@echo off
color 0b
echo Initializing...
wpeinit
wpeutil updatebootinfo

View file

@ -7,7 +7,7 @@ pushd "$wd"
clear
$host.UI.RawUI.WindowTitle = "WK PE Tool"
$logpath = "$WKPath\Info\$date"
md "$logpath" 2>&1 | out-null
md "$logpath" 2>&1 | Out-Null
$log = "$logpath\winpe.log"
$source_server = "10.0.0.10"
$backup_servers = @(
@ -20,23 +20,23 @@ $backup_servers = @(
"letter"="Y";
"path"="Backups"}
)
$backup_user = "WORKGROUP\backup"
$backup_user = "backup"
$backup_pass = "Abracadabra"
# Functions
function apply-image {
param([string]$image, [int]$index)
Param([string]$image, [int]$index)
$path = ""
$split_image = $false
$split_image_pattern = ""
# Check for local source
$volumes = get-volume | where {$_.Size -ne 0 -and $_.DriveLetter -match '^[C-Z]$'}
$volumes = Get-Volume | Where-Object {$_.Size -ne 0 -and $_.DriveLetter -match '^[C-Z]$'}
foreach ($v in $volumes) {
$letter = $v.DriveLetter + ":"
if (test-path "$letter\sources\$image.wim") {
if (Test-Path "$letter\sources\$image.wim") {
$path = "$letter\sources\$image.wim"
} elseif (test-path "$letter\sources\$image.swm") {
} elseif (Test-Path "$letter\sources\$image.swm") {
$path = "$letter\sources\$image.swm"
$split_image = $true
$split_image_pattern = "$letter\sources\$image*.swm"
@ -46,9 +46,9 @@ function apply-image {
# Check for remote source (if necessary)
if ($path -match '^$') {
net use z: "\\$source_server\Windows" /user:guest notarealpassword
if (test-path "Z:\$image.wim") {
if (Test-Path "Z:\$image.wim") {
$path = "Z:\$image.wim"
} elseif (test-path "Z:\$image.swm") {
} elseif (Test-Path "Z:\$image.swm") {
$path = "Z:\$image.swm"
}
}
@ -65,7 +65,7 @@ function apply-image {
net use z: /delete
}
function format-gpt {
param($dest_disk)
Param($dest_disk)
wk-write "Drive will use a GPT (UEFI) layout."
# Double-check we have the right drive
@ -77,9 +77,9 @@ function format-gpt {
}
$diskpart_script = "select disk {0}`r`n" -f $dest_disk.DiskNumber
$diskpart_script += "uniqueid disk"
out-file -encoding 'UTF8' -filepath "$wd\diskpart.script" -inputobject $diskpart_script
start "diskpart" -argumentlist @("/s", "$wd\diskpart.script") -wait -nonewwindow -PassThru -RedirectStandardOutput "$wd\drive_uid" | out-null
if (!(Get-Content "$wd\drive_uid" | where {$_ -imatch $_sel_uid})) {
Out-File -encoding 'UTF8' -filepath "$wd\diskpart.script" -inputobject $diskpart_script
Start-Process "diskpart" -argumentlist @("/s", "$wd\diskpart.script") -wait -nonewwindow -PassThru -RedirectStandardOutput "$wd\drive_uid" | Out-Null
if (!(Get-Content "$wd\drive_uid" | Where-Object {$_ -imatch $_sel_uid})) {
# GUIDs do not match
wk-error "Diskpart failed to select the same disk for formatting, aborting setup."
wk-warn "This system requires manual formatting & setup"
@ -122,16 +122,16 @@ function format-gpt {
$diskpart_script += "assign letter='W'`r`n"
# Run script
out-file -encoding 'UTF8' -filepath "$wd\diskpart.script" -inputobject $diskpart_script
start "diskpart" -argumentlist @("/s", "$wd\diskpart.script") -wait -nonewwindow
Out-File -encoding 'UTF8' -filepath "$wd\diskpart.script" -inputobject $diskpart_script
Start-Process "diskpart" -argumentlist @("/s", "$wd\diskpart.script") -wait -nonewwindow
}
function format-mbr {
param($dest_disk)
Param($dest_disk)
wk-write "Drive will use a MBR (legacy) layout."
if ($dest_disk.PartitionStyle -notmatch '^RAW$') {
# Only clean if necessary
clear-Disk $dest_disk.DiskNumber -RemoveData -RemoveOEM -Confirm:$false
Clear-Disk $dest_disk.DiskNumber -RemoveData -RemoveOEM -Confirm:$false
}
Initialize-Disk $dest_disk.DiskNumber -PartitionStyle 'MBR'
New-Partition -DiskNumber $dest_disk.DiskNumber -Size 100Mb -DriveLetter 'S' -IsActive:$true
@ -139,6 +139,120 @@ function format-mbr {
Format-Volume -DriveLetter 'S' -FileSystem 'NTFS' -NewFileSystemLabel 'System Reserved'
Format-Volume -DriveLetter 'W' -FileSystem 'NTFS' -NewFileSystemLabel 'Windows'
}
function select-disk {
$_skipped_parts = 0
# Check if any source drives were detected
$disks = Get-Disk | Where-Object {$_.Size -ne 0} | Sort-Object -Property "Number"
if ($disks.count -eq 0) {
wk-error "No suitable source drives were detected."
return $false
} elseif ($disks.count -eq $null) {
# Assuming only one disk is available
$answer = $disks.DiskNumber
} else {
# Build source menu
$menu_imaging_source = "For which drive are we creating backup image(s)?`r`n`r`n"
$valid_answers = @("M", "m")
foreach ($_ in $disks) {
$valid_answers += $_.DiskNumber
$menu_imaging_source += "{0}: {1,4:N0} Gb`t[{2}] ({3}) {4}`r`n" -f $_.DiskNumber, ($_.Size / 1GB), $_.PartitionStyle, $_.BusType, $_.FriendlyName
}
$menu_imaging_source += "`r`n"
$menu_imaging_source += "M: Main Menu`r`n"
$menu_imaging_source += "`r`n"
$menu_imaging_source += "Please make a selection`r`n"
# Select source
do {
clear
$answer = read-host -prompt $menu_imaging_source
} until ($valid_answers -contains $answer)
}
if ($answer -imatch '^\d+$') {
# Valid disk selected
clear
$_d = Get-Disk -number $answer
$_disk_details = "Disk:`t{0,4:N0} Gb`t[{1}] ({2}) {3}" -f ($_d.Size / 1GB), $_d.PartitionStyle, $_d.BusType, $_d.FriendlyName
wk-write "$_disk_details"
wk-write "Partition(s):"
# Print partition info
$partitions = Get-Partition -DiskNumber $_d.DiskNumber
foreach ($_p in $partitions) {
# Assign letter
Add-PartitionAccessPath -DiskNumber $_d.DiskNumber -PartitionNumber $_p.PartitionNumber -AssignDriveLetter 2>&1 | Out-Null
# Update partition info
$_p = Get-Partition -DiskNumber $_d.DiskNumber -PartitionNumber $_p.PartitionNumber
$_v = Get-Volume -Partition $_p
# Set size label
$_size = (human-size $_p.size 0)
if ($_v -ne $null) {
$_used = (human-size ($_v.Size - $_v.SizeRemaining) 0)
}
# Print partition info
if ($_p.AccessPaths -eq $null) {
# No drive letter
$_msg = " *{0:N0}:`t ({1}) {2}" -f $_p.PartitionNumber, $_size, $_p.Type
wk-error "$_msg"
$_skipped_parts += 1
} else {
# Has drive letter
$_path = $_p.AccessPaths | Where-Object {$_ -imatch '^\w:\\$'}
$_label = " {0}" -f $_p.Type
if ($_v -and $_v.FileSystemLabel -ne "") {
$_label = '"{0}"' -f $_v.FileSystemLabel
}
$_msg = " {0:N0}:`t{1} ({2,6}) {3} ({4} used)" -f $_p.PartitionNumber, $_path, $_size, $_label, $_used
wk-write "$_msg"
}
}
if ($_skipped_parts -gt 0) {
wk-warn " *`tUnable to backup these partition(s)"
}
wk-write ""
if (ask " Backup these partition(s)?") {
return $_d
} else {
return $false
}
}
return $answer
}
function select-server {
# Build server menu
$avail_servers = @(gdr | Where-Object {$_.DisplayRoot -imatch '\\\\'})
if ($avail_servers.count -eq 0) {
wk-error "No suitable backup servers were detected."
return $false
}
$menu_imaging_server = "Where are we saving the backup image(s)?`r`n`r`n"
$valid_answers = @("M", "m")
for ($i=0; $i -lt $avail_servers.length; $i++) {
$valid_answers += ($i + 1)
$menu_imaging_server += ("{0}: {1} ({2:N2} Gb free)`r`n" -f ($i + 1), $avail_servers[$i].Description, ($avail_servers[$i].Free / 1Gb))
}
$menu_imaging_server += "`r`n"
$menu_imaging_server += "M: Main Menu`r`n"
$menu_imaging_server += "`r`n"
$menu_imaging_server += "Please make a selection`r`n"
# Select server
do {
# clear
$answer = read-host -prompt $menu_imaging_server
} until ($valid_answers -contains $answer)
if ($answer -imatch '^\d+$') {
$answer -= 1
return $avail_servers[$answer]
}
return $answer
}
function wk-exit {
popd
if ($answer -match 'R') {
@ -154,35 +268,37 @@ function mount-servers {
# Mount servers
wk-write "Connecting to backup server(s)"
foreach ($_server in $backup_servers) {
if (test-connection $_server.ip -count 1 -quiet 2>&1 | out-null) {
if (test-connection $_server.ip -count 3 -quiet) {
try {
$_path = "\\{0}\{1}" -f $_server.ip, $_server.path
$_drive = "{0}:" -f $_server.letter
net use $_drive "$_path" /user:$backup_user $backup_pass | out-null
net use $_drive "$_path" /user:$backup_user $backup_pass | Out-Null
wk-write ("`t{0} server: mounted" -f $_server.name)
# Add friendly description
$_regex = "^{0}$" -f $_server.letter
(gdr | where {$_.Name -imatch $_regex}).Description = $_server.name
(gdr | Where-Object {$_.Name -imatch $_regex}).Description = $_server.name
} catch {
wk-warn ("`t{0} server: failed" -f $_server.name)
}
} else {
wk-warn ("`t{0} server: unreachable" -f $_server.name)
wk-warn ("`t{0} server: timed-out" -f $_server.name)
}
}
}
function unmount-servers {
# Unmount servers
wk-write "Disconnecting from backup server(s)"
$mounted_servers = @(gdr | where {$_.DisplayRoot -imatch '\\\\'})
$mounted_servers = @(gdr | Where-Object {$_.DisplayRoot -imatch '\\\\'})
foreach ($_server in $mounted_servers) {
try {
$_drive = "{0}:" -f $_server.Name
net use $_drive /delete | out-null
wk-warn ("`t{0} server: unmounted" -f $_server.name)
net use $_drive /delete | Out-Null
#wk-warn ("`t{0} server: unmounted" -f $_server.name)
wk-warn "`tServer: unmounted"
} catch {
wk-warn ("`t{0} server: failed" -f $_server.name)
#wk-warn ("`t{0} server: failed" -f $_server.name)
wk-warn "`tServer: failed"
}
}
}
@ -194,86 +310,92 @@ function menu-imaging {
wk-warn "WARNING: This section is experimental"
pause
## WARNING
# Check if any source drives were detected
$disks = get-disk | where {$_.Size -ne 0}
# if ($disks.count -eq 0) {
# wk-error "No suitable source drives were detected."
# pause "Press Enter to return to main menu... " $True
# return 1
# }
# Service Order
$menu_service_order += "Please enter the service order`r`n"
do {
clear
$service_order = read-host -prompt $menu_service_order
} until ($service_order -imatch '^\d[\w\-]+$')
# Select Disk
$disk = select-disk
if (!($disk)) {
# No drives detected or user aborted
wk-warn "Drive Imaging aborted."
wk-write ""
pause "Press Enter to return to main menu... "
return $false
} elseif ($disk -imatch '^M$') {
# User selected to return to the menu
return
}
wk-write ""
# Mount server(s)
mount-servers
# Build server menu
$avail_servers = @(gdr | where {$_.DisplayRoot -imatch '\\\\'})
# if ($avail_servers.count -eq 0) {
# wk-error "No suitable backup servers were detected."
# pause "Press Enter to return to main menu... " $True
# return 1
# }
$menu_imaging_server = "Where are we saving the backup image(s)?`r`n`r`n"
$valid_answers = @("M", "m")
for ($i=0; $i -lt $avail_servers.length; $i++) {
$valid_answers += ($i + 1)
$menu_imaging_server += ("{0}: {1} ({2:N2} Gb free)`r`n" -f ($i + 1), $avail_servers[$i].Description, ($avail_servers[$i].Free / 1Gb))
}
$menu_imaging_server += "`r`n"
$menu_imaging_server += "M: Main Menu`r`n"
$menu_imaging_server += "`r`n"
$menu_imaging_server += "Please make a selection`r`n"
# Select server
do {
##testing## clear
$answer = read-host -prompt $menu_imaging_server
} until ($valid_answers -contains $answer)
if ($answer -imatch '^M$') {
# Exit if requested
unmount-servers
# Select Server
$server = select-server
if (!($server)) {
# No servers detected
wk-warn "Drive Imaging aborted."
wk-write ""
pause "Press Enter to return to main menu... "
return $false
} elseif ($server -imatch '^M$') {
# User selected to return to the menu
return
} else {
$answer -= 1
$dest_backup_server = $avail_servers[$answer]
}
# Build source menu
$menu_imaging_source = "For which drive are we creating backup image(s)?`r`n`r`n"
$valid_answers = @("M", "m")
foreach ($_ in $disks) {
$valid_answers += $_.DiskNumber
$menu_imaging_source += "{0}: {1:N0} Gb`t({2}) {3} ({4})`r`n" -f $_.DiskNumber, ($_.Size / 1GB), $_.BusType, $_.FriendlyName, $_.PartitionStyle
}
$menu_imaging_source += "`r`n"
$menu_imaging_source += "M: Main Menu`r`n"
$menu_imaging_source += "`r`n"
$menu_imaging_source += "Please make a selection`r`n"
# Select source
do {
##testing## clear
$answer = read-host -prompt $menu_imaging_source
} until ($valid_answers -contains $answer)
if ($answer -imatch '^M$') {
# Exit if requested
return
} else {
##TODO##
get-volume
}
# Service Order
$menu_service_order += "Please enter the service order`r`n"
do {
##testing## clear
$service_order = read-host -prompt $menu_service_order
} until ($service_order -imatch '^\d[\w\-]+$')
wk-write ""
wk-write ("Saving partition backups to: {0}" -f $server.Description)
wk-write ""
# Backup partitions
wk-write ("Saving partition backups to: {0}" -f $dest_backup_server.Description)
wk-write ("`t{0}{1}" -f $dest_backup_server.Root, $service_order)
$partitions = Get-Partition -DiskNumber $disk.DiskNumber
foreach ($_p in $partitions) {
$_v = Get-Volume -Partition $_p
$_name = "{0}" -f $_p.PartitionNumber
if ($_v -and $_v.FileSystemLabel -ne "") {
$_name += "_{0}" -f $_v.FileSystemLabel
} else {
$_name += "_{0}" -f $_p.Type
}
$_imagepath = "{0}{1}" -f $server.Root, $service_order
$_imagefile = "{0}{1}\{2}.wim" -f $server.Root, $service_order, $_name
if ($_p.AccessPaths -ne $null) {
$_capturepath = $_p.AccessPaths | Where-Object {$_ -imatch '^\w:\\$'}
# Take image
wk-write (" Imaging partition {0} --> `"{1}`"" -f $_p.PartitionNumber, $_imagefile)
if (!(Test-Path "$_imagepath")) {
mkdir "$_imagepath" | out-null
}
New-WindowsImage -ImagePath "$_imagefile" -CapturePath "$_capturepath" -Name "$_name" -CompressionType "fast" | out-null
# Verify image
## Code borrowed from: https://stackoverflow/a/10262275
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "$WKPath\7z.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = 't "{0}"' -f $_imagefile
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
write-host " Verifying . . . " -NoNewline
$p.WaitForExit()
if ($p.ExitCode -eq 0) {
write-host "Complete." -foreground "green"
} else {
write-host "Failed." -foreground "red"
}
}
}
# Unmount server(s)
unmount-servers
@ -284,11 +406,11 @@ function menu-setup {
wk-write ""
# Check if any destination drives were detected
$disks = get-disk | where {$_.Size -ne 0 -and $_.BusType -inotmatch 'USB'}
$disks = Get-Disk | Where-Object {$_.Size -ne 0 -and $_.BusType -inotmatch 'USB'}
if ($disks.count -eq 0) {
wk-error "No suitable destination drives were detected."
pause "Press Enter to return to main menu... " $True
return 1
return $false
}
# Build windows menu
@ -314,7 +436,7 @@ function menu-setup {
# Select Windows version
do {
##testing## clear
clear
$answer = read-host -prompt $menu_setup_windows
} until ($valid_answers -contains $answer)
@ -340,7 +462,7 @@ function menu-setup {
# Select disk
do {
##testing## clear
clear
$answer = read-host -prompt $menu_setup_disk
} until ($valid_answers -contains $answer)
@ -349,7 +471,7 @@ function menu-setup {
return
} else {
# Double check before deleting data
$dest_disk = $disks | where {$_.DiskNumber -eq $answer}
$dest_disk = $disks | Where-Object {$_.DiskNumber -eq $answer}
wk-warn "All data will be deleted from the following drive:"
wk-warn ("`t{0:N0} Gb`t({1}) {2}`r`n" -f ($dest_disk.Size / 1GB), $dest_disk.PartitionStyle, $dest_disk.FriendlyName)
if (ask ("Proceed and install {0}?" -f $dest_windows_version.Name)) {
@ -396,7 +518,7 @@ function menu-setup {
wk-error "Windows Setup aborted."
wk-write ""
pause "Press Enter to return to main menu... "
return 1
return $false
}
} else {
wk-error "Windows Setup aborted."
@ -414,7 +536,7 @@ function menu-tools {
wk-write "Misc Tools"
wk-write ""
wk-warn "Be careful."
start "$WKPath\explorer++" -argumentlist @("$WKPath")
Start-Process "$WKPath\explorer++" -argumentlist @("$WKPath")
wk-exit
}
function menu-main {
@ -434,10 +556,10 @@ Please make a selection
"@
do {
##testing## clear
clear
$answer = read-host -prompt $menu_main
} until ($answer -imatch '^[123QRS]$')
##testing## clear
clear
if ($answer.GetType().Name -match "String") {
$answer = $answer.ToUpper()

View file

@ -41,6 +41,21 @@ function wk-write {
write-host ($text)
out-file -filepath $log -inputobject $text -append
}
function human-size {
param($bytes, [int]$decimals = 2)
if ($bytes -gt 1Tb) {
$size = "{0:N$decimals} Tb" -f ($bytes / 1Tb)
} elseif ($bytes -gt 1Gb) {
$size = "{0:N$decimals} Gb" -f ($bytes / 1Gb)
} elseif ($bytes -gt 1Mb) {
$size = "{0:N$decimals} Mb" -f ($bytes / 1Mb)
} elseif ($bytes -gt 1Kb) {
$size = "{0:N$decimals} Kb" -f ($bytes / 1Kb)
} else {
$size = "{0:N$decimals} b" -f $bytes
}
return $size
}
function pause {
param([string]$message = "Press Enter to continue... ", [bool]$warning = $False)
if ($warning) {

View file

@ -50,6 +50,14 @@ dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\en-us\WinPE-Dism
:: Install WinPE-WMI > WinPE-NetFX > WinPE-Scripting > WinPE-PowerShell before you install WinPE-SecureBootCmdlets.
dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\WinPE-SecureBootCmdlets.cab" /logpath:"dism.log"
:: Install WinPE-WMI > WinPE-NetFX > WinPE-Scripting > WinPE-PowerShell before you install WinPE-StorageWMI.
dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\WinPE-StorageWMI.cab" /logpath:"dism.log"
dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\en-us\WinPE-StorageWMI_en-us.cab" /logpath:"dism.log"
:: Install ?? before you install WinPE-EnhancedStorage.
dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\WinPE-EnhancedStorage.cab" /logpath:"dism.log"
dism /add-package /image:"%wd%\mount" /packagepath:"%winpe_ocs%\en-us\WinPE-EnhancedStorage_en-us.cab" /logpath:"dism.log"
:Robocopy
del "%wd%\WK\Scripts\WK.log"
mkdir "%wd%\mount\WK"
@ -78,12 +86,16 @@ echo.
echo Press any key to commit changes...
pause>nul
:Set-ScratchSpace
rem Force RamDisk size to try and avoid capture-image errors
dism /image:"%wd%\mount" /set-scratchspace:512
:Unmount
dism /unmount-image /mountdir:"%wd%\mount" /commit
:CreateISO
del winpe10-test.iso
makewinpemedia.cmd /iso "%wd%\pe_files" winpe10-test.iso
del winpe10-2016.iso
makewinpemedia.cmd /iso "%wd%\pe_files" winpe10-2016.iso
goto Done
:Abort