Have you ever experienced slow installations when using the WUSA.exe together with *.MSU files? I did with a number of installations, such as:
- Microsoft Language Packs -> Multi-Language User Interface (MUI)
- Microsoft Internet Explorer 11
- Microsoft Internet Explorer components (Hyphenation, Spelling)
- Microsoft Internet Explorer 11 Language Packs
- Various Microsoft hotfixes
The Solution (short version)
In case you are in a hurry and are not waiting for any blabla, here is the quick version of the solution:
- Do not use the MSU file to install the software, but instead, extract the MSU file and use the included CAB file instead (not the one called WSUSSCAN.cab, the other one). Use the following command to extract the MSU file:
expand -f:* “C:\%InstallFile%.msu” %TEMP%
For example:
expand -f:* “C:\Temp\Windows6.1-KB2896256-x64.msu” C:\TEMP - Then use the following command to install the software:
dism.exe /online /add-package /packagepath:”%InstallFile%.cab” /quiet /norestart /logpath:”%LogFile%”
For example:
dism.exe /online /add-package /packagepath:”C:\Temp\Windows6.1-KB2896256-x64.cab” /quiet /norestart /logpath:”C:\Logs\Install_hotfix_Windows6.1-KB2896256-x64.log”
For more information please continue reading.
The Situation
First of all let’s be clear under which circumstances my problem arose:
- Operating system: Windows Server 2008 R2
- System deployment tool: Microsoft SCCM 2012 R2
- Execution script: PowerShell (version 5.0)
- Execution command in script:
wusa.exe %InstallFile% /quiet /norestart /log:%LogFile%
The PowerShell wrapper was started by SCCM, which means that it runs under the local System account.
The Problem
The installation of the individual installations took a REALLY long time. For example, an Internet Explorer language pack took up to 25 minutes to install, which under normal circumstances should only take 2 minutes or so. The same goes for the other components. Since I was creating a new golden image for my XenDesktop 7.x workers and I was installing 8 language packs this took about 2 hours! This was unacceptable of course.
The Reason
In my installation packages I used the WUSA.exe to install the software. The WUSA.exe is the Windows Update Standalone Installer. As per Microsoft:
The wusa.exe file is located in the %windir%\System32 folder. The Windows Update Standalone Installer uses the Windows Update Agent API to install update packages. Update packages have an .msu file name extension. The .msu file name extension is associated with the Windows Update Standalone Installer.
I have to admit that I am still not 100% sure why the problem arose, but the main cause is for sure related to how the process WUSA.exe works. In the end, I suspect the problem has to do with two things:
- First of all, as written in the aforementioned Microsoft article, the WUSA.exe “uses the Windows Update metadata in the .msu file to search for applicable updates“. This is the first step in the installation process. To me this means that the WUSA process tries to contact either the Windows Update server within our LAN or it tries to reach a Windows Update server on the Internet.
- Secondly, the SCCM installation runs under the local System account. This account has very limited permissions outside of the local server. It does have sufficient rights to contact the Windows Update server in the LAN, but not to contact Windows Update servers on the Internet.
As I said, I am not 100% sure what caused the delay in the process. Either the WUSA.exe tried to contact servers on the Internet (which it could not) or it tried to find some information on the local Windows Update servers which it could not find. I do not know.
In the end, the WUSA.exe process simply “got stuck” for whatever reason. After 25 minutes or so it (probably) ended in a time-out. Mind you, the installation itself worked fine, but it took a really long time to complete.
The Solution (long version)
In the Microsoft article mentioned in the previous paragraph a potential solution is presented. The solution is to install the MSU files by using the command DISM.exe /Add-Package. However, for some reason, this command did not work on all packages. It worked on the Windows Language packs, but not on IE 11 nor the hotfixes. In the cases where it did not work I received a strange error. But I wanted one method to rule them all.
So I decided to go a slightly different way. You see, DISM can be used to install CAB files as well. As per Microsoft:
Operating system package-servicing commands (DISM) can be used offline to install, remove, or update Windows® packages provided as cabinet (.cab) or Windows Update Stand-alone Installer (.msu) files.
Reference: DISM Operating System Package Servicing Command-Line Options
So I decided to use the “dism.exe” command to install the CAB file included within the MSU file. These are the steps:
- Extract the MSU file using the following command:
expand -f:* “C:\Temp\%InstallFile%.msu” %TEMP%
For example:
expand -f:* “C:\Temp\Windows6.1-KB2896256-x64.msu” %TEMP% - After extraction there will be four files present in your directory: two CAB files, one XML file and one TXT file. The MSU file used in this example included the following files:
- Windows6.1-KB2896256-x64.cab
- Windows6.1-KB2896256-x64.xml
- Windows6.1-KB2896256-x64-pkgProperties.txt
- WSUSSCAN.cab
Do NOT use the file called WSUSSCAN.cab. Use the other one. In our example this would be the file Windows6.1-KB2896256-x64.cab.
- Use the following command to install the CAB file:
dism.exe /online /add-package /packagepath:”%InstallFile%” /quiet /norestart /logpath:”%LogFile%”
For example:
dism.exe /online /add-package /packagepath:”C:\Temp\Windows6.1-KB2896256-x64.cab” /quiet /norestart /logpath:”C:\Logs\Install_hotfix_Windows6.1-KB2533623-x64.log”
And one last thing. In case you are wondering why I used the “dism.exe” executable within PowerShell instead of the native PowerShell command “Add-WindowsPackage”, please remember I was working on Windows Server 2008 R2. Even though PowerShell version 5.0 was installed on the local system, the cmdlets for DISM are only available from Windows 8.1/Windows Server 2012 R2.
Dennis Span works as a Lead Account Technology Strategist at Cloud Software Group in Vienna, Austria. He holds multiple Citrix certifications (CCE-V). Dennis has been a Citrix Technology Advocate (CTA) since 2017 (+ one year as Citrix Technology Professional, CTP). Besides his interest in virtualization technologies and blogging, he loves spending time with his family as well as snowboarding, playing basketball and rowing. He is fluent in Dutch, English, German and Slovak and speaks some Spanish.
You are a genius! Thanks.
Thanks a lot for your kind remark Damien! I am glad if the article was of some help to you.
Thank you. I was stuck for days trying to install the Convenience rollup for Windows 7 SP1. Your method finished it in a few hours. Works like a charm. Very nice piece of detective work.
Thanks Alan! Very kind of you. I am happy your problem was solved.
It greatly helped me … Thanks a lot. I appreciate..
I am happy to hear that Deva!
Interesting installation method, i’ve found that disconnecting the internet will allow an MSU file to install much faster. I’m not sure why the local System account would have access to the LAN but not the Internet, seems like an odd design decision by Microsoft to run it under that if this is the case. Might explain why the updates hang for so long though if they can’t actually establish the connection they’re trying to do. Will keep this in mind for next time i’m pushing out large updates.
Hi Andrew. Thanks for your message. I can believe that disconnecting from the Internet may significantly improve the installation of an MSU file. As I state in the article, the WUSA.exe tries to contact a Windows Update server (at least that is what I assume) before installing the MSU. If there is no Internet connection, the WUSA.exe will quickly realize that a connection to a Windows Update server cannot be established and will therefore start with the installation sooner. At least that is what I assume.
Thanks for the help because I can’t run wusa exe because it can’t count to 1
Glad to have been of help Clemens!
For offline image servicing I don’t think DISM performs any of the usual diligence surrounding prerequisite checking. It’ll sometimes let you inject a CAB into a WIM that shouldn’t work due to that WIM missing some other update. If online servicing is the same way, using DISM to install packages could prove troublesome.
I plan to test some of this soon since I’m fighting with a 2012R2 installation and MDT as I write this…
Excellent Alternative. My issue with your alternative though is, I am trying to run some custom sequences using SCCM and WUSA but on Server 2008 SP2 – Where DISM does not yet exist.
Any work arounds for that?
I can use my SUP as a last resort but, i wanted some smooth TS running WUSA setup as applications for each patch.
Hi Royston,
DISM.exe DOES exist on Windows Server 2008 R2, only the equivalent PowerShell command “Add-WindowsPackage” not. Please check it once again.
he said window server 2008 _sp2_, not windows server 2008 _R2_.
Thanks for the info. That looks to sort out an issue where the patches wouldn’t install on a few machines. Wrapped the whole thing up in a Powershell script that may be useful to others. Think that an install date of 01/01/1601 may be used to indicate that a reboot is required but if this isn’t that case, the reboot message will be incorrect:
$roots = @(“$($ENV:USERPROFILE)\Desktop”, “$($ENV:USERPROFILE)\C:\Downloads”)
$copyto = “C:\Temp”
if (-not (Test-Path $copyto)) {
mkdir $copyto -ErrorAction SilentlyContinue
}
$items = @()
foreach ($root in $roots ) {
if ( [System.IO.Directory]::Exists($root) ) {
$items += get-childitem $root | Where-Object -FilterScript {$_.Name -match ‘\(KB\d+\)’}
}
}
[regex]$kbreg = “KB\d+”
foreach ( $item in $items ) {
$patch = get-childitem $item.FullName -recurse
$kb = ($kbreg.Match($item.Name)).Value
if ( $kb ) {
$installfrom = “$copyto\$kb”
mkdir $installfrom
Write-Host “Copying $($patch.Name) to $installfrom”
expand -f:* $patch.FullName $installfrom
$patch = get-childitem -path “$installfrom\*kb*.cab”
Write-Host “$(Get-Date): Installing $($patch.Name)”
$log = “$installfrom\$($kb).log”
$patchpath = $patch.FullName
dism /online /add-package /packagepath:$patchpath /quiet /norestart /logpath:$log
$hotfix = get-hotfix | Where-Object -FilterScript {$_.HotfixID -eq $kb }
$reboot = (“required”, “not required”)[$hotfix.InstallDate -lt (get-date).AddDays( -1 )]
Write-Host “$(Get-Date): Installation finished. Reboot possibly $reboot.”
}
}
Very nice work Kevin. Thanks!
Pingback: DISM repairs for (old) updates still requiring reboot | Wim's Space
Still works for Windows 10. I have no idea why Microsoft doesn’t recognize this issue seriously.
Anyway, thanks for sharing with us!
Hi Bagus. Good to know it still works on W10. I get what you are saying. This issue has persisted in many operating systems and has never been properly addressed.
Your article is a great help.
Found it in times of W2008-R2.
Had a set of required KB’s to install for each Server.
The problem was to install KB’s in the proper order, as the .MSU files time-stamped with the date of the download.
Your article with the idea looking into the KB’s came handy.
The solution is to check the “Modified” date for the .XML files from each .MSU and install the “oldest” ones first.