Share via


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:

 

http://j5gkha.bay.livefilestore.com/y1p4xfahhGCYCVtaA-raBfxi-IYZ15iNWvhuhs0zhYnsgc_Z8BZWudg-mcAQGqS3jPHkhYsw7vfQhSXyMnT-IhyeBb9Qv2ppMZh/FIMDBLABMGMT01.jpg

To keep the logic of the script files simple, each scenario folder has a copy of all script files:

http://j5gkha.bay.livefilestore.com/y1pED3qQIV42kEEa7RdzC1al5YmMl7GDP5bS-3jYff21VXafy5s4TJmvN97TGp7TSBBPtnG9snSJyq2iR6cOjhefg/FIMDBLABMGMT02.jpg

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.

 


See Also