FIM, PowerShell and DateTime type attributes

In FIM 2010 we couldn’t update DateTime attribute types using the Configuration Migration PowerShell cmdlets.  This used to crop up from time to time and has hampered quite a few people over the last couple of years.  The good news is that this problem has been fixed in FIM 2010 R2.  In FIM 2010 R2 you can happily modify DateTime attribute values using PowerShell as long as you submit the DateTime value, as a String, in the correct format: ISO-8601 with three digits of fractional precision, i.e. yyyy-MM-ddTHH:mm::ss.fff.

ISO-8601 with three digits of fractional precision

The date/time format expected by the FIM Service web service is the ISO-8601 with three digits of fractional precision format: yyyy-MM-ddTHH:mm::ss.fff.  For example, to flow 01/06/2012 as the start date you would flow: 2012-06-01T00:00:00.000.

Example PowerShell code

The following example updates the EmployeeEndDate of the user PAULW.

# It is assumed that you are executing this script locally on a server that hosts the FIM Service.
# For the purpose of this example, we're targeting a user Paul Williams with an AccountName value
# of PAULW.
[String]$targetAccountName = "paulw";

# Load FIMAutomation module if not already loaded
if(@(Get-PSSnapin | ? { $_.Name -eq "FIMAutomation" } ).Count -eq 0)
{
    Add-PSSnapin FIMAutomation;
}

# Get the target resource's GUID
[String]$targetGuid = (
    Export-FIMConfig `
        -OnlyBaseResources `
        -CustomConfig "/Person[AccountName = '$targetAccountName']"
    ).ResourceManagementObject.ObjectIdentifier;

# Create the import object for the target resource
[Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject]$importObject = `
    New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject;
$importObject.ObjectType = "Person";
$importObject.TargetObjectIdentifier = $targetGuid;
$importObject.SourceObjectIdentifier = $targetGuid;
$importObject.State = [Microsoft.ResourceManagement.Automation.ObjectModel.ImportState]::Put;

# Create the change
[Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange]$importChange = `
    New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange;
$importChange.Operation = [Microsoft.ResourceManagement.Automation.ObjectModel.ImportOperation]::Replace;
$importChange.AttributeName = "EmployeeEndDate";
$importChange.AttributeValue = "2012-06-01T00:00:00.000";
$importChange.FullyResolved = $true;
$importChange.Locale = "Invariant";

# Add the change to the import object
$importObject.Changes += $importChange;

# Submit to FIM Service WS endpoint
Import-FIMConfig -ImportObject $importObject;

Value does not conform to a valid date time format

Note that if the DateTime value is incorrect you’ll get the following error:

Import-FIMConfig : Failure when making web service call.

SourceObjectID = urn:uuid:982e33ee-f107-4382-b411-fd09d6156eeb
Error = System.InvalidCastException: Attribute EmployeeEndDate with value 01/06/2012T00:59:00 does not conform to a valid date time format.
at Microsoft.ResourceManagement.Automation.ImportConfig.UnifiedClientPut(List`1 changeList, UniqueIdentifier objectIdentifier, String objectType, CultureInfo locale)
at Microsoft.ResourceManagement.Automation.ImportConfig.ProcessLocaleBucket(String objectIdentifier, String objectType, Dictionary`2 localeBucket)
at Microsoft.ResourceManagement.Automation.ImportConfig.Put(String objectIdentifier, String objectType, List`1 changeList)
at Microsoft.ResourceManagement.Automation.ImportConfig.EndProcessing()
At line:41 char:17
+ Import-FIMConfig <<<<  -ImportObject $importObject;
+ CategoryInfo          : InvalidOperation: (:) [Import-FIMConfig], InvalidOperationException
+ FullyQualifiedErrorId : ImportConfig,Microsoft.ResourceManagement.Automation.ImportConfig

Note the clear error:

Error = System.InvalidCastException: Attribute EmployeeEndDate with value 01/06/2012T00:59:00 does not conform to a valid date time format.

Other valid DateTime formats

At the start of this post I made a point of clearly stating that you need to use the ISO-8601 with three digits of fractional precision format.  This is not strictly true.  I said this because there are other scenarios whereby you have to use this format, e.g. when exporting DateTime values via the FIM MA.  Within the confines of the PowerShell example you can use other valid string representations of DateTime objects, e.g.

  • 2012-06-01 00:00:00
  • 01 June 2012 00:00:00

From limited testing it looks like we can use any valid string representation supported by System.DateTime.  I guess this means any of the valid patterns supported by System.Globalization.DateTimeFormatInfo.

Advertisements

About Paul Williams

IT consultant working for Microsoft specialising in Identity Management and Directory Services.
This entry was posted in FIM, FIM 2010 R2, Scripting and tagged , , , , , , . Bookmark the permalink.

6 Responses to FIM, PowerShell and DateTime type attributes

  1. Carol says:

    I’m very glad to see that one finally fixed Paul – it really has been far too long to have to work around something so fundamental. Next I’d like to see them fix datetime in the Function Evaluator, in email templates and for it to stop adding and removing hours between the sync service and the portal.

  2. Pingback: Forefront Identity Manager 2010 R2 Documentation | Yet another identity management blog

  3. Leo says:

    Yes I glad it is fixed too, but Is there a way to empty a date field once it is filled in

    • Good question. As I’m sure you know you delete values by performing a replace with an empty string, however in the case of the PS cmdlets they appear to detect and empty string as an invalid format and refuse to permit the operation. I’m going to investigate and post back as soon as I have more info.

      • Looks like this is a limitation in the cmdlet – it doesn’t correctly identify an empty string and handle that specific scenario. Work around is to set the value to [DateTime]::MaxValue or [DateTime]::MinValue, depending on the purpose of the attribute. Or use an alternative WCF client of course. Sorry…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s