Saturday, February 6, 2016

Check your inputs -- Save your job!

At various times in my 10 years of Identity Management Consulting and 25 years working in the IT industry I have been asked to clean up various messes generated by those before me. Some of those messes involved disk failure or other issues that couldn't be completely prevented. But some involved automated process that didn't check their inputs.

 If garbage into a computer gives you garbage out, then garbage into an automated process that doesn't check its inputs gives you a meltdown! Even Disney's Sorcerer's Apprentice Fantasia illustrates what can go wrong with an automated process.

 I have seen the end results when I get called in to fix them. Thousands of groups having lost their members (depopulated) or even worse thousands of users deleted. In the database world unchecked inputs can permit SQL injection attacks.  That's why you check them.

What does it mean to check your inputs? First you need to consider what are valid inputs. Then you establish tests that validate the inputs and if the test fail they halt your automated process and call someone's attention to it. For example in Identity Management if a table is your input, is an empty table valid or does that mean the input is wrong? What about only 1 row? What about looking at how the table has changed? If it has 10% more rows than it did last time or yesterday is that too many? 10% fewer rows? 10% of the rows have changed? I have seen it where a table was used to populate  groups and one row of data appeared, one row of corrupt data. The only check on the input was to see if the table had more than zero rows.

Next you need to be concerned about what you are doing with those inputs. My friend and fellow MVP Carol Wapshere cautions against deleting user data based on an absence of data as well as against taking immediately destructive action.

Here is a look at how you can check your inputs with Microsoft Identity Manager (Forefront Identity Manager)

The first place I like to validate my inputs is at the SQL layer before importing into FIM. I like to keep at least one copy of the old data and then compare to that. Do we have too many new rows (>10%), too few rows (<95 changes="" data="" many="" of="" old="" too="">15%)? If so halt and call a human.

The second place to check is in your script that runs the MA's -- you can check the Adds, Imports and Changes that have just been imported (as long as you just do a stage only). You can check either how many are sitting there or how many happened in the run profile you just ran. The former presents a problem in that existing normal disconnectors will be in your count as adds. The latter is more difficult as you need to find the correct run history get its details and then parse through XML. So to solve this you can use the former method a little more intelligently. Find out how many disconnectors exist prior to running the import, and then subtract them from your # of ImportAdds.

 $MANAme = "HR"
  $Filter = "name='" + $MAName + "'"
    $TheMA = get-wmiobject -class "MIIS_ManagementAgent" -namespace "root\MicrosoftIdentityIntegrationServer" -filter $Filter 
  $PriorImportAdds = $TheMA.NumImportAdd().ReturnValue
   $result = $TheMA.Execute($ProfileName) 
   $returnVal = $result.ReturnValue.ToString() 
  $NumCSObjs = $TheMA.NumCSObjects().ReturnValue
  $smtp = new-object Net.Mail.SmtpClient("")
  if ((100*($TheMA.NumImportAdd().ReturnValue - $PriorImportAdds)/$NumCSObjs) > 10) 
    $smtp.Send("", "", "Too many adds ", " $MAName $ProfileName : $returnVal Please investigate  " )
    Write-Error "Too many adds  $MAName $ProfileName : $returnVal " -EA Stop
  if ((100*$TheMA.NumImportDelete().ReturnValue/$NumCSObjs) > 1) #1% 
  { $smtp.Send("", "", "Too many adds ", " $MAName $ProfileName : $returnVal Please investigate  " )
    Write-Error "Too many deletes  $MAName $ProfileName : $returnVal " -EA Stop
  if ((100*$TheMA.NumImportUpdate().ReturnValue/$NumCSObjs) > 1) #1% 
  { $smtp.Send("", "", "Too many adds ", " $MAName $ProfileName : $returnVal Please investigate  " )
    Write-Error "Too many deletes  $MAName $ProfileName : $returnVal " -EA Stop

Later in your script you can check after you run a delta sync to see how many pending changes you have to AD, deletes, updates, and adds. If they exceed your threshold call a human.

The easiest safeguard to put in place to limit the damage is to limit how many deletes you will process in the export run profile step. This limits how many get deleted. I highly recommend this a quick first step, especially if you have no other safeguards.

This still allows deletions to take place but slows it down. i.e the first run will delete 50, the next run will delete 50 and so on until all of the deletions take place. But this is more survivable -- especially if you have your script notify you if the step stops.

If you do nothing else please limit the number of deletes on your export profiles and remember that MIM (FIM/ILM/MIIS) like all power tools requires care when using.