When I was patching a production SharePoint farm, the Configuration Wizard failed in three machines due to missing packages. I had verified those packages and I could confirm that they are already installed. After quick investigation, I found that several of the installer cache files are missing from the Windows Installer cache files "C:\Windows\Installer".

For such issue, you have two options:

Copy the missing files from another healthy serverSuch solution is a nightmare, because the files are located on other servers with different names, so, even if you copied all the contents of the “Installer” folder from different healthy machine, will not resolve the problem.

Rebuild the serverThis is the optimum solution but would cost time and sometimes money.

All those files' information are restored on the windows registry, so, there must be away to identify the missing files.

I had searched online hopefully to find a script which can identify the missing files from the registry, but unfortunately, I didn’t find a decisive script which can do it. I could find some scripts with VBS language which can precisely identify the MSP (patch) files with the unique revision number which can be used to identify the missing files on other destination, but they were not precise to identify the MSI (Package) files.

I had found online many are complaining about the same issue when they upgrade/patch SharePoint, SQL or other enterprise software.

Hence, I had built my PowerShell script “Restore-InstallerFiles.ps1” which is capable to identify the missing files and/or restore them from different sources such as local folder, shared folder or another machine which can be accessed from the target machine.

Make sure that the current local identity has Read/Write permission on the "C:\Windows\Installer" folder of the target machine, and Read permission on the source folder (If the source was a machine name, make sure you have read permission on the local folder "C:\Windows\Installer" inside the source machine).

Execute the script locally on the target machine with the following parameters and as illustrated with the following examples.

Minimum System Requirements:

PowerShell Version: 2.0CLR (Microsoft .Net Framework) Version: 2.0

Script Parameters:

.PARAMETER SourceMachine
Alias: M
DataType: System.String[]
Mandatory: True
Description: The name of the source machine(s) where the script can find the missing files there, and restore them to the target machine with the correct names.
Example(s): "Machine1_Name", "Machine2_Name", "Machine3_Name", "Machine4_Name"
Default Value: N/A
Notes: This parameter is a mandatory if the the "SourceFolder" not specified.
.PARAMETER SourceFolder
Alias: F
DataType: System.String[]
Mandatory: True
Description: The source folder(s) where the script can find the missing files there, and restore them to the target machine with the correct names.
Example(s): "D\installer_bak", "D\installer_bak2", "E\installer_bak3"
Default Value: N/A
Notes: This parameter is a mandatory if the the "SourceMachine" not specified.
.PARAMETER ScanOnly
Alias: S
DataType: Switch
Mandatory: True
Description: Only scan for the missing files and then display them without attempting the fix.
Example(s): N/A
Default Value: N/A
Notes: This parameter is a mandatory and cannot be combined with the two parameters "SourceMachine" or "SourceFolder".
.PARAMETER LogFile
Alias: L
DataType: System.String
Mandatory: False
Description: The location of the output transcript logging file.
Example(s): "D:\Log.txt"
Default Value: N/A
Notes: N/A

In the following screenshot, I'm using the script to scan for the missing files, which returned 0 missing files on that machine.

In the following screenshot, I'm using the script to scan for the missing files, which returned 7 missing files on that machine.

In the following screenshot, I'm using the script to restore the missing files from a local folder which copy of the installer cache files from different machine.

Updates:

Date: March, 11th, 2017Update(s): Backward compatibility with PS version 2.0 and CLR (Microsoft .Net Framework) version 2.0.Fixing the bug in the internal function "Get-FileRevisionNumber" which was related with PS version backward compatibility.

Hi Pramod,
If the names are the same on other machines, then, there is no need for my script!
The idea of the script is to scan/crawl for the missing files on other sources (folders/machines) and copy them to the target machine. The scan basically looks into the subject and revision number inside the source file's metadata properties to find the matching with the missing ones.

I hope it resolves your problem. Although I had already tried this script successfully on real large SharePoint farms, but it would be glad if you could share your experience with us and rate the script. Furthermore, your comments/suggestions would be much appreciated which would help me to enhance my script.

Hi, I have problem, when I try to use your script.
I had few errors:
Failed to access the metadata of the file "D:\x64\Setup\sql_rsshp.msi"!
Method invocation failed because [System.__ComObject] does not contain a method named 'SummaryInformation'.

and

Failed to access the metadata of the file "D:\x64\Setup\sqlsqm.msi"!
Copy-TheMissingFile : Cannot bind argument to parameter 'DestinationFile' because it is an empty string.

Thanks for your comment.
I think it would be a permission issue.
Please make sure that you've read permission on the source folder and files. And you get to have Read/Write permission on the “C:Windows\Installer” folder.

If you still encounter further errors, please use the "-LogFile" parameter to get the transcript of the script's output and share it with me. It would be something like that -LogFile "D:\Test.log" (Make sure you've Read/Write permission on that file path.).

Thank you very much for your precious comment.
I had already seen this approach online before and I'm afraid, the function you had provided doesn't retrieve the revision number of the Patch files (*.msp).

After I had reviewed my code, I can confirm that this error occurs when it tries access a non-Windows Installer file. In your case, the file you have could be corrupted, because I had tested on the file “sql_rsshp.msi” for SQL Server 2012 and the file “sqlsqm.msi” for SQL Server 2012 and 2008 R2, and I could retrieve the revision number without any exception. I believe it had worked with you cause, you had added exception handler which would return a null value when it tried to call the “SummaryInformation“.

Nevertheless, with thanks to you, I had updated that function with the Try/Catch scopes to handle the exception, and I had saw a missing parameter for the “Write-Line” and fixed it.

Thanks for the update Ahmad. I realize now that earlier method I used was wrong.
I want to Point out one more function which was not working in Powershell 2 , The ordered Dictionary declaring technic was not supported in Powershell 2.

Thanks again for your precious comments!
I admit that I didn’t consider the backward compatibility for my script to version 2.0. It was compatible with version 5.0 as I was using the “Class” keyword, and then I had modified my script to be compatible with version 4.0.
After I had tested my script with backward compatibility using the “-Version” parameter “%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Version 2”, I had realized that this was the only function was not compatible with version 2. Hence, again with thanks to you, I had updated the function and replaced the array by the “OrderedDictionary” class as you suggested, also, I got to add the “$true” value for the “Mandatory” property as version 2 doesn’t accept it.

Please don’t hesitate to contact me back if you have any further comments. You are always welcome.

Cracking script but I'm having an issue where every file is returning the error "Failed to access the metadata of the file".

I've tried several things to get around the problem. I've used the "SourceFolder" and "SourceMachine" switches with no success. I've tried using a domain account that has admin rights to both machines and I've also tried copying the source machine's "Installer" folder to the target machine and running as Admin but I keep getting the same result. Both folders have been given full rights to the accounts I've used.

Hi,
Usually this error is referring to non-Windows Installer files or corrupted ones as the script is trying to use the Windows Installer COM object to access the MSI and MSP files.
Try another source, also, make sure you’ve read permission on that source folder and read/write permission on the target Installer folder.

If you still encounter further errors, please do the following:
1. use the “-LogFile” parameter to get the transcript of the script’s output and share it with me. It would be something like that -LogFile
D:\Test.log” (Make sure you’ve Read/Write permission on that file path.).
2. If possible, please upload one or more of the MSI/MSP files which the script can access to any Google Drive, One Drive, etc, and share the links with me.
Looking forward to hearing from you soon.

Thank you very much for your reply and the info you had provided.
I had tested the files, and there are all fine.
I'm afraid we are facing environment compatibility issue.

I would ask you kindly to do the following:
1. Download the updated script and run it again with the following two parameters:
-Verbose
-LogFile
2. Run this command on your PowerShell host and share with me the results:
$PSVersionTable;
3. Finally, I would like to know your Windows version info by the following commands:
$windows = (Get-WmiObject -class Win32_OperatingSystem).Caption;
$winVer = [System.Environment]::OSVersion.Version.ToString();
$is64 = [System.Environment]::Is64BitOperatingSystem;
$sp = [System.Environment]::OSVersion.ServicePack;

Thank you very much for your reply. And sorry for my late one.
After several tests, I can confirm that this script is not 100% compatible with PS version 2.0. And from the info you had provided, I believe we have the same compatibility issue with PS version 3.0 as well.
Hence, I can confirm that, the minimum PowerShell Version required in order to run the script is "4.0".
Run "$PSVersionTable;" in your PowerShell host to verify the running PSVersion (PowerShell Version).
You can upgrade to a higher PowerShell version by downloading and installing the "Windows Management Framework".
Windows Management Framework 4.0: www.microsoft.com/.../details.aspx?id=40855Windows Management Framework 5.0: www.microsoft.com/.../details.aspx?id=50395Please review the 'System Requirements' section first before you start your download to verify the compatibility with your OS version.

Are you able to install a higher “Windows Management Framework” version on the target server? If not, are you able to run VBS script there? If upgrading the PS version is not applicable, and you are allowed to run VBS on that server, please bear with me some days to finish my VBS version which is still incomplete and unpublished yet.

thank you for your script. i was able to restore about 64 packages but also have the same errors as other users.
I am running with framework 4 so powershell 4 host.

have the following errors still:
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\a4b512.msp"!
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\a4b51c.msp"!
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\a4b59b.msp"!
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacb5.msi"!
[021/539] - 33a83.msi : \\servername\C$\Windows\Installer\aacb5.msi >>>>> C:\Windows\Installer\33a83.msi
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacb9.msi"!
[022/539] - 33a87.msi : \\servername\C$\Windows\Installer\aacb9.msi >>>>> C:\Windows\Installer\33a87.msi
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacbd.msi"!
[023/539] - 33a8b.msi : \\servername\C$\Windows\Installer\aacbd.msi >>>>> C:\Windows\Installer\33a8b.msi
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacc1.msi"!
[024/539] - 33a8f.msi : \\servername\C$\Windows\Installer\aacc1.msi >>>>> C:\Windows\Installer\33a8f.msi
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacc5.msi"!
[025/539] - 33a93.msi : \\servername\C$\Windows\Installer\aacc5.msi >>>>> C:\Windows\Installer\33a93.msi
Failed to access the metadata of the file "\\servername\C$\Windows\Installer\aacc9.msi"!

Thank you very much for your feedback.
I know all the pain comes from the internal function “Get-FileRevisionNumber” which is not compatible with any PS version before 4.0.
Not sure in your case why it’s not working, cause I had run the script on 10s of life servers already without an issue with PS version 4.0 and CLR version 4.0.
Would you kindly run “$PSVersionTable” and share the output with me?

Nevertheless, I believe I had fixed the lack of the “Get-FileRevisionNumber” function and it should be working fine now with PS version 2.0 and higher, and CLR (.Net Framework) version 2.0 and higher as tested on my labs.
Please download the beta version from the following link and give it a shot, then give me your feedback.
ahmad.jempress.com/.../...nstallerFiles-PSV2.0.ps1

If you still encounter further issues, please use the command again with the following two parameters and share the log file with me, and of course, you can replace the server name, and remove your user name from the log file as it’s generated automatically:
-Verbose
-LogFile "D:\ Restore-InstallerFiles-PSV2.0.log "

Thank you very much for your comment.
First let’s clear one point, this script doesn’t restore the missing/deleted files from nil.
It restore/copy the missing files from other existing healthy source such as other machine in the same network, or a copy of the installer folder from another machine with the same condition of the target one. When I say the same condition, I mean almost the same applications installed on the source machine, should be installed on the target one in order to give the script a chance to determine the missing files.

For your comment about the “0” found, do you mean this is the scan result? Cause if it is, it should give you a big number greater than “0” for sure in your condition.

Anyway, we feel the pain of the missing files when we try to uninstall an existing application or upgrade/patch it, or install some application which has dependency on one of the installed such as the SharePoint for example which needs some other files related to SQL. Which scenario do you have?

Hi Ahmed,
Many many thanks for your instant reply. It was the scan result. The script finally worked. What I did was running the get-help command and it just worked afterword. The scan gave me a huge number found . I'm embarrassed to write it down here . It covered some of them and I will try to cover the rest using another source machine. Thank you for your great work and help.
Best regards.

This a great script
Is this script applicable to be run remotely or using SCCM OR PStools.
I have tried many ways but it failed to recover missing files and it give me missing files found 0 and when I run it locally it worked.

Please advise how I can using is script to be run remote in many computer.

This would require for me to create a simulation VMs to test the remote task.
And I'm afraid, I cannot share the code I've done for my ex employer cause it should belong to them and also it was customized to work with their environments with many validations.
You can search online on how to execute a script remotely with consideration that you cannot perform a remote action/session from a remote session. I mention that because my script is copying files from remote machine already which cannot be added into a remote session. My code must be revised to use parts in remote action and the other parts as local. I know it sounds a complicated task, but I had achieved it before.

Is it possible to copy files from a specific folder of another server? I cannot copy directly from a healthy server due to network restriction but I have another server that will map to the unhealthy server

Hi Shine,
Thank you very much for your comment.
Of course you can specify a folder location in the same machine or remote machine as shown in the two following examples:
.\Restore-InstallerFiles -SourceFolder "D:\InstallerFiles";
.\Restore-InstallerFiles -SourceFolder "\\MachineX\D$\MSI Files";

Thank you very much for your swift response. It is from a different machine and a specific location which is this one:

.\Restore-InstallerFiles -SourceFolder "\\MachineX\D$\MSI Files";

I thought it is not possible but thanks you give me that information. I cannot actually put this on a same location because of space issue and we are not allowed to expand. But I do have a different server that I can map to it. I will try it definitely, Thank you

i am not a computer/coding whiz (though i may be slightly above the common user, tweaking regedit etc sort). my problem came from my adobe acrobat prog. i was trying to find its form feature, then it opened adobe distiller and suddenly started an installation of.. microsoft distributable something? i forget. i cancelled it out of surprise (i didn't run anything??), then it seems to have corrupted/deleted my windows/installer contents. i don't know yet how far the damage went but right now it seems to have disrupted the references for file icons. i have only been able to fix the problem with MSOffice files (.docx, .xlsx icons etc) by reinstalling Office.

so i have 2 questions:
1. do i have to have another computer/system for your script to work on repairs (e.g. another computer with the same programs, to pull the files/folders from)
OR
would it work if exposed to the original program installer (e.g. the MSOffice installer exe)?
2. how do i use the script? it's my first time encountering this format is this just double-click to run?

i am thinking to use your script to save some time (vs having to reinstall all affected programs). hoping to hear from you. thank you

Hi,
First, kindly accept my apologies for my late reply.
The script cannot restore the deleted files from the original machine.
I'm afraid you need to have another machine which you believe it has the same missing software installed to crawl the missing installer file from it. If you don't have access to such machine, then you need to reinstall the missing software again and if it didn't work, you need to rebuild the machine again by reinstalling new Windows and reinstall the software.
I hope you find my reply helpful.
Thank you.

Hello,
No worries. I know your post is from 2017, I was just taking chances myself. I appreciate the reply Aww.. I see. I guess I really have to reinstall my progs. No shortcuts in sight, haha.
Thanks again

Team,
I have face while installed the MSOLEDBSQL V12 and got the below error message. Do we have any solution? i have tried multiple way but no lock. Could anyone help me here?

Product: Microsoft OLE DB Driver for SQL Server -- Error 1723. There is a problem with this Windows Installer package. A DLL required for this installation to complete could not be run. Contact your support personnel or package vendor. Action SNAC_SetClientSSNLDefaults_32, entry: SNAC_SetClientSSNLDefaults, library: C:\Windows\Installer\MSI5EE5.tmp