Last week in a customer development environment I had one of those oh shit moments where I thought I’d lost a couple of weeks of work. A couple of weeks of development around multiple Management Agents, MV Schema changes etc. Luckily for me I was just connecting to an older VM Image, but it got me thinking. It would be nice to have an automated process that each night would;
- Export each Management Agent on a FIM/MIM Sync Server
- Export the FIM/MIM Synchronisation Server Configuration
- Take a copy of the Extensions Folder (where I keep my PowerShell Management Agents scripts)
- Export the FIM/MIM Service Server Configuration
And that is what this post covers.
My automated process performs the following;
- An Azure PowerShell Timer Function WebApp is triggered at 2330 each night
- The Azure Function App initiates a Remote PowerShell session to my Dev MIM Sync Server (which is also a MIM Service Server)
- In the Remote PowerShell session the script;
- Creates a new subfolder under c:\backup with the current date and time (dd-MM-yyyy-hh-mm)
- Creates further subfolders for each of the backup elements
- Utilizes the Lithnet MIIS Automation PowerShell Module to;
- Enumerate each of the Management Agents on the FIM/MIM Sync Server and export each Management Agent to the MAExports Folder
- Export the FIM/MIM Sync Server Configuration to the ServerExport Folder
- Copies the Extensions folder and subfolder contexts to the MAExtensions Folder
- Utilizes the FIM/MIM Export-FIMConfig cmdlet to export the FIM Server Configuration to the PortalExport Folder
Implementing the FIM/MIM Backup Process
The majority of the setup to get this to work I’ve covered in other posts, particularly around Azure PowerShell Function Apps and Remote PowerShell into a FIM/MIM Sync Server.
- I created a C:\Backup Folder on my FIM/MIM Server. This is where the backups will be placed (you can change the path in the script).
- I installed the Lithnet MIIS Automation PowerShell Module on my MIM Sync Server
- I configured my MIM Sync Server to accept Remote PowerShell Sessions. That involved enabling WinRM, creating a certificate, creating the listener, opening the firewall port and enabling the incoming port on the NSG . You can easily do all that by following my instructions here. From the same post I setup up the encrypted password file and uploaded it to my Function App and set the Function App Application Settings for MIMSyncCredUser and MIMSyncCredPassword.
- I created an Azure PowerShell Timer Function App. Pretty much the same as I show in this post, except choose Timer.
- I configured my Schedule for 2330 every night using the following CRON configuration
0 30 23 * * *
- I set the Azure Function App Timezone to my timezone so that the nightly backup happened at the correct time relative to my timezone. I got my timezone index from here. I set the following variable in my Azure Function Application Settings to my timezone name AUS Eastern Standard Time.
The Function App Script
With all the pre-requisites met, the only thing left is the Function App script itself. Here it is. Update lines 2, 3 & 6 if your variables and password key file are different. The path to your password keyfile will be different on line 6 anyway.
Update line 25 if you want the backups to go somewhere else (maybe a DFS Share).
If your MIM Service Server is not on the same host as your MIM Sync Server change line 59 for the hostname. You’ll need to get the FIM/MIM Automation PS Modules onto your MIM Sync Server too. Details on how to achieve that are here.
Running the Function App I have limited output but enough to see it run. The first part of the script runs very quick. The Export-FIMConfig is what takes the majority of the time. That said less than a minute to get a nice point in time backup that is auto-magically executed nightly. Sorted.
The script itself can be run standalone and you could implement it as a Scheduled Task on your FIM/MIM Server. However I’m using Azure Functions for a number of things and having something that is easily portable and repeatable and centralised with other functions (pun not intended) keeps things organised.
I now have a daily backup of the configurations associated with my development environment. I’m sure this will save me some time in the near future.
Follow Darren on Twitter @darrenjrobinson