FunctionsToExport/Function_Set-WindowsImageVHD.ps1
Function Set-WindowsImageVHD { [CmdletBinding()] Param( [Parameter(ValueFromPipeline)] [ValidateScript({ $Item = $_ | Get-Item -ErrorAction SilentlyContinue if (-not $Item) { throw 'Item ("{0}") does not exist' -f $_ } elseif ($Item.Attributes -notmatch "Directory") { throw 'Item ("{0}") is not a directory' -f $_ } $true } )] [string]$Location = $PWD, [string]$Name = "WindowsImage", [string[]]$DisableWindowsOptionalFeature, [string[]]$RemoveAppxProvisionedPackage, [string[]]$RemoveWindowsCapability, [string[]]$AddWindowsPackage, [string[]]$AddWindowsDriver, [string[]]$MergeFolder, [string[]]$AddAppxProvisionedPackage, [string]$UnattendPath, [string]$StartBinPath ) $PSDefaultParameterValues['*-VHDChain:Location'] = $Location $PSDefaultParameterValues['*-VHDChain:Name'] = $Name $MountPath = Add-VHDChain | Mount-VHDChain if ($DisableWindowsOptionalFeature) { # Disable-WindowsOptionalFeature # FeatureName # State: Enabled|Disabled 'Disable-WindowsOptionalFeature' | Write-Verbose Get-WindowsOptionalFeature -Path $MountPath | Where-Object { $_.State -eq 'Enabled' -and $DisableWindowsOptionalFeature -contains $_.FeatureName } | ForEach-Object { 'Disable-WindowsOptionalFeature FeatureName: "{0}"' -f $_.FeatureName | Write-Verbose $_ | ConvertTo-Json | Write-Verbose $_ | Disable-WindowsOptionalFeature | ConvertTo-Json | Write-Verbose } } if ($RemoveWindowsCapability) { # Remove-WindowsCapability # Name # State: Installed|NotPresent 'Remove-WindowsCapability' | Write-Verbose Get-WindowsCapability -Path $MountPath | Where-Object { $_.State -eq 'Installed' -and $RemoveWindowsCapability -contains $_.Name } | ForEach-Object { 'Remove-WindowsCapability Name: "{0}"' -f $_.Name | Write-Verbose $_ | ConvertTo-Json | Write-Verbose $_ | Remove-WindowsCapability | ConvertTo-Json | Write-Verbose } } if ($RemoveAppxProvisionedPackage) { # Remove-AppxProvisionedPackage # DisplayName / PackageName # no State 'Remove-AppxProvisionedPackage' | Write-Verbose $ExceptionRegex = @( 'Microsoft.DesktopAppInstaller' 'Microsoft.SecHealthUI' 'Microsoft.VCLibs' 'Microsoft.UI.Xaml' ) -join "|" Get-AppxProvisionedPackage -Path $MountPath | Where-Object { ($RemoveAppxProvisionedPackage -contains $_.DisplayName -or $RemoveAppxProvisionedPackage -contains $_.PackageName) -and $_.PackageName -notmatch $ExceptionRegex } | ForEach-Object { 'Remove-AppxProvisionedPackage PackageName:"{0}"' -f $_.PackageName | Write-Verbose $_ | ConvertTo-Json | Write-Verbose $_ | Remove-AppxProvisionedPackage | ConvertTo-Json | Write-Verbose } } if ($AddWindowsPackage) { 'Add-WindowsPackage' | Write-Verbose $AddWindowsPackage | ForEach-Object { $Splat = @{ Path = $MountPath PackagePath = $_ } $Splat | ConvertTo-Json | Write-Verbose Add-WindowsPackage @Splat | ConvertTo-Json | Write-Verbose } } if ($AddWindowsDriver) { 'Add-WindowsDriver' | Write-Verbose $AddWindowsDriver | ForEach-Object { $Splat = @{ Path = $MountPath Driver = $_ Recurse = $true } $Splat | ConvertTo-Json | Write-Verbose Add-WindowsDriver @Splat | ConvertTo-Json | Write-Verbose } } if ($MergeFolder) { 'Mergefolder' | Write-Verbose $MergeFolder | ForEach-Object { $Splat = @{ Path = $_ + '\*' Destination = $MountPath Recurse = $true } $Splat | ConvertTo-Json | Write-Verbose Copy-Item @Splat | ConvertTo-Json | Write-Verbose } } if ($AddAppxProvisionedPackage) { 'Add-AppxProvisionedPackage' | Write-Verbose $AddAppxProvisionedPackage | ForEach-Object { $Splat = @{ Path = $MountPath PackagePath = $_ Verbose = $true SkipLicense = $true } $Splat | ConvertTo-Json | Write-Verbose Add-AppxProvisionedPackage @Splat | ConvertTo-Json | Write-Verbose } } if ($StartBinPath) { 'Copy start.bin' | Write-Verbose $Splat = @{ Type = 'Directory' Path = Join-Path $MountPath 'Users\Default\AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState' Force = $true Verbose = $true } New-Item @Splat $Splat = @{ Path = $StartBinPath Destination = Join-Path $MountPath 'Users\Default\AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start.bin' Verbose = $true } Copy-Item @Splat | ConvertTo-Json | Write-Verbose } if ($UnattendPath) { 'Copy unattend.xml' | Write-Verbose $Splat = @{ Path = $UnattendPath Destination = Join-Path $MountPath 'unattend.xml' Verbose = $true } Copy-Item @Splat | ConvertTo-Json | Write-Verbose } Dismount-VHDChain } |