How to Use PowerShell to Manage Multiple FIM Scenarios on a Lab Computer
FIM ScriptBox Item
When testing various lab scenarios with FIM, it is a good idea to avoid side effects by just having the data deployed that is relevant for a given scenario.
The probably simplest method to have multiple scenarios deployed on a single FIM server is to operate with database backups.
To simplify the scenario based database management in a lab environment, I wrote a collection of scripts.
The idea of the implementation outlined in this post is to create a folder per scenario:
To keep the logic of the script files simple, each scenario folder has a copy of all script files:
While I like PowerShell, I do also like convenience.
Part of this is the ability to start a PowerShell script by double-clicking it.
One way of accomplishing this is to use a VBScript to run a PowerShell script.
The related VBScript has only 5 lines of script code:
Option Explicit
Dim oShell, appCmd
Set oShell = CreateObject("WScript.Shell")
appCmd = "powershell -noexit &'" & Replace(WScript.ScriptFullName, ".vbs", ".ps1") & "'"
oShell.Run appCmd, 4, false
To avoid the need for modifying the script code for each PowerShell script you want to run this way, you just need to save the VBScript in the folder where your PowerShell script is stored.
In addition to this, the VBScript must have the same name as the related PowerShell script.
The gist of the VBScript code is very simple:
- The script code
- Reads its full name
- Replaces the extension “.vbs” with “.ps1”
- Starts PowerShell with the calculated PowerShell script name as parameter.
Backing up the FIM databases
In my testing, I found it helpful to stop the FIM Service and the FIM Synchronization Service and also to restart the SQL Service prior to taking the database backups.
That way, you can make sure that there are no open database handles.
After taking care of these services, the script codes takes the database backups and stores the related files in the current folder.
There is no need to specify parameters for this operation.
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 |
#------------------------------------------------------------------------------------------------------------------------------------ set-variable -name FimServiceDb -value "FIMService" -option constant set-variable -name FimSyncDb -value "FIMSynchronizationService" -option constant set-variable -name ConString -value "Provider=SQLOLEDB;Data Source=localhost;Trusted_Connection=Yes;Initial Catalog=master;" $curFolder = Split-Path -Parent $MyInvocation.MyCommand.Path #------------------------------------------------------------------------------------------------------------------------------------ write-host "Processing database backup" write-host "==========================" write-host "Step 1 of 7: Stopping FIM Service" $fimService = get-service "FIMService" if($fimService.status -ne "Stopped") {stop-Service "FIMService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 2 of 7: Stopping FIM Synchronization Service" $syncService = get-service "FIMSynchronizationService" if($syncService.status -ne "Stopped") {stop-Service "FIMSynchronizationService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 3 of 7: Restarting SQL Server Service" $sqlService = get-service "MSSQLSERVER" restart-Service "MSSQLSERVER" -force write-host "WARNING: Waiting for service '"$sqlService.name"' to finish starting..." -foregroundcolor yellow -backgroundcolor black start-sleep -s 10 if($sqlService.status -ne "Running") {throw "SQL Service is not running"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 4 of 7: Backing up FIM Service database" $connection = New-Object System.Data.OleDb.OleDbConnection $ConString $connection.Open() $fileName = $curFolder + "\" + $FimServiceDb + ".bak" $sqlCmd = "BACKUP DATABASE " + $FimServiceDb + " TO DISK = '" + $fileName + "' WITH FORMAT" $cmd1 = New-Object System.Data.OleDb.OleDbCommand $sqlCmd,$connection $cmd1.executenonquery()|out-null #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 5 of 7: Backing up FIM Synchronization Service database" $fileName = $curFolder + "\" + $FimSyncDb + ".bak" $sqlCmd = "BACKUP DATABASE " + $FimSyncDb + " TO DISK = '" + $fileName + "' WITH FORMAT" $cmd1 = New-Object System.Data.OleDb.OleDbCommand $sqlCmd,$connection $cmd1.executenonquery()|out-null $connection.Close() #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 6 of 7: Starting FIM Service" $fimService = get-service "FIMService" if($fimService.status -eq "Stopped") {start-Service "FIMService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 7 of 7: Starting FIM Synchronization Service" $syncService = get-service "FIMSynchronizationService" if($syncService.status -eq "Stopped") {start-Service "FIMSynchronizationService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "`nCommand completed successfully`n" #------------------------------------------------------------------------------------------------------------------------------------ trap { Write-Host "`nError: $($_.Exception.Message)`n" -foregroundcolor white -backgroundcolor darkred Exit } #------------------------------------------------------------------------------------------------------------------------------------ |
Restoring the FIM databases
The database restore works pretty much the same way as the database backup.
First, the FIM Service and the FIM Synchronization Service are stopped and the SQL Server service is restarted.
Then, the script code uses the backup files in the current folder to restore to a database state.
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 |
------------------------------------------------------------------------------------------------------------------------------------ set-variable -name FimServiceDb -value "FIMService" -option constant set-variable -name FimSyncDb -value "FIMSynchronizationService" -option constant set-variable -name ConString -value "Provider=SQLOLEDB;Data Source=localhost;Trusted_Connection=Yes;Initial Catalog=master;" #------------------------------------------------------------------------------------------------------------------------------------ $curFolder = Split-Path -Parent $MyInvocation.MyCommand.Path $fimServicedBPath = $curFolder + "\" + $FimServiceDb + ".bak" $fimSyncServicedBPath = $curFolder + "\" + $FimSyncDb + ".bak" if((test-path $fimServicedBPath) -eq $false) {throw "FIM service database backup not found"} if((test-path $fimSyncServicedBPath) -eq $false) {throw "FIM synchronization service database backup not found"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Processing FIM Database Restore" write-host "===============================" write-host "Step 1 of 7: Stopping FIM Service" $fimService = get-service "FIMService" if($fimService.status -ne "Stopped") {stop-Service "FIMService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 2 of 7: Stopping FIM Synchronization Service" $syncService = get-service "FIMSynchronizationService" if($syncService.status -ne "Stopped") {stop-Service "FIMSynchronizationService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 3 of 7: Restarting SQL Server Service" $sqlService = get-service "MSSQLSERVER" restart-Service "MSSQLSERVER" -force write-host "WARNING: Waiting for service '"$sqlService.name"' to finish starting..." -foregroundcolor yellow -backgroundcolor black start-sleep -s 10 if($sqlService.status -ne "Running") {throw "SQL Service is not running"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 4 of 7: Restoring FIM Service database" $connection = New-Object System.Data.OleDb.OleDbConnection $ConString $connection.Open() $fileName = $curFolder + "\" + $FimServiceDb + ".bak" $sqlCmd = "RESTORE DATABASE " + $FimServiceDb + " FROM DISK = '" + $fileName + "' WITH REPLACE" $cmd1 = New-Object System.Data.OleDb.OleDbCommand $sqlCmd,$connection $cmd1.executenonquery()|out-null #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 5 of 7: Restoring FIM Synchronization Service database" $fileName = $curFolder + "\" + $FimSyncDb + ".bak" $sqlCmd = "RESTORE DATABASE " + $FimSyncDb + " FROM DISK = '" + $fileName + "' WITH REPLACE" $cmd1 = New-Object System.Data.OleDb.OleDbCommand $sqlCmd,$connection $cmd1.executenonquery()|out-null $connection.Close() #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 6 of 7: Starting FIM Service" $fimService = get-service "FIMService" if($fimService.status -eq "Stopped") {start-Service "FIMService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "Step 7 of 7: Starting FIM Synchronization Service" $syncService = get-service "FIMSynchronizationService" if($syncService.status -eq "Stopped") {start-Service "FIMSynchronizationService"} #------------------------------------------------------------------------------------------------------------------------------------ write-host "`nCommand completed successfully`n" #------------------------------------------------------------------------------------------------------------------------------------ trap { Write-Host "`nError: $($_.Exception.Message)`n" -foregroundcolor white -backgroundcolor darkred Exit } #------------------------------------------------------------------------------------------------------------------------------------ |
Conclusion
As indicated in the introduction, the scripts in this post are not meant to replace a professional backup solution for a production environment.
The idea is to provide a quick and convenient way to manage various scenarios on a lab machine.
Note
To provide feedback about this script, create a post on the FIM TechNet Forum.
For more FIM related Windows PowerShell scripts, see the FIM ScriptBox.