public/Update-OSDeployUSB.ps1
|
function Update-OSDeployUSB { <# .SYNOPSIS Updates an existing OSDeploy USB drive with new BootMedia from an OSDeployCore BootImage build. .DESCRIPTION Refreshes the BootMedia files on one or more existing OSDeploy USB drives. The function: - Prompts for selection of a completed BootImage from %ProgramData%\OSDeployCore\boot-media - Prompts for the specific bootmedia folder (bootmedia or bootmedia_ca2023) - Locates all connected USB volumes whose label matches $BootLabel (default 'USB-WinPE') - Copies the selected media to each matching USB volume using robocopy - Writes a BootMedia.json file to each updated volume No partitioning or formatting is performed. Use New-OSDeployUSB to create a new drive. .PARAMETER BootLabel Volume label used to identify USB boot partitions to update. Maximum 11 characters. Default is 'USB-WinPE'. .EXAMPLE Update-OSDeployUSB Updates all connected USB volumes labeled 'USB-WinPE' with the selected BootImage build. .EXAMPLE Update-OSDeployUSB -BootLabel 'OSDEPLOY' Updates all connected USB volumes labeled 'OSDEPLOY'. .NOTES Author: David Segura Company: Recast Software Version: 0.1.0 Date: April 2026 Prerequisites: - PowerShell 5.0 or higher - Windows 10 or higher - Run as Administrator - At least one completed BootImage build in %ProgramData%\OSDeployCore\boot-media - One or more USB drives previously created with New-OSDeployUSB .LINK https://github.com/OSDeploy/OSDeploy #> [CmdletBinding()] param ( # Label used to identify USB boot partitions. Default is 'USB-WinPE'. [ValidateLength(0, 11)] [string] $BootLabel = 'USB-WinPE' ) #================================================= Write-OSDeployBanner $Error.Clear() Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" #================================================= # Requires Run as Administrator $IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $IsAdmin) { Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] This function must be Run as Administrator" return } #================================================= # Set Variables $ErrorActionPreference = 'Stop' #================================================= # Block Block-StandardUser Block-WindowsVersionNe10 Block-PowerShellVersionLt5 Block-WindowsReleaseIdLt1703 #================================================= # Select a BootImage build $SelectBootImage = Select-OSDeployCoreBootImage if ($null -eq $SelectBootImage) { Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] No OSDeployCore BootImage build was found or selected" return } Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Selected BootImage: $($SelectBootImage.Name)" Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] BootImage path: $($SelectBootImage.Path)" #================================================= # Select a bootmedia folder Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Select a bootmedia folder to copy to the USB (Cancel to exit)" $BootMediaObject = Get-ChildItem $SelectBootImage.Path -Directory | Where-Object { ($_.Name -eq 'bootmedia') -or ($_.Name -eq 'bootmedia-ca2023') } | Sort-Object Name, FullName | Select-Object Name, FullName | Out-GridView -Title 'Select a bootmedia folder to copy to the USB (Cancel to exit)' -OutputMode Single if ($null -eq $BootMediaObject) { Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] No bootmedia folder was found or selected" return } #================================================= # Disable Autorun Set-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer' -Name NoDriveTypeAutorun -Type DWord -Value 0xFF -ErrorAction SilentlyContinue #================================================= # Update matching USB volumes if (Test-Path -Path $BootMediaObject.FullName) { $WinpeVolumes = Get-USBVolume | Where-Object { $_.FileSystemLabel -eq $BootLabel } if ($WinpeVolumes) { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Copying $($BootMediaObject.FullName) to $BootLabel partitions" foreach ($volume in $WinpeVolumes) { if (Test-Path -Path "$($volume.DriveLetter):\") { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Updating $($volume.DriveLetter):\" robocopy.exe "$($BootMediaObject.FullName)" "$($volume.DriveLetter):\" *.* /e /ndl /r:0 /w:0 /xd '$RECYCLE.BIN' 'System Volume Information' /xj $SelectBootImage | ConvertTo-Json -Depth 5 | Out-File -FilePath "$($volume.DriveLetter):\BootMedia.json" -Force } } } else { Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] No USB partitions labeled '$BootLabel' were found" } } else { Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] BootMedia path not found: $($BootMediaObject.FullName)" } #================================================= Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" #================================================= } |