private/disk/disk-core.ps1
|
function Get-FirstAvailableDriveLetter { param() $GetVolume = Get-Volume # Get all available drive letters, and store in a temporary variable. $UsedDriveLetters = @($GetVolume | % { "$([char]$_.DriveLetter)"}) + @(Get-WmiObject -Class Win32_MappedLogicalDisk | %{$([char]$_.DeviceID.Trim(':'))}) $TempDriveLetters = @(Compare-Object -DifferenceObject $UsedDriveLetters -ReferenceObject $( 67..90 | % { "$([char]$_)" } ) | ? { $_.SideIndicator -eq '<=' } | % { $_.InputObject }) # For completeness, sort the output alphabetically $AvailableDriveLetter = ($TempDriveLetters | Sort-Object) $AvailableDriveLetter[0] } function Get-LastAvailableDriveLetter { param() $GetVolume = Get-Volume # Get all available drive letters, and store in a temporary variable. $UsedDriveLetters = @($GetVolume | % { "$([char]$_.DriveLetter)"}) + @(Get-WmiObject -Class Win32_MappedLogicalDisk | %{$([char]$_.DeviceID.Trim(':'))}) $TempDriveLetters = @(Compare-Object -DifferenceObject $UsedDriveLetters -ReferenceObject $( 67..90 | % { "$([char]$_)" } ) | ? { $_.SideIndicator -eq '<=' } | % { $_.InputObject }) # For completeness, sort the output alphabetically $AvailableDriveLetter = ($TempDriveLetters | Sort-Object -Descending) $AvailableDriveLetter[0] } function Invoke-DiskpartClean { <# .SYNOPSIS Cleans a disk by using DiskPart in WinPE. .DESCRIPTION Selects the specified disk and runs DiskPart clean from WinPE. This helper is intended for deployment scenarios where Clear-Disk can be unreliable, especially in virtual machines. It writes the exact DiskPart commands to verbose output and exits without action when the system is not running from X:. .PARAMETER DiskNumber Disk number to select and clean with DiskPart. .EXAMPLE Invoke-DiskpartClean -DiskNumber 0 Cleans disk 0 when running in WinPE. .EXAMPLE Invoke-DiskpartClean -DiskNumber 1 -Verbose Displays the DiskPart commands that will be run, then cleans disk 1 when running in WinPE. .LINK https://github.com/OSDeploy/OSD/tree/master/docs .NOTES Author: David Segura - Recast Software 2026-07-21 - Refreshed help and verbose tracing for DiskPart clean #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$DiskNumber ) Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Starting disk clean workflow for disk $DiskNumber" #Virtual Machines have issues using PowerShell for Clear-Disk #$OSDDisk | Clear-Disk -RemoveOEM -RemoveData -Confirm:$true -PassThru -ErrorAction SilentlyContinue | Out-Null Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> select disk $DiskNumber" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> clean" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> exit" #Abort if not in WinPE if ($env:SystemDrive -ne "X:") { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Skipping disk clean because the system drive is not X:" return } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Invoking DiskPart clean on disk $DiskNumber" $null = @" select disk $DiskNumber clean exit "@ | diskpart.exe } function Invoke-DiskpartFormatSystemPartition { <# .SYNOPSIS Formats a system partition by using DiskPart in WinPE. .DESCRIPTION Selects the requested disk and partition, then quick-formats it with DiskPart. This helper is intended for WinPE deployment scenarios and exits without action when the system is not running from X:. The function writes the exact DiskPart commands to verbose output before running them. .PARAMETER DiskNumber DiskPart disk number that contains the system partition to format. .PARAMETER PartitionNumber DiskPart partition number to format on the selected disk. .PARAMETER FileSystem File system to apply to the selected partition. .PARAMETER LabelSystem Volume label to assign during the DiskPart format operation. .EXAMPLE Invoke-DiskpartFormatSystemPartition -DiskNumber 0 -PartitionNumber 1 -FileSystem FAT32 -LabelSystem System Formats partition 1 on disk 0 as FAT32 with the label System when running in WinPE. .EXAMPLE Invoke-DiskpartFormatSystemPartition -DiskNumber 0 -PartitionNumber 2 -FileSystem NTFS -LabelSystem Windows -Verbose Displays the DiskPart commands that will be run, then formats partition 2 on disk 0 as NTFS with the label Windows when running in WinPE. .LINK https://github.com/OSDeploy/OSD/tree/master/docs .NOTES Author: David Segura - Recast Software 2026-07-21 - Refreshed help and verbose tracing for DiskPart format #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$DiskNumber, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$PartitionNumber, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$FileSystem, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$LabelSystem ) #Write-Warning "Format-Volume FileSystem NTFS NewFileSystemLabel $Label" #Format-Volume -ObjectId $PartitionSystem.ObjectId -FileSystem NTFS -NewFileSystemLabel "$Label" -Force -Confirm:$false Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Starting system partition format workflow for disk $DiskNumber partition $PartitionNumber" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> select disk $DiskNumber" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> select partition $PartitionNumber" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> format fs=$FileSystem quick label='$LabelSystem'" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DISKPART> exit" #Abort if not in WinPE if ($env:SystemDrive -ne "X:") { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Skipping system partition format because the system drive is not X:" return } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Invoking DiskPart format on disk $DiskNumber partition $PartitionNumber" $null = @" select disk $DiskNumber select partition $PartitionNumber format fs=$FileSystem quick label="$LabelSystem" exit "@ | diskpart.exe } |