Skip to main content

FIM Run History Statistics

Probably not optimal but I didn't find any problem running this on a server with over 500 runs in the history
Note: Remember to clear your run history every so often!

  1. param(  
  2.     [string]   $ComputerName = '.',  
  3.     [string[]] $MaName       = $null,  
  4.     [string[]] $RunProfile   = $null  
  5. )  
  7. process {  
  8.     Get-WmiObject -Class 'MIIS_RunHistory' -Namespace 'root\MicrosoftIdentityIntegrationServer' -Filter 'RunStatus != "in-progress"' `  
  9.         |? { ([int]$MaName.Count -eq 0 -or $MaName -contains $_.MaName) -and ([int]$RunProfile.Count -eq 0 -or $RunProfile -contains $_.RunProfile) } `  
  10.         | Select-Object -Property MaName,RunProfile,@{Name='RunTime';Expression={[DateTime]::Parse($_.RunEndTime).Subtract([DateTime]$_.RunStartTime).Ticks}} `  
  11.         | Group-Object -Property MaName,RunProfile `  
  12.         | Sort-Object -Property Name `  
  13.         | Select-Object -Property *,@{Name='RunTimeStatistics';Expression={$_.Group |% {$_.RunTime} | Measure-Object -Average -Minimum -Maximum}} `  
  14.         | Select-Object -Property @(  
  15.             @{Name='MaName';Expression={$_.Group | Select-Object -Expand MaName -First 1}},  
  16.             @{Name='RunProfile';Expression={$_.Group | Select-Object -Expand RunProfile -First 1}},  
  17.             @{Name='Count';Expression={$_.Count}},  
  18.             @{Name='Average';Expression={[TimeSpan]::FromTicks($_.RunTimeStatistics.Average)}},  
  19.             @{Name='Minimum';Expression={[TimeSpan]::FromTicks($_.RunTimeStatistics.Minimum)}},  
  20.             @{Name='Maximum';Expression={[TimeSpan]::FromTicks($_.RunTimeStatistics.Maximum)}}  
  21.           )  
  22. }  
Sample Output:
  1. MaName                    RunProfile                Count Average          Minimum          Maximum           
  2. ------                    ----------                ----- -------          -------          -------           
  3. FIM                       Delta Import (Stage Only)    53 00:03:09.6399434 00:00:00.8600000 01:06:17.5000000  
  4. FIM                       Delta Synchronization        40 00:28:40.7335000 00:00:07.3430000 01:56:22.2770000  
  5. FIM                       Export                       73 00:13:49.2960411 00:00:01.1400000 10:40:30.8540000  
  6. FIM                       Full Import (Stage Only)      6 00:53:05.3663333 00:39:20.7340000 01:05:16.5430000  
  7. FIM                       Full Synchronization          5 05:00:17.6780000 02:29:12.5000000 12:23:55.1030000  
  8. HR                        Delta Synchronization         9 00:48:04.5875556 00:00:31.4700000 01:36:13.5440000  
  9. HR                        Full Import (Stage Only)     13 00:29:37.1741538 00:22:12.7530000 00:49:48.9470000  
  10. HR                        Full Synchronization          4 04:29:55.9657500 04:23:31.1970000 04:44:26.8300000  
  11. AD                        Delta Import (Stage Only)    95 00:01:13.9470000 00:00:00.1230000 00:16:50.9160000  
  12. AD                        Delta Synchronization        52 00:20:28.0028846 00:01:10.6770000 01:37:17.9900000  
  13. AD                        Export                       45 00:00:26.8889778 00:00:00.1230000 00:11:19          
  14. AD                        Full Import (Stage Only)      6 00:19:43.9363333 00:15:51.3100000 00:22:27.4700000  
  15. AD                        Full Synchronization          7 05:34:44.6480000 00:00:53.7230000 08:52:22.9770000  
This produces some very nice information for getting an idea of how well your FIM environment is performing. Other kinds of statistics that would be interesting to see would be a per day of week stat.


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.

FIM 2010 R2 Self-Service Password Reset Auto-Registration

I have been working on our FIM 2010 R2 SP1 lab environment looking for ways to simplify some of the overly complicated scenarios we had to implement to workaround the limitations in FIM 2010. One of those workarounds was the auto-registration of SSPR for new employees. When we onboard a new employee, we want to create a simple SSPR for them to get their first-time password reset.

Prior to the R2 release we were using the client and PowerShell to complete the registration process on a daily schedule. I was working on converting this to use the R2 registration cmdlets and combined it with PowerShell 3.0 Workflows to get to a solution similar to this.
[CmdletBinding()]  param()  begin {      workflow Invoke-RegisterSSPR {          InlineScript {              Import-Module FIM          }  $workflow = InlineScript { Get-FIMResource -Filter '/WorkflowDefinition[DisplayName = "Password Reset AuthN Workflow for New Employees"]' }  $members  …

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…