public/Add-WindowsDriver.ps1
|
<#
.SYNOPSIS Adds one or more drivers into install image indexes. .DESCRIPTION Mounts selected indexes from the install image in media, adds driver packages, and commits changes back to the image. .PARAMETER MediaRoot Path to the root of extracted Windows install media. .PARAMETER DriverPath Path to a driver INF file or a folder containing drivers. .PARAMETER Index Optional index numbers to service. Defaults to all indexes. .PARAMETER Recurse Recursively searches for driver INF files when DriverPath is a folder. .PARAMETER ForceUnsigned Adds unsigned drivers. .PARAMETER MountRoot Temporary root path used for DISM mount operations. .EXAMPLE Add-WindowsDriver -MediaRoot 'D:\Work\Media' -DriverPath 'D:\Drivers' -Recurse -Verbose #> function Add-WindowsDriver { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [string] $MediaRoot, [Parameter(Mandatory)] [string] $DriverPath, [int[]] $Index, [switch] $Recurse, [switch] $ForceUnsigned, [string] $MountRoot = (Join-Path $env:TEMP 'SplitterMounts') ) $resolveDriverPathParams = @{ Path = $DriverPath } $resolvedDriverPath = Resolve-Path @resolveDriverPathParams $getInstallImagePathParams = @{ MediaRoot = $MediaRoot } $installImagePath = Get-InstallImagePath @getInstallImagePathParams $getWindowsInstallImageParams = @{ ImagePath = $installImagePath } $images = Get-WindowsInstallImage @getWindowsInstallImageParams if ($Index) { $images = $images | Where-Object { $_.Index -in $Index } } if (-not $images) { throw "No matching image indexes were found to service." } foreach ($image in $images) { $mountPath = Join-Path $MountRoot ("Image{0}" -f $image.Index) $newCleanDirectoryParams = @{ Path = $mountPath } New-CleanDirectory @newCleanDirectoryParams Write-Verbose "Mounting image index $($image.Index) to $mountPath" $mountArgs = @( '/Mount-Image' "/ImageFile:$installImagePath" "/Index:$($image.Index)" "/MountDir:$mountPath" '/CheckIntegrity' ) try { $invokeMountProcessParams = @{ FilePath = 'dism.exe' ArgumentList = $mountArgs ErrorAction = 'Stop' } Invoke-NativeProcess @invokeMountProcessParams } catch { throw "Failed to mount image index $($image.Index). $($_.Exception.Message)" } $shouldCommit = $false try { $target = "index $($image.Index)" if ($PSCmdlet.ShouldProcess($target, 'Add driver')) { Write-Verbose "Adding driver(s) from $resolvedDriverPath" $addDriverArgs = @( "/Image:$mountPath" '/Add-Driver' "/Driver:$resolvedDriverPath" ) if ($Recurse) { $addDriverArgs += '/Recurse' } if ($ForceUnsigned) { $addDriverArgs += '/ForceUnsigned' } try { $invokeAddDriverProcessParams = @{ FilePath = 'dism.exe' ArgumentList = $addDriverArgs ErrorAction = 'Stop' } Invoke-NativeProcess @invokeAddDriverProcessParams } catch { throw "Failed to add drivers to image index $($image.Index). $($_.Exception.Message)" } $shouldCommit = $true } } finally { if ($shouldCommit) { Write-Verbose "Committing mounted image index $($image.Index)" $unmountArgs = @( '/Unmount-Image' "/MountDir:$mountPath" '/Commit' ) } else { Write-Verbose "Discarding mounted image index $($image.Index)" $unmountArgs = @( '/Unmount-Image' "/MountDir:$mountPath" '/Discard' ) } try { $invokeUnmountProcessParams = @{ FilePath = 'dism.exe' ArgumentList = $unmountArgs ErrorAction = 'Stop' } Invoke-NativeProcess @invokeUnmountProcessParams } catch { throw "Failed to unmount image index $($image.Index). $($_.Exception.Message)" } } } } |