The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.

Good morning.

I am working on script to synchronize data from Servicenow to Active Roles. To do that, i have created a sync step in which SNOW is the source and ARS the target. In the updating rules, I have a forward sync rule in which I run my script.

The script basically modify the members of a given group from SNOW, using the Remove-QADGroupMember -Identity ($GroupName) -Member $c[$i] -Confirm:$false -Control @{'OperationReason'="Set by script"} // add-qadgroupmember -identity ($GroupName) -member $c[$i] -Control @{'OperationReason'="Set by script"}. This removes or add users to the group and create an entry in the change history.

However, as it is a sync task, I cannot get it working totally, always getting an error. In the beginning, I was synching the "members" target item (ARS attribute) and getting an error as the content of the members change before the script finishes.

Then I decided to try other options. First i went for one of the "Custom Attributes 10" that are available and there I got an error message saying that the attribute can only contain on value. What I could see in the details of the result window is that each user that were removed or added were included in the attribute + a "ActiveRoles.ManagementShell.Data.ArsServerConnection", that comes from the "Connect-QADService -proxy" to get the changes registered in the change history.

So the content of Custom attribute 10 would be ActiveRoles.ManagementShell.Data.ArsServerConnection, user1, user2, (blank). I added the blank with "Return $Null" to leave the attibute blank.
Then I tried with "WhenChanged" attribute and adding the current date with "[DateTime]$date=Get-Date -Format "dd.MM.yyyy HH:mm:ss"" // return $date, getting the error of the subject. i have tried with and without declaring the type of $date, and changing the format to how it is currently registered.

I have also tried to use "Flags" attribute, integer, giving some similar type error.

So I am assuming that every time that the users are added/deleted, they are added to the target item.

After the long explanation, the question, is there a way of pass only the result needed, independently of what the script does?

Would you do this in a different way? I cannot use a direct connection with SNOW, if you are going to suggest that.

Best regards

Top Replies

  • Working with group members in ARSS can be tricky.

    I don't quite understand your comment:  

    Would you do this in a different way? I cannot use a direct connection with SNOW, if you are going to suggest that.

    How are you getting the data to AR now if it's not coming from SNOW?

    Anyway, let's put that aside for the moment.

    Here's my thought

    Why not use your current sync job to populate a multi-value string AR virtual attribute (for example, myTempMembersVA) with the names of the members and then use a scheduled Automation Workflow or an ARSS (post action) Step Handler to process these into the actual members property using your Add-QADGroupMember driven script?

    This assumes however that your members are coming from your source as a simple list of strings (like you would have in the native members attribute - except that in the members attribute, they are DNs)

  • Thank you for your answer.

    Regarding the question you mentioned, about how I am getting the data from SNOW. I meant that I have to use a sync rule instead of connecting through the API or sending POST messages, as to be able to do that, I would need to have a different azure configuration, which would incur in a lot of money per month. Therefore, I use the "Connection" in the Synchronization Service for that, and that makes me use the sync steps.

    Now SNOW stores the Members of a group as normal names (Displayname) while in AD it is stored as Distinguished Name (DN). As this field doesn't even exist in SNOW I cannot do any other thing that:

    Get the name of the modified group

    Connect to SNOW and get the Members of the group

    Convert the names to DN

    Add or remove them from the group in ARS, creating an entry in the change history for each member added or removed

    I got another syn rule working, with a similar script, but in the change history shows the status of the group before and after the change, which makes quite complicated to review the changes.

    Now, regarding your proposed solution, I had thought before about it, but they don't appear in the list of available attributes, so it is not an option. However, I had also think on using a multi-value attribute, that wouldn't be used, and clear it after but, I cannot find one that meets all requirements neither.

    I also cannot find where the output information is kept, till it is assigned to the selected attribute, like some temporary ARS file or something like that, as it is not written to the attribute till the changes are committed.

    I am not sure if it is clear. I can also share some screenshots if needed.

    Regards

  • I got another syn rule working, with a similar script, but in the change history shows the status of the group before and after the change, which makes quite complicated to review the changes.

    Unfortunately, that is the nature of Change History on groups.

    but they don't appear in the list of available attributes,

    You need to:

    1) Add / create the virtual attribute in Active Roles:

    https://support.oneidentity.com/technical-documents/active-roles/7.4.4/administration-guide/254#TOPIC-1624804

    2) Stop and start your sync service to make it recognize the virtual attribute

    NOTE:  If the current Active Roles Sync Service Connection you are using for your "target" is not based on the Active Roles Connector, you will have to create another one that is in order to be able to see this virtual property in the list of available properties to write to.

    also cannot find where the output information is kept, till it is assigned to the selected attribute,

    What I would suggest you do here is modify the attribute mapping rule you are using to get your members from SNOW to use a Powershell script instead of just the SNOW property and add some diagonstic code to dump out the "raw" version of the value coming from SNOW.  Something like this:

    # Get the contents of the SNOW members attribute

    $RawSNOWMembers = $SrcObj["SNOWMembersAttributeName"]

    # Dump this to a file

    Add-Content "My_Test_Log.txt" $("=" * 120 )

    Add-Content "My_Test_Log.txt"  $RawSNOWMembers

    Add-Content "My_Test_Log.txt" $("=" * 120 )

    # Pass the contents of the property on 'as-is'

    $SrcObj["SNOWMembersAttributeName"]

  • The restart of the service worked and now I am able to see the new VA. Thanks for that.

    I am getting now an error coming from SNOW, as it seems that the connector schema cannot find anymore the list I was using (Groups (Sys_user_groups), so the mappings are not working anymore. Will check with SNOW developer and I will let you know if I finally got it running.

    Thank you very much

    -----------------------Edit after solve the issue with SNOW----------------------------

    It has worked. Now the add and remove qadgroup modify the group, adding an entry in the change history and the VA keeps the partial results.

    I will now add a Handler to clear the content of the VA after committing the changes. Any suggestions on how to do that?

    Thank you very much for the help

    Best regards

  • Parsing a string representation of a c# DateTime is a tricky thing because different cultures have different date formats. .Net is aware of these date formats and pulls them from your current culture (System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat) when you call DateTime.Parse(this.Text); You can either call DateTime.ParseExact and pass in the exact format string that you're expecting, or you can pass in an appropriate culture to DateTime.Parse to parse the date.

    For example, this will parse your date correctly:

    DateTime.Parse( "22/11/2009", CultureInfo.CreateSpecificCulture("fr-FR") );

    Of course, you shouldn't just randomly pick France, but something appropriate to your needs.

    What you need to figure out is what System.Threading.Thread.CurrentThread.CurrentCulture is set to, and if/why it differs from what you expect. The IFormatProvider parameter specifies the culture to use to parse the date. Unless your string comes from the user, you should pass CultureInfo.InvariantCulture. If the string does come from the user, you should pass CultureInfo.CurrentCulture, which will use the settings that the user specified in Regional Options in Control Panel.