A Script to Extract WIM and PSF from MSU Windows Update Files


jen1

Well-known member
Member
Local time
9:15 AM
Posts
96
OS
Windows 11 vmware
I want to share a script I created to extract WIM and PSF files from MSU Windows Update files. You might find it useful, as there are no existing tools that can extract PSF files!

This script is designed for simplicity. To use it, you will need to have 7-Zip installed. The default installation path is C:\Program Files\7-Zip\7z.exe, but you can easily change this in the script if your 7-Zip is located elsewhere (line 24).

How to Use the Script

Extract the MSU file to any folder of your choice.
Place the script inside the same folder. (I will not explain how to run a script in detail here; please refer to my previous thread Reduce the size of the uupdump ISO by approximately 2GB)
Run the script. It will automatically extract the WIM and PSF files into the folder.
After extraction, the script will delete the original WIM and PSF files.
It will also automatically install the SSU and prompt you to install the new KB.

I created this script to extract update files once and then install them quickly and easily in my VMs. Others may find different uses for it.

I want to clarify that I take no credit for the PSF extraction method, as I adapted that part from a script by uupdump. My goal was to make it more user-friendly and accessible for everyone.

I hope this script helps you as much as it has helped me! Feel free to ask any questions or provide feedback.

Powershell:
# =========================
# PSFX Unified Extractor
# =========================

$Base = $PSScriptRoot
Write-Host "Base folder: $Base"

# Detect WIM + PSF
$WimFile = Get-ChildItem $Base -Filter *.wim | Select-Object -First 1
$PsfFile = Get-ChildItem $Base -Filter *.psf | Select-Object -First 1
if (-not $WimFile -or -not $PsfFile) {
    Write-Error "Could not find both .wim and .psf files in $Base"
    exit 1
}
Write-Host "Found WIM: $($WimFile.Name)"
Write-Host "Found PSF: $($PsfFile.Name)"

# Create subfolder for extracted update (same name as WIM without extension)
$SubFolder = Join-Path $Base ($WimFile.BaseName)
if (-not (Test-Path $SubFolder)) {
    New-Item -ItemType Directory -Path $SubFolder | Out-Null
}

# --- Extract WIM with 7-Zip ---
$SevenZip = "C:\Program Files\7-Zip\7z.exe"

Write-Host "Extracting WIM into $SubFolder ..."

Start-Process -FilePath $SevenZip -ArgumentList "x `"$($WimFile.FullName)`" -o`"$SubFolder`" -y" -Wait -NoNewWindow
Remove-Item $WimFile.FullName -Force

# =========================
# Inline PSFX functions (from psfx.txt)
# =========================

function Native($DllFile){
  $Lib = [IO.Path]::GetFileName($DllFile)
  $Marshal = [System.Runtime.InteropServices.Marshal]
  $Module = [AppDomain]::CurrentDomain.DefineDynamicAssembly((Get-Random), 'Run').DefineDynamicModule((Get-Random))
  $Struct = $Module.DefineType('DI', 1048841, [ValueType], 0)
  [void]$Struct.DefineField('lpStart', [IntPtr], 6)
  [void]$Struct.DefineField('uSize', [UIntPtr], 6)
  [void]$Struct.DefineField('Editable', [Boolean], 6)
  $GLOBAL:DELTA_INPUT = $Struct.CreateType()
  $Struct = $Module.DefineType('DO', 1048841, [ValueType], 0)
  [void]$Struct.DefineField('lpStart', [IntPtr], 6)
  [void]$Struct.DefineField('uSize', [UIntPtr], 6)
  $GLOBAL:DELTA_OUTPUT = $Struct.CreateType()
  $Class = $Module.DefineType('PSFE', 1048961, [Object], 0)
  [void]$Class.DefinePInvokeMethod('LoadLibraryW','kernel32.dll',22,1,[IntPtr],@([String]),1,3).SetImplementationFlags(128)
  [void]$Class.DefinePInvokeMethod('ApplyDeltaB',$Lib,22,1,[Int32],@([Int64],[Type]$DELTA_INPUT,[Type]$DELTA_INPUT,[Type]$DELTA_OUTPUT.MakeByRefType()),1,3)
  [void]$Class.DefinePInvokeMethod('DeltaFree',$Lib,22,1,[Int32],@([IntPtr]),1,3)
  $GLOBAL:Win32 = $Class.CreateType()
}

function ApplyDelta($dBuffer,$dFile){
  $trg = [Activator]::CreateInstance($DELTA_OUTPUT)
  $src = [Activator]::CreateInstance($DELTA_INPUT)
  $dlt = [Activator]::CreateInstance($DELTA_INPUT)
  $dlt.lpStart = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($dBuffer.Length)
  $dlt.uSize = [Activator]::CreateInstance([UIntPtr], @([UInt32]$dBuffer.Length))
  $dlt.Editable = $true
  [System.Runtime.InteropServices.Marshal]::Copy($dBuffer,0,$dlt.lpStart,$dBuffer.Length)
  [void]$Win32::ApplyDeltaB(0,$src,$dlt,[ref]$trg)
  if ($trg.lpStart -eq [IntPtr]::Zero){ return }
  $out = New-Object byte[] $trg.uSize.ToUInt32()
  [System.Runtime.InteropServices.Marshal]::Copy($trg.lpStart,$out,0,$out.Length)
  [IO.File]::WriteAllBytes($dFile,$out)
  if ($dlt.lpStart -ne [IntPtr]::Zero){ [System.Runtime.InteropServices.Marshal]::FreeHGlobal($dlt.lpStart) }
  if ($trg.lpStart -ne [IntPtr]::Zero){ [void]$Win32::DeltaFree($trg.lpStart) }
}

function G($DirectoryName){
  $DeltaList = [ordered]@{}
  $doc = New-Object xml
  $doc.Load($DirectoryName + "\express.psf.cix.xml")
  $child = $doc.FirstChild.NextSibling.FirstChild
  while(!$child.LocalName.Equals("Files")){ $child = $child.NextSibling }
  $FileList = $child.ChildNodes
  foreach($file in $FileList){
    $fileChild = $file.FirstChild
    while(!$fileChild.LocalName.Equals("Delta")){ $fileChild = $fileChild.NextSibling }
    $deltaChild = $fileChild.FirstChild
    while(!$deltaChild.LocalName.Equals("Source")){ $deltaChild = $deltaChild.NextSibling }
    $DeltaList[$($file.id)] = @{
      name=$file.name;
      time=$file.time;
      stype=$deltaChild.type;
      offset=$deltaChild.offset;
      length=$deltaChild.length
    }
  }
  return $DeltaList
}

function P($CabFile,$DllFile='msdelta.dll'){
  if ($DllFile -eq 'msdelta.dll' -and (Test-Path "$env:SystemRoot\System32\UpdateCompression.dll")){
    $DllFile = "$env:SystemRoot\System32\UpdateCompression.dll"
  }
  Native $DllFile
  [void]$Win32::LoadLibraryW($DllFile)
  $DirectoryName = $CabFile.Substring(0,$CabFile.LastIndexOf('.'))
  $PSFFile = $DirectoryName + ".psf"
  $null = [IO.Directory]::CreateDirectory($DirectoryName)
  $DeltaList = G $DirectoryName
  $PSFFileStream = [IO.File]::OpenRead([IO.Path]::GetFullPath($PSFFile))
  $cwd = [IO.Path]::GetFullPath($DirectoryName)
  [Environment]::CurrentDirectory = $cwd
  $null = [IO.Directory]::CreateDirectory("000")
  foreach($DeltaFile in $DeltaList.Values){
    $FullFileName = $DeltaFile.name
    if (Test-Path $FullFileName){ continue }
    $ShortFold = [IO.Path]::GetDirectoryName($FullFileName)
    $ShortFile = [IO.Path]::GetFileName($FullFileName)
    $UseRobo = (($cwd + '\' + $FullFileName).Length -gt 255) -or (($cwd + '\' + $ShortFold).Length -gt 248)
    if ($UseRobo -eq 0 -and $ShortFold.IndexOf("_") -ne -1){ $null = [IO.Directory]::CreateDirectory($ShortFold) }
    if ($UseRobo -eq 0){ $WhereFile = $FullFileName } else { $WhereFile = "000\" + $ShortFile }
    try { [void]$PSFFileStream.Seek($DeltaFile.offset,0) } catch {}
    $Buffer = New-Object byte[] $DeltaFile.length
    try { [void]$PSFFileStream.Read($Buffer,0,$DeltaFile.length) } catch {}
    $OutputFileStream = [IO.File]::Create($WhereFile)
    try { [void]$OutputFileStream.Write($Buffer,0,$DeltaFile.length) } catch {}
    [void]$OutputFileStream.Close()
    if ($DeltaFile.stype -eq "PA30" -or $DeltaFile.stype -eq "PA31"){ ApplyDelta $Buffer $WhereFile }
    $null = [IO.File]::SetLastWriteTimeUtc($WhereFile,[DateTime]::FromFileTimeUtc($DeltaFile.time))
    if ($UseRobo -eq 0){ continue }
    Start-Process robocopy.exe -NoNewWindow -Wait -ArgumentList ('"' + $cwd + '\000' + '"' + ' ' + '"' + $cwd + '\' + $ShortFold + '"' + ' ' + $ShortFile + ' /MOV /R:1 /W:1 /NS /NC /NFL /NDL /NP /NJH /NJS')
  }
  [void]$PSFFileStream.Close()
  $null = [IO.Directory]::Delete("000",$True)
}

# =========================
# Run patch
# =========================
Write-Host "Applying PSF patch into $SubFolder ..."
P $WimFile.FullName "msdelta.dll"
Remove-Item $PsfFile.FullName -Force

# =========================
# Prompt to Install
# =========================
# --- Install SSU first if present ---
$SSU = Get-ChildItem $Base -Filter *SSU*.cab | Select-Object -First 1
if ($SSU) {
    Write-Host "Installing Servicing Stack Update: $($SSU.Name)"
    Start-Process dism.exe -ArgumentList "/online /add-package /packagepath:`"$($SSU.FullName)`"" -Wait -NoNewWindow
    Write-Host "SSU installation complete."
} else {
    Write-Host "No SSU CAB found in $Base, skipping SSU install."
}

# --- Prompt to Install LCU ---
$answer = Read-Host "Do you want to install the cumulative update now? (Y/N)"
if ($answer -match '^[Yy]$') {
    Write-Host "Installing LCU via DISM..."
    Start-Process dism.exe -ArgumentList "/online /add-package /packagepath:`"$SubFolder`"" -Wait -NoNewWindow
} else {
    Write-Host "Update prepared in $SubFolder, you can install later with DISM."
}
 

My Computer My Computer

At a glance

Windows 11 vmwareI9 13950hx128GBNVIDIA 4090
OS
Windows 11 vmware
Computer type
Laptop
Manufacturer/Model
Dell
CPU
I9 13950hx
Memory
128GB
Graphics Card(s)
NVIDIA 4090
Sound Card
Realtek
I want to share a script I created to extract WIM and PSF files from MSU Windows Update files. You might find it useful, as there are no existing tools that can extract PSF files!
UUP dump's scripts use PSFExtractor, and it's been used by other image updating scripts. Doesn't that count?
 

My Computer My Computer

At a glance

Windows 7
OS
Windows 7
UUP dump's scripts use PSFExtractor, and it's been used by other image updating scripts. Doesn't that count?
No, it does not. UUPDump uses the script mentioned above and does not utilize PSFExtractor. I won't go into detail about this, as it's intended for advanced users only. However, it's important to note that PSF files are encoded and appear as a blob to PSFExtractor. You can read the script yourself for more information. If you have specific questions about a certain function, I can explain that, but I won't provide details on how the hex structure is written or how it should be modified.
 

My Computer My Computer

At a glance

Windows 11 vmwareI9 13950hx128GBNVIDIA 4090
OS
Windows 11 vmware
Computer type
Laptop
Manufacturer/Model
Dell
CPU
I9 13950hx
Memory
128GB
Graphics Card(s)
NVIDIA 4090
Sound Card
Realtek
Nice script, and for personal use, I 've made a few changes so it will run as admin by default, with the installation of the 7Zip4PowerShell module to unpack the MSUs into the $base folder automatically.

Powershell:
function RunAsAdmin {
    $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
    $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((RunAsAdmin) -eq $false)  {
    if ($elevated) {
    } else {
        Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
    }
    exit
}

# Install PowerShell Module
Write-Host "Istall 7Zip4PowerShell module ..."
Install-Module -Name 7Zip4PowerShell -Force

# Extract MSU Package
Write-Host "Extracting MSU-Package ..."
$msus = Get-ChildItem -Path $Base -Recurse | Where-Object {$_.Extension -eq ".msu"}
foreach($msu in $msus){
    Expand-7Zip $msu.FullName "$Base"
 

My Computer My Computer

At a glance

Windows 10
OS
Windows 10
I do not recommend automatic extraction for the MSU, as you only need six specific files: DesktopDeployment.cab, DesktopDeployment_X86.cab, onepackage.AggregatedMetadata.cab, the SSU, and the WIM and PSF files. I should have mentioned this earlier, but I assumed that anyone wanting to extract the WIM would already know.
Extracting all the files, which is three times the size of the necessary files, will lead to unnecessary disk cycles and overhead, ultimately slowing down the process. Manually extracting the files I mentioned is a faster and more efficient option. Additionally, some users may not need to extract the SSU, so I prefer to make the extraction of the MSU optional. This can be easily done using 7-Zip.
 

My Computer My Computer

At a glance

Windows 11 vmwareI9 13950hx128GBNVIDIA 4090
OS
Windows 11 vmware
Computer type
Laptop
Manufacturer/Model
Dell
CPU
I9 13950hx
Memory
128GB
Graphics Card(s)
NVIDIA 4090
Sound Card
Realtek
Nice script, and for personal use, I 've made a few changes so it will run as admin by default, with the installation of the 7Zip4PowerShell module to unpack the MSUs into the $base folder automatically.

Powershell:
function RunAsAdmin {
    $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
    $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((RunAsAdmin) -eq $false)  {
    if ($elevated) {
    } else {
        Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
    }
    exit
}

# Install PowerShell Module
Write-Host "Istall 7Zip4PowerShell module ..."
Install-Module -Name 7Zip4PowerShell -Force

# Extract MSU Package
Write-Host "Extracting MSU-Package ..."
$msus = Get-ChildItem -Path $Base -Recurse | Where-Object {$_.Extension -eq ".msu"}
foreach($msu in $msus){
    Expand-7Zip $msu.FullName "$Base"
Is this the full script?
 

My Computer My Computer

At a glance

Windows 11Intel Core i7 8th Gen64GB
OS
Windows 11
Computer type
PC/Desktop
CPU
Intel Core i7 8th Gen
Memory
64GB
I want to share a script I created to extract WIM and PSF files from MSU Windows Update files. You might find it useful, as there are no existing tools that can extract PSF files!

This script is designed for simplicity. To use it, you will need to have 7-Zip installed. The default installation path is C:\Program Files\7-Zip\7z.exe, but you can easily change this in the script if your 7-Zip is located elsewhere (line 24).

How to Use the Script

Extract the MSU file to any folder of your choice.
Place the script inside the same folder. (I will not explain how to run a script in detail here; please refer to my previous thread Reduce the size of the uupdump ISO by approximately 2GB)
Run the script. It will automatically extract the WIM and PSF files into the folder.
After extraction, the script will delete the original WIM and PSF files.
It will also automatically install the SSU and prompt you to install the new KB.

I created this script to extract update files once and then install them quickly and easily in my VMs. Others may find different uses for it.

I want to clarify that I take no credit for the PSF extraction method, as I adapted that part from a script by uupdump. My goal was to make it more user-friendly and accessible for everyone.

I hope this script helps you as much as it has helped me! Feel free to ask any questions or provide feedback.

Powershell:
# =========================
# PSFX Unified Extractor
# =========================

$Base = $PSScriptRoot
Write-Host "Base folder: $Base"

# Detect WIM + PSF
$WimFile = Get-ChildItem $Base -Filter *.wim | Select-Object -First 1
$PsfFile = Get-ChildItem $Base -Filter *.psf | Select-Object -First 1
if (-not $WimFile -or -not $PsfFile) {
    Write-Error "Could not find both .wim and .psf files in $Base"
    exit 1
}
Write-Host "Found WIM: $($WimFile.Name)"
Write-Host "Found PSF: $($PsfFile.Name)"

# Create subfolder for extracted update (same name as WIM without extension)
$SubFolder = Join-Path $Base ($WimFile.BaseName)
if (-not (Test-Path $SubFolder)) {
    New-Item -ItemType Directory -Path $SubFolder | Out-Null
}

# --- Extract WIM with 7-Zip ---
$SevenZip = "C:\Program Files\7-Zip\7z.exe"

Write-Host "Extracting WIM into $SubFolder ..."

Start-Process -FilePath $SevenZip -ArgumentList "x `"$($WimFile.FullName)`" -o`"$SubFolder`" -y" -Wait -NoNewWindow
Remove-Item $WimFile.FullName -Force

# =========================
# Inline PSFX functions (from psfx.txt)
# =========================

function Native($DllFile){
  $Lib = [IO.Path]::GetFileName($DllFile)
  $Marshal = [System.Runtime.InteropServices.Marshal]
  $Module = [AppDomain]::CurrentDomain.DefineDynamicAssembly((Get-Random), 'Run').DefineDynamicModule((Get-Random))
  $Struct = $Module.DefineType('DI', 1048841, [ValueType], 0)
  [void]$Struct.DefineField('lpStart', [IntPtr], 6)
  [void]$Struct.DefineField('uSize', [UIntPtr], 6)
  [void]$Struct.DefineField('Editable', [Boolean], 6)
  $GLOBAL:DELTA_INPUT = $Struct.CreateType()
  $Struct = $Module.DefineType('DO', 1048841, [ValueType], 0)
  [void]$Struct.DefineField('lpStart', [IntPtr], 6)
  [void]$Struct.DefineField('uSize', [UIntPtr], 6)
  $GLOBAL:DELTA_OUTPUT = $Struct.CreateType()
  $Class = $Module.DefineType('PSFE', 1048961, [Object], 0)
  [void]$Class.DefinePInvokeMethod('LoadLibraryW','kernel32.dll',22,1,[IntPtr],@([String]),1,3).SetImplementationFlags(128)
  [void]$Class.DefinePInvokeMethod('ApplyDeltaB',$Lib,22,1,[Int32],@([Int64],[Type]$DELTA_INPUT,[Type]$DELTA_INPUT,[Type]$DELTA_OUTPUT.MakeByRefType()),1,3)
  [void]$Class.DefinePInvokeMethod('DeltaFree',$Lib,22,1,[Int32],@([IntPtr]),1,3)
  $GLOBAL:Win32 = $Class.CreateType()
}

function ApplyDelta($dBuffer,$dFile){
  $trg = [Activator]::CreateInstance($DELTA_OUTPUT)
  $src = [Activator]::CreateInstance($DELTA_INPUT)
  $dlt = [Activator]::CreateInstance($DELTA_INPUT)
  $dlt.lpStart = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($dBuffer.Length)
  $dlt.uSize = [Activator]::CreateInstance([UIntPtr], @([UInt32]$dBuffer.Length))
  $dlt.Editable = $true
  [System.Runtime.InteropServices.Marshal]::Copy($dBuffer,0,$dlt.lpStart,$dBuffer.Length)
  [void]$Win32::ApplyDeltaB(0,$src,$dlt,[ref]$trg)
  if ($trg.lpStart -eq [IntPtr]::Zero){ return }
  $out = New-Object byte[] $trg.uSize.ToUInt32()
  [System.Runtime.InteropServices.Marshal]::Copy($trg.lpStart,$out,0,$out.Length)
  [IO.File]::WriteAllBytes($dFile,$out)
  if ($dlt.lpStart -ne [IntPtr]::Zero){ [System.Runtime.InteropServices.Marshal]::FreeHGlobal($dlt.lpStart) }
  if ($trg.lpStart -ne [IntPtr]::Zero){ [void]$Win32::DeltaFree($trg.lpStart) }
}

function G($DirectoryName){
  $DeltaList = [ordered]@{}
  $doc = New-Object xml
  $doc.Load($DirectoryName + "\express.psf.cix.xml")
  $child = $doc.FirstChild.NextSibling.FirstChild
  while(!$child.LocalName.Equals("Files")){ $child = $child.NextSibling }
  $FileList = $child.ChildNodes
  foreach($file in $FileList){
    $fileChild = $file.FirstChild
    while(!$fileChild.LocalName.Equals("Delta")){ $fileChild = $fileChild.NextSibling }
    $deltaChild = $fileChild.FirstChild
    while(!$deltaChild.LocalName.Equals("Source")){ $deltaChild = $deltaChild.NextSibling }
    $DeltaList[$($file.id)] = @{
      name=$file.name;
      time=$file.time;
      stype=$deltaChild.type;
      offset=$deltaChild.offset;
      length=$deltaChild.length
    }
  }
  return $DeltaList
}

function P($CabFile,$DllFile='msdelta.dll'){
  if ($DllFile -eq 'msdelta.dll' -and (Test-Path "$env:SystemRoot\System32\UpdateCompression.dll")){
    $DllFile = "$env:SystemRoot\System32\UpdateCompression.dll"
  }
  Native $DllFile
  [void]$Win32::LoadLibraryW($DllFile)
  $DirectoryName = $CabFile.Substring(0,$CabFile.LastIndexOf('.'))
  $PSFFile = $DirectoryName + ".psf"
  $null = [IO.Directory]::CreateDirectory($DirectoryName)
  $DeltaList = G $DirectoryName
  $PSFFileStream = [IO.File]::OpenRead([IO.Path]::GetFullPath($PSFFile))
  $cwd = [IO.Path]::GetFullPath($DirectoryName)
  [Environment]::CurrentDirectory = $cwd
  $null = [IO.Directory]::CreateDirectory("000")
  foreach($DeltaFile in $DeltaList.Values){
    $FullFileName = $DeltaFile.name
    if (Test-Path $FullFileName){ continue }
    $ShortFold = [IO.Path]::GetDirectoryName($FullFileName)
    $ShortFile = [IO.Path]::GetFileName($FullFileName)
    $UseRobo = (($cwd + '\' + $FullFileName).Length -gt 255) -or (($cwd + '\' + $ShortFold).Length -gt 248)
    if ($UseRobo -eq 0 -and $ShortFold.IndexOf("_") -ne -1){ $null = [IO.Directory]::CreateDirectory($ShortFold) }
    if ($UseRobo -eq 0){ $WhereFile = $FullFileName } else { $WhereFile = "000\" + $ShortFile }
    try { [void]$PSFFileStream.Seek($DeltaFile.offset,0) } catch {}
    $Buffer = New-Object byte[] $DeltaFile.length
    try { [void]$PSFFileStream.Read($Buffer,0,$DeltaFile.length) } catch {}
    $OutputFileStream = [IO.File]::Create($WhereFile)
    try { [void]$OutputFileStream.Write($Buffer,0,$DeltaFile.length) } catch {}
    [void]$OutputFileStream.Close()
    if ($DeltaFile.stype -eq "PA30" -or $DeltaFile.stype -eq "PA31"){ ApplyDelta $Buffer $WhereFile }
    $null = [IO.File]::SetLastWriteTimeUtc($WhereFile,[DateTime]::FromFileTimeUtc($DeltaFile.time))
    if ($UseRobo -eq 0){ continue }
    Start-Process robocopy.exe -NoNewWindow -Wait -ArgumentList ('"' + $cwd + '\000' + '"' + ' ' + '"' + $cwd + '\' + $ShortFold + '"' + ' ' + $ShortFile + ' /MOV /R:1 /W:1 /NS /NC /NFL /NDL /NP /NJH /NJS')
  }
  [void]$PSFFileStream.Close()
  $null = [IO.Directory]::Delete("000",$True)
}

# =========================
# Run patch
# =========================
Write-Host "Applying PSF patch into $SubFolder ..."
P $WimFile.FullName "msdelta.dll"
Remove-Item $PsfFile.FullName -Force

# =========================
# Prompt to Install
# =========================
# --- Install SSU first if present ---
$SSU = Get-ChildItem $Base -Filter *SSU*.cab | Select-Object -First 1
if ($SSU) {
    Write-Host "Installing Servicing Stack Update: $($SSU.Name)"
    Start-Process dism.exe -ArgumentList "/online /add-package /packagepath:`"$($SSU.FullName)`"" -Wait -NoNewWindow
    Write-Host "SSU installation complete."
} else {
    Write-Host "No SSU CAB found in $Base, skipping SSU install."
}

# --- Prompt to Install LCU ---
$answer = Read-Host "Do you want to install the cumulative update now? (Y/N)"
if ($answer -match '^[Yy]$') {
    Write-Host "Installing LCU via DISM..."
    Start-Process dism.exe -ArgumentList "/online /add-package /packagepath:`"$SubFolder`"" -Wait -NoNewWindow
} else {
    Write-Host "Update prepared in $SubFolder, you can install later with DISM."
}
The script gives error in function Native($DllFile) and function ApplyDelta($dBuffer,$dFile).
 

My Computer My Computer

At a glance

Windows 11Intel Core i7 8th Gen64GB
OS
Windows 11
Computer type
PC/Desktop
CPU
Intel Core i7 8th Gen
Memory
64GB
Is this the full script?

No, that's the section that @Maxstar added to the script from @jen1.

The script gives error in function Native($DllFile) and function ApplyDelta($dBuffer,$dFile).

I think you should provide more information for @jen1.

I tested the script on my system using build 26200.5761 and it ran without any problems.


Greetings
 

My Computer My Computer

At a glance

Win 11
OS
Win 11
I do not recommend automatic extraction for the MSU, as you only need six specific files
I know, but I'm using your script for file sourcing purposes only, just to find manifest files and/or cat-mum pairs without installing the update itself.
 

My Computer My Computer

At a glance

Windows 10
OS
Windows 10
I know, but I'm using your script for file sourcing purposes only, just to find manifest files and/or cat-mum pairs without installing the update itself.
Please can you share the full script of your merged version. Thanks.
 

My Computer My Computer

At a glance

Windows 11Intel Core i7 8th Gen64GB
OS
Windows 11
Computer type
PC/Desktop
CPU
Intel Core i7 8th Gen
Memory
64GB
No, that's the section that @Maxstar added to the script from @jen1.



I think you should provide more information for @jen1.

I tested the script on my system using build 26200.5761 and it ran without any problems.


Greetings
Thanks for your encouraging response. Maybe it has to do with the user profile privileges. I will attempt it with the Local Admin profile.
 

My Computer My Computer

At a glance

Windows 11Intel Core i7 8th Gen64GB
OS
Windows 11
Computer type
PC/Desktop
CPU
Intel Core i7 8th Gen
Memory
64GB
Please can you share the full script of your merged version. Thanks.
No, this script is written by @jen1, and in order to avoid violating certain unwritten copyright rules, I will not share a modified script! Also, because you can easily merge the script(s) if you know how it works. And the developer has also indicated that he does not recommend my addition for standard use.
 

My Computer My Computer

At a glance

Windows 10
OS
Windows 10
No, this script is written by @jen1, and in order to avoid violating certain unwritten copyright rules, I will not share a modified script! Also, because you can easily merge the script(s) if you know how it works. And the developer has also indicated that he does not recommend my addition for standard use.
While I share your sense of commitment and sensitivity to both the written and unwritten copyright rules, I am quite sure @jen1 shared the script he developed primarily for knowledge sharing purposes such that others can contribute to making his idea better. By this I don't expect it to be an issue for you to share your fully modified script also for knowledge sharing purposes.

@jen1, kindly indicate your reservation just in case I have misrepresented your intention.

I sincerely appreciate everyone.

Kudos!
 

My Computer My Computer

At a glance

Windows 11Intel Core i7 8th Gen64GB
OS
Windows 11
Computer type
PC/Desktop
CPU
Intel Core i7 8th Gen
Memory
64GB
Back
Top Bottom