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.
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.
Pingback: Forefront Identity Manager 2010 R2 Documentation | Yet another identity management blog
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…