My name is Charles, I went to the Midwest Management Summit back in May 2019. It was my second time attending the conference. You might remember me as “that guy who has no remote users” 🙂
I said I would blog about a tip I talked about shortly after the conference… This blog post is about 7 months late, I’m sorry!
So for those that do not know this conference, there is a session where anyone can go up on stage and present an IT-related tip or trick.
I went on the stage to talk very briefly about a rather important detail that you need to know when you deal with a disconnected/offline WSUS server: You need to track your update approvals on your internet-connected WSUS server.
On your disconnected WSUS server, you must not approve an update that was not approved on your internet-connected WSUS server or you will have issues.
Microsoft’s official documentation regarding setting up a disconnected WSUS instance can be summarized with the following 3 steps:
- Matching advanced configuration:
- Express updates: If you want to use express updates, make sure that both the internet-connected WSUS and the disconnected WSUS instances have the same setting configured
- Languages: Make sure that you select the same languages for update files
- WsusContent: This one is simple, just copy the “WsusContent” folder on the internet-connected WSUS to the disconnected one.
- Metadata: Export & Import the WSUS metadata with wsusutil.exe import/export
OK, so you made sure that you have the same advanced configuration, you copied the “WsusContent” folder and you imported the metadata from your internet-connected WSUS server… now what?
Well, now you have a bunch of unapproved updates in your WSUS Console on your disconnected WSUS Server. You don’t know which ones were approved or declined on the internet-connected WSUS.
The next part is from my personal experience… If you approve a bunch of updates and some are missing the associated content, WSUS gets stuck. In your WSUS console, it will show that you have thousands of updates “needing files”. What’s happening here is that you approved updates for which your disconnected WSUS does not have the content. In a normal scenario, WSUS would simply download the content from Microsoft. In our case, the WSUS server simply gets stuck there because some updates are missing files. And for some &*%!$% reason, WSUS will not skip over and verify the other updates once it gets stuck with a couple of updates missing content.
Make sure that the same approvals are mirrored on your disconnected WSUS instance.
And when I say update approvals, I mean which updates were declined and which updates were approved.
“OK, I will create the same automatic approval rules on my disconnected WSUS. Done.”
Sure, that might work if you don’t do any kind of cleanup on your WSUS instance. There are various solutions online of scripts that people use to decline/delete updates they don’t need (Itanium, Ia64, superseded updates, etc.)
The automatic approval rules criteria in WSUS are very basic and you will end up approving updates on your disconnected WSUS that are declined on your internet-connected. Ask me how I know…
I personally use Bryan Dam’s software update maintenance script, see his blog posts here and here. This script was originally written to maintain SCCM software update point WSUS instances but later he added the WSUS Standalone mode which I’m using for my WSUS Servers.
I won’t go into details here about which updates I’m declining and whatnot. Just know that if you use a WSUS Server, you should probably have some sort of maintenance script running regularly or you will have a bad time…
“How am I supposed to keep track of all the updates that I declined/approved?”
With PowerShell we can get the information we want and it’s possible to script this so that we can export and import the update approvals.
When you’re ready to do an export of your internet-connected WSUS, you will have to export the metadata, copy the “WsusContent” folder and also get the list of which updates were approved. Make sure you copy all three at the same time to make sure that you have the matching metadata, content and update approvals.
So where I work, the team responsible for copying content over to the disconnected WSUS server is different than the team maintaining WSUS. A procedure was written about how to perform the export and import process but it never worked really well and WSUS crapped itself… many times.
I decided that I had enough with this and tried to automate the process as much as I could.
I wrote a script that I called “Invoke-WSUSImportExportManager”
At first, I simply wanted to automate the following:
- Copy “WsusContent” to $folder
- Copy the WSUS Metadata to $folder
- Record WSUS information in a XML file and copy to $folder
- WSUS Configuration
- WSUS Computer groups hierarchy
- WSUS Update approvals
- Copy “WsusContent”
- Import the WSUS Metadata
- Update WSUS Configuration
- Match the configuration
- Re-create the same computer groups hierarchy
- Approve the same updates to the same computer groups
And then it became bigger and bigger…
On top of doing the import and export process, it also does the following tasks:
- Reindex the WSUS Database
- Adds or Removes the custom indexes (Taken from Bryan Dam’s script)
- Sets a couple of common IIS settings for the WsusPool that should be changed from its default values
- Show locally published updates (third-party updates) in the WSUS console
All these “Actions” that the script performs are customizable.
The script is available on GitHub here. I tried to explain how the script works in the readme but feel free to ask me any questions if you need more information.
Note: My PowerShell skills are not super awesome so I’m sorry for the state of the scripts. If you have some feedback/suggestions regarding that, please let me know and I’ll try my best to improve the scripts.
Charles, Thanks so much for the great article and loved the visual of the struggle with updating air gapped networks!! How do you and your team handle the monthly/quarterly patching between the internet connected WSUS and then transferring to media to take into these networks? I wouldn’t want to export ALL the WSUSContent every time; just the deltas as well as the updated config and metdata files.
Hello! We use robocopy with the mirror option (/MIR) the copy to the media and also when copying to the disconnected WSUS server. Robocopy is smart enough to only copy the things that changed. Does that answer your question?
Please can you explain more? I have this situation in remote sites and if i can not transfer 100gb and transfer only 5gb monthly would be great!!
Hi Diego, sorry I just saw your comment.
As I mentioned below to Krista, the media needs the whole copy of the export. But when it’s time to copy it on the disconnect WSUS, if you use robocopy /MIR, you will only copy the difference so you will save a bit of time but the physical media (USB, HD, etc.) will need the whole copy of the WSUS Export.
I am testing with that now. The problem is that I only want to export the new files to be copied to external media to take to the disconnected WSUS servers versus bringing the entire dataset every time. Are you aware of a clean way to accomplish this?
No, currently the way we use it is that we have the entire dataset on the external media and use robocopy to only copy the differences. In order to only carry a delta of what changed you would need to keep track of what changed on your internet-connected WSUS instance. I personally think it’s easier to simply use robocopy and let it copy only the things that have changed. The part that is the longest when importing update is importing the metadata, not the copy of the patch files. So even if you used deltas, it would still take as much time to import the new updates on your disconnected WSUS.
Great Post, it seems a lot of people are in this “air gapped” situation but not a lot of concrete articles.
Is there a chance to just get the part where you export and import the approved updates?
I tried to go through your code but at 3000 lines long I had trouble understanding where it is plus I am no good at reading code!
Hi Fred, it’s in the “Export-WSUSConfigurationToXML” function that I also save the approvals, here is link: https://github.com/CharlesNRU/updates-automation/blob/fd51d896cf9a2e1cd990e92debd0307f9b19e7ac/WSUS%20Scripts/Invoke-WSUSImportExportManager/Invoke-WSUSImportExportManager.ps1#L1360
But basically, you retrieve all the approved updates and then you loop through each update with the GetUpdateApprovals() method. I record all this information in a XML file that is exported along with the metadata and the WsusContent so that I can approve exactly the same updates on the disconnected WSUS.
Thanks for shedding some much needed light on this subject. I’ve been working for about a month now on trying to get this darn thing to work. I’ve been able to do the export from out connected system, but when doing the import, it seems to always fail when it attempts to do the post install/recreated the database. I’ve gone through the export a half a dozen times, as well as the import, and each time it still does the same thing.
Is there perhaps a step I am missing?
Thanks ahead of time!
So that step uses wsusutil postinstall to re-create the database, it should have created a log file in %TEMP% if wsusutil started successfully, maybe have a look at that log file to see if anything can help you figure out why it’s failing.
Also, it happened a couple of times where I had to completely remove the wsus role, reboot and reinstall it again (including doing the post-install configuration) for this step to work for some reason, but it’s a one-time thing.
Thanks for the speedy reply, it was telling me that the file path was invalid/unrecognized characters. One thing I have noticed on the off network server, when I installed it, it obviously won’t allow me to go through the wizard to have it connect to anything, so I just cancel out of that. I do run the post install it suggests on the GUI, but when I looked through the logs it points to the c:\program files\software etc etc directory, maybe that’s what’s been causing my issues all this time is that I’m not using the post install on the command line. I uninstalled and reinstalled yesterday, as well as ran the post install from the admin command prompt and set it to reimport the stuff yesterday.
I’ll let you know how it goes from here and see if I make any progress.. this has been a learning/nightmare for damn sure!
how to run the import export script
So this works great for syncing, and robocopy cuts down the sync time a lot.
However, the offline WSUS is not accepting any connections.
Anyone run into anything similar?