Skip to content

Commit 5f47158

Browse files
author
David Jones
committed
New parameter to fix CS issue
1 parent 8395c21 commit 5f47158

13 files changed

Lines changed: 440 additions & 13 deletions

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"cref",
1313
"dacl",
1414
"disall",
15+
"diskpart",
1516
"DISM",
1617
"DISPLAYDESCRIPTION",
1718
"DISPLAYNAME",

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
9+
## [1.10.35] Released
10+
11+
### Fixed
12+
added -UseDismExpansion parmater to mutiple funtion as a workarround for CroudStrike not likeing Expand-WindowsImage.
13+
14+
### Added
15+
Get-WindowsImageFromIso this will list the windows image numbers and names on an iso. Same as Get-WindowsImage
16+
817
## [1.9.30] Released
918

1019
### Fixed

WindowsImageTools/Private/Initialize-VHDPartition.ps1

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,17 @@
142142
Try {
143143
Add-WindowsImageType
144144
$vhdParams = @{
145-
VHDFormat = $VHDFormat
146-
Path = $Path
147-
SizeBytes = $Size
145+
Path = $Path
146+
Size = $Size
147+
Dynamic = $Dynamic
148+
Force = $force
148149
}
149-
150+
If (-not $Dynamic) {
151+
Write-Warning -Message 'Creating a Fixed Disk May take a long time!'
152+
}
153+
Write-Verbose -Message "[$($MyInvocation.MyCommand)] [$fileName] : Params for New-DpVhd"
154+
Write-Verbose -Message ($vhdParams | Out-String)
155+
#New-DpVhd @vhdParams
150156
If ($Dynamic) {
151157
Write-Verbose -Message "[$($MyInvocation.MyCommand)] [$fileName] : Params for [WIM2VHD.VirtualHardDisk]::CreateSparseDisk()"
152158
Write-Verbose -Message ($vhdParams | Out-String)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
function New-DpVhd {
2+
<#
3+
.SYNOPSIS
4+
Creates a new VHD or VHDX file using diskpart.
5+
6+
.DESCRIPTION
7+
Uses diskpart to create a new VHD or VHDX file at the specified path and size. If the file exists, -Force is required to overwrite it. Ensures the path is a file, not a folder.
8+
9+
.PARAMETER Path
10+
The path to the new VHD or VHDX file. Must end in .vhd or .vhdx.
11+
12+
.PARAMETER Size
13+
The size of the VHD(X) in MB, GB, or TB (e.g., 40GB).
14+
15+
.PARAMETER Force
16+
If specified, overwrites the existing file at the path.
17+
18+
.EXAMPLE
19+
New-DpVhd -Path 'C:\disks\disk1.vhdx' -Size 40GB -Force
20+
21+
.NOTES
22+
Author: WindowsImageTools Team
23+
Requires: Administrator privileges
24+
#>
25+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
26+
param (
27+
[Parameter(Mandatory, Position = 0, HelpMessage = 'Path to the new VHD/VHDX file')]
28+
[ValidateNotNullOrEmpty()]
29+
[ValidatePattern("\.vhdx?$")]
30+
[string]$Path,
31+
32+
[Parameter(Mandatory, Position = 1, HelpMessage = 'Size of the VHD/VHDX in bytes (e.g., 40GB, 128849018880)')]
33+
[ValidateNotNullOrEmpty()]
34+
[double]$Size,
35+
36+
[switch]$Force,
37+
38+
# If specified, creates a dynamic (expandable) VHD(X). Otherwise, creates a fixed VHD(X).
39+
[switch]$Dynamic
40+
)
41+
42+
# Make path absolute
43+
$Path = Get-FullFilePath -Path $Path
44+
45+
# Ensure path is not a folder
46+
if (Test-Path $Path -PathType Container) {
47+
throw "The specified path '$Path' is a directory. Please specify a file path ending in .vhd or .vhdx."
48+
}
49+
50+
# If file exists, require -Force or confirmation
51+
if (Test-Path $Path -PathType Leaf) {
52+
$shouldDelete = $false
53+
if ($Force) {
54+
$shouldDelete = $PSCmdlet.ShouldProcess($Path, 'Remove existing file')
55+
} else {
56+
$shouldDelete = $PSCmdlet.ShouldProcess($Path, 'Remove existing file') -and $PSCmdlet.ShouldContinue("The file '$Path' already exists. Do you want to overwrite it?", 'Confirm Overwrite')
57+
}
58+
if ($shouldDelete) {
59+
Remove-Item -Path $Path -Force
60+
} else {
61+
throw "The file '$Path' already exists. Use -Force to overwrite or confirm the action."
62+
}
63+
}
64+
65+
# Calculate maximum size in MB for diskpart
66+
$maxMB = [long]($Size / 1MB)
67+
68+
$type = if ($Dynamic) { 'expandable' } else { 'fixed' }
69+
$diskpartScript = @"
70+
create vdisk file="$Path" maximum=$maxMB type=$type
71+
"@
72+
$scriptFile = [System.IO.Path]::GetTempFileName()
73+
Set-Content -Path $scriptFile -Value $diskpartScript -Encoding ASCII
74+
75+
try {
76+
Write-Verbose "Running diskpart to create VHD: $Path"
77+
$output = diskpart /s $scriptFile 2>&1
78+
if ($LASTEXITCODE -ne 0 -or ($output -join "`n") -match 'error') {
79+
throw "diskpart failed: $($output -join "`n")"
80+
}
81+
} finally {
82+
Remove-Item -Path $scriptFile -ErrorAction SilentlyContinue
83+
}
84+
}
85+

WindowsImageTools/Private/Set-DiskPartition.ps1

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,11 @@
110110
[string[]]$filesToInject,
111111

112112
# Bypass the warning and about lost data
113-
[switch]$Force
113+
[switch]$Force,
114+
115+
# Use DISM for image expansion instead of Expand-WindowsImage
116+
[Parameter(HelpMessage = 'If true, use Expand-DpWindowsImage for image expansion. If false, use Expand-WindowsImage.')]
117+
[switch]$UseDismExpansion = $false
114118
)
115119

116120

@@ -216,7 +220,11 @@
216220
$WinDrive = Join-Path -Path "$($WindowsPartition.DriveLetter):" -ChildPath '\'
217221
$windir = Join-Path -Path $WinDrive -ChildPath Windows
218222
Write-Verbose -Message "[$($MyInvocation.MyCommand)] [$DiskNumber] Windows Partition [$($WindowsPartition.partitionNumber)] : Applying image from [$SourcePath] to [$WinDrive] using Index [$Index]"
219-
$null = Expand-WindowsImage -ImagePath $SourcePath -Index $Index -ApplyPath $WinDrive -ErrorAction Stop
223+
if ($UseDismExpansion) {
224+
$null = Expand-DpWindowsImage -ImagePath $SourcePath -Index $Index -ApplyPath $WinDrive -ErrorAction Stop
225+
} else {
226+
$null = Expand-WindowsImage -ImagePath $SourcePath -Index $Index -ApplyPath $WinDrive -ErrorAction Stop
227+
}
220228

221229
#region Modify the OS with Drivers, Active Features and Packages
222230
if ($Driver) {

WindowsImageTools/Private/Set-VHDPartition.ps1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@
105105
[string[]]$filesToInject,
106106

107107
# Bypass the warning and about lost data
108-
[switch]$Force
108+
[switch]$Force,
109+
110+
# Use DISM for expansion instead of native PowerShell
111+
[Parameter(HelpMessage = 'Use DISM for expansion instead of native PowerShell')]
112+
[switch]$UseDismExpansion = $false
109113
)
110114

111115

@@ -141,6 +145,7 @@
141145
try {
142146
Write-Verbose -Message "[$($MyInvocation.MyCommand)] [$VhdxFileName] : Mounted as diskNumber [$($disk.Number)]"
143147

148+
144149
$SetDiskParam = @{
145150
DiskNumber = $disk.Number
146151
SourcePath = $SourcePath
@@ -157,6 +162,7 @@
157162
if ($Driver) { $SetDiskParam.add('Driver', $Driver) }
158163
if ($Package) { $SetDiskParam.add('Package', $Package) }
159164
if ($filesToInject) { $SetDiskParam.add('filesToInject', $filesToInject) }
165+
if ($PSBoundParameters.ContainsKey('UseDismExpansion')) { $SetDiskParam.add('UseDismExpansion', $UseDismExpansion) }
160166

161167
Set-DiskPartition @ParametersToPass @SetDiskParam
162168

WindowsImageTools/Public/Convert-Wim2VHD.ps1

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@
6767
.PARAMETER Package
6868
Paths to packages to install via DISM.
6969
70+
7071
.PARAMETER filesToInject
7172
Files or folders to copy to the root of the Windows drive.
7273
74+
.PARAMETER UseDismExpansion
75+
If specified, uses DISM.exe for image expansion instead of native PowerShell.
76+
7377
.EXAMPLE
7478
Convert-Wim2VHD -Path c:\windows8.vhdx -SourcePath d:\Source\install.wim -DiskLayout UEFI
7579
@@ -85,6 +89,11 @@
8589
8690
Creates a Windows To Go VHD image that can boot in UEFI or BIOS mode.
8791
92+
.EXAMPLE
93+
Convert-Wim2VHD -Path c:\windows8.vhdx -SourcePath d:\Source\install.wim -DiskLayout UEFI -UseDismExpansion $true
94+
95+
Creates a VHDX using DISM.exe for image expansion. This is required due to CrowdStrike blocking PowerShell from writing core files like SAM to the target disk.
96+
8897
.NOTES
8998
Author: WindowsImageTools Team
9099
Requires: Administrator privileges
@@ -220,7 +229,11 @@
220229
Test-Path -Path $(Resolve-Path $Path)
221230
}
222231
})]
223-
[string[]]$filesToInject
232+
[string[]]$filesToInject,
233+
234+
# Use DISM for expansion instead of native PowerShell
235+
[Parameter(HelpMessage = 'Use DISM for expansion instead of native PowerShell')]
236+
[switch]$UseDismExpansion
224237

225238
)
226239
$Path = $Path | Get-FullFilePath
@@ -308,6 +321,9 @@
308321
{
309322
$SetVHDPartitionParam.add('filesToInject', $filesToInject)
310323
}
324+
if ($PSBoundParameters.ContainsKey('UseDismExpansion')) {
325+
$SetVHDPartitionParam.add('UseDismExpansion', $UseDismExpansion.IsPresent)
326+
}
311327
Write-Verbose -Message "[$($MyInvocation.MyCommand)] : InitializeVHDPartitionParam"
312328
Write-Verbose -Message ($InitializeVHDPartitionParam | Out-String)
313329
Write-Verbose -Message "[$($MyInvocation.MyCommand)] : SetVHDPartitionParam"
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
function Expand-DpWindowsImage {
2+
<#
3+
.SYNOPSIS
4+
Applies a Windows image from a WIM file to a target directory using DISM.
5+
6+
.DESCRIPTION
7+
Wrapper for DISM.exe to apply a specific image index from a WIM file to a target directory. Mimics Expand-WindowsImage. Optionally uses /Compact for compact OS deployment.
8+
9+
.PARAMETER ImagePath
10+
Path to the WIM file containing the Windows image.
11+
12+
.PARAMETER Index
13+
Index of the image inside the WIM to apply.
14+
15+
.PARAMETER ApplyPath
16+
Target directory where the image will be applied.
17+
18+
.PARAMETER Compact
19+
If specified, applies the image using the /Compact option for compact OS deployment.
20+
21+
.EXAMPLE
22+
Expand-DpWindowsImage -ImagePath 'C:\images\install.wim' -Index 1 -ApplyPath 'D:\Windows'
23+
24+
Applies the first image from install.wim to the D:\Windows directory using DISM.
25+
26+
.EXAMPLE
27+
Expand-DpWindowsImage -ImagePath 'C:\images\install.wim' -Index 1 -ApplyPath 'D:\Windows' -Compact
28+
29+
Applies the first image from install.wim to the D:\Windows directory using DISM with the /Compact option for compact OS deployment.
30+
31+
.NOTES
32+
Author: WindowsImageTools Team
33+
Requires: Administrator privileges
34+
#>
35+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
36+
param (
37+
[Parameter(Mandatory, Position = 0, HelpMessage = 'Path to the WIM file')]
38+
[ValidateNotNullOrEmpty()]
39+
[string]$ImagePath,
40+
41+
[Parameter(Mandatory, Position = 1, HelpMessage = 'Index of the image inside the WIM')]
42+
[ValidateNotNullOrEmpty()]
43+
[int]$Index,
44+
45+
[Parameter(Mandatory, Position = 2, HelpMessage = 'Target directory to apply the image')]
46+
[ValidateNotNullOrEmpty()]
47+
[string]$ApplyPath,
48+
49+
[switch]$Compact
50+
)
51+
52+
$ImagePath = Get-FullFilePath -Path $ImagePath
53+
$ApplyPath = Get-FullFilePath -Path $ApplyPath
54+
55+
$dismArgs = @(
56+
'/Apply-Image',
57+
"/ImageFile:$ImagePath",
58+
"/Index:$Index",
59+
"/ApplyDir:$ApplyPath"
60+
)
61+
if ($Compact) {
62+
$dismArgs += '/Compact'
63+
}
64+
65+
if ($PSCmdlet.ShouldProcess("Apply image index $Index from $ImagePath to $ApplyPath")) {
66+
$psi = New-Object System.Diagnostics.ProcessStartInfo
67+
$psi.FileName = 'dism.exe'
68+
$psi.Arguments = $dismArgs -join ' '
69+
$psi.RedirectStandardOutput = $true
70+
$psi.RedirectStandardError = $true
71+
$psi.UseShellExecute = $false
72+
$psi.CreateNoWindow = $true
73+
$process = [System.Diagnostics.Process]::Start($psi)
74+
$progressActivity = 'Expand Windows Image'
75+
$progressId = 0
76+
$lastPercent = 0
77+
while (-not $process.HasExited) {
78+
while ($null -ne ($line = $process.StandardOutput.ReadLine())) {
79+
if ($line -match '(\d{1,3}\.\d)%') {
80+
$percent = [double]$Matches[1]
81+
$lastPercent = $percent
82+
Write-Progress -Id $progressId -Activity $progressActivity -Status "$percent% Complete" -PercentComplete $percent
83+
}
84+
}
85+
Start-Sleep -Milliseconds 100
86+
}
87+
# Read any remaining output after exit
88+
while ($null -ne ($line = $process.StandardOutput.ReadLine())) {
89+
if ($line -match '(\d{1,3}\.\d)%') {
90+
$percent = [double]$Matches[1]
91+
$lastPercent = $percent
92+
Write-Progress -Id $progressId -Activity $progressActivity -Status "$percent% Complete" -PercentComplete $percent
93+
}
94+
}
95+
# Always write 100% on exit
96+
Write-Progress -Id $progressId -Activity $progressActivity -Status '100% Complete' -PercentComplete 100 -Completed
97+
$stderr = $process.StandardError.ReadToEnd()
98+
if ($process.ExitCode -ne 0) {
99+
throw "DISM failed with exit code $($process.ExitCode): $stderr"
100+
}
101+
}
102+
}

WindowsImageTools/Public/Install-WindowsFromWim.ps1

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@
189189
Test-Path -Path $(Resolve-Path $Path)
190190
}
191191
})]
192-
[string[]]$filesToInject
192+
[string[]]$filesToInject,
193+
194+
# Use DISM for expansion instead of native PowerShell
195+
[Parameter(HelpMessage = 'Use DISM for expansion instead of native PowerShell')]
196+
[switch]$UseDismExpansion
193197

194198
)
195199
$SourcePath = $SourcePath | Get-FullFilePath
@@ -257,6 +261,9 @@
257261
if ($filesToInject) {
258262
$SetDiskPartitionParam.add('filesToInject', $filesToInject)
259263
}
264+
if ($PSBoundParameters.ContainsKey('UseDismExpansion')) {
265+
$SetDiskPartitionParam.add('UseDismExpansion', $UseDismExpansion.IsPresent)
266+
}
260267
Write-Verbose -Message "[$($MyInvocation.MyCommand)] : InitializeDiskPartitionParam"
261268
Write-Verbose -Message ($InitializeVHDPartitionParam | Out-String)
262269
Write-Verbose -Message "[$($MyInvocation.MyCommand)] : SetDiskPartitionParam"

WindowsImageTools/WindowsImageTools.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'WindowsImageTools.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '1.9.30'
15+
ModuleVersion = '1.10.35'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()

0 commit comments

Comments
 (0)