Skip to main content

Asynchronous FIM Run Profile Execution

Update 2011-09-21: I updated the output of the job to be a custom PSObject with more detail about the job.

I am finally to the point in my FIM project where I need to start automating tasks. I took a look at several examples of using PowerShell to start FIM Run Profiles. I wasn't quite satisfied with them as I knew I could do imports async to save time. Finally, a real reason to look into using the Start-Job cmdlet. I am hoping I can use async for exports as well. I imagine others can use this example to multi-thread other processes since it handles most of the basics.
  1. function Start-FIMRunProfile {  
  2.     param (  
  3.         [Parameter(Mandatory = $true)]  
  4.         [ValidateNotNullOrEmpty()]  
  5.         [Alias('MA')]  
  6.         [string] $MaName,  
  8.         [Parameter(Mandatory = $true)]  
  9.         [ValidateNotNullOrEmpty()]  
  10.         [Alias('Profile')]  
  11.         [Alias('Run')]  
  12.         [string] $RunProfile,  
  14.         [ValidateNotNullOrEmpty()]  
  15.         [Alias('Computer')]  
  16.         [string] $ComputerName = '.'  
  17.     )   
  19.     Start-Job -Name "$($ComputerName)\$($maName) ($($profileName))" -ArgumentList $MaName,$RunProfile,$ComputerName -ScriptBlock {  
  20.         param($MaName$RunProfile$ComputerName)  
  22.         $ma = Get-WmiObject -Class "MIIS_ManagementAgent" -Namespace "root\MicrosoftIdentityIntegrationServer" -Filter "Name = '$MaName'" -Computer $ComputerName  
  23.         $started = Get-Date  
  24.         $result = $ma.Execute($RunProfile)  
  25.         $finished = Get-Date  
  27.         $ma | Select-Object @{N='MA';E={$MaName}},@{N='RunProfile';E={$RunProfile}},@{N='Result';E={$result.ReturnValue}},@{N='Started';E={$started}},@{N='Finished';E={Get-Date}},@{N='Duration';E={(Get-Date) - $started}},@{N='Details';E={[xml]$ma.RunDetails().ReturnValue}}  
  29.         if ($result.ReturnValue -ne 'success') {  
  30.             throw $result.ReturnValue  
  31.         }  
  32.     }  
  33. }  
Calling the function is really simple, you can even pipe the output over to the other *-Job cmdlets.
  1. Start-FIMRunProfile 'FIMMA' 'Daily Import'  
  2. Start-FIMRunProfile 'ADMA' 'Daily Import'  
  3. Get-Job | Wait-Job | Receive-Job  
  4. Start-FIMRunProfile 'ADMA' 'Daily Sync' | Wait-Job | Receive-Job  
  5. Start-FIMRunProfile 'FIMMA' 'Daily Sync' | Wait-Job | Receive-Job  
  6. Start-FIMRunProfile 'ADMA' 'Daily Export'  
  7. Start-FIMRunProfile 'FIMMA' 'Daily Export'  
  8. Get-Job | Wait-Job | Receive-Job  


  1. It seems intermittent, but I run into sql-deadlock errors on spids where mms_run_history is being updated. Have you seen this in your environment at all?

  2. No I haven't, the only time I have seen that is if I have tried running more than one sync at a time ...

  3. yeah I would have expected it on the syncs, but this is occurring on Full Import jobs (though I imagine delta and exports should show the same behavior). The issue occurs regardless of how many MAs there are (tried with 8 and later with just 3) and does not occur for all MAs scripted to import.

    Thanks for the quick response though. And, I'll post a resolution should I stumble across one :). For now my work-around is running the imports sequentially.


Post a Comment

Popular posts from this blog

PowerShell SupportsShouldProcess Worst & Best Practices

This has been a very big discussion within the Scripting Games 2013 community and I want to add my two cents in an official blog post.

I've left several people comments on how they might be misunderstanding how SupportsShouldProcess works, but I also realize, everyone of these individuals has given me more insight into its use and perhaps, how it should best be utilized.

For those of you that don't know, SupportsShouldProcess is a parameter on the CmdletBinding attribute you can place on your cmdlets that automatically adds the -WhatIf and -Confirm parameters. These will naturally flow into other cmdlets you use that also SupportsShouldProcess, e.g. New-Item, Move-Item.

The major discussion has been around, should you just let the other cmdlets handle the $PSCmdlet.ShouldProcess feature, and if not how should you implement it. ShouldProcess has the following definitions.

Generate Random SecureString Key

Ever need to encrypt a SecureString that can be used across multiple servers? I suggest storing this BASE64 value in a secure location only accessible by the account(s) that need to decrypt the SecureString.
$secret = 'secret1234'$key    = [Convert]::ToBase64String((1..32 |% { [byte](Get-Random -Minimum 0 -Maximum 255) }))  $encryptedSecret = ConvertTo-SecureString -AsPlainText -Force -String $secret | ConvertFrom-SecureString -Key ([Convert]::FromBase64String($key))  $encryptedSecret | Select-Object @{Name='Key';Expression={$key}},@{Name='EncryptedSecret';Expression={$encryptedSecret}} | fl  $ss = ConvertTo-SecureString -Key ([Convert]::FromBase64String($key)) -String $encryptedSecret(New-Object System.Management.Automation.PSCredential 'SECURESTRING',$ss).GetNetworkCredential().Password

PowerShell Error Handling Behavior Debunked

Note: I am using simple error messages as an example, please reference the best practices and guidelines I outlined on when to use custom error messages.

I have been churning in my mind for the last few days all the entries in the 2013 Scripting Games and how they handle errors, or lack thereof.

I am coming to the conclusion through some testing that the simple fact of seeing a try..catch or throw statements does not mean there is proper error handling.

I've been testing several variations and forms of error handling, so lets start with the basics.
function Test-WriteError {      [CmdletBinding()] param()  "Test-WriteError::ErrorActionPreference = $ErrorActionPreference"Move-Item -Path 'C:\Does\Not\Exists.log' -Destination 'C:\No\Where'"Test-WriteError::End"}   Test-WriteError::ErrorActionPreference = Continue
Move-Item : Cannot find path 'C:\Does\Not\Exists.log' because it does not exist.
At line:6 char:5
+     Move-Item -Path 'C:\Does\N…