Monday, May 16, 2011

Bulk updating user's preferences (UserSettings) in CRM: PART III

I have split this post into 3 parts:
· Part One: Retrieving a spreadsheet with the list of available time zones and languages
· Part Two: Generating a spreadsheet for entering the user preferences for each user
· Part Three: Uploading the updated spreadsheet to update user preferences

Part Three: Uploading the updated spreadsheet to update user preferences

When you have finished filling out the spreadsheet of part two, you are ready to upload the changes to CRM. If you have added data validation and saved the users.xml file as a spreadsheet, you must restore its original XML value (since this tool will not understand Excel format). You can do that by simply generating the users.xml file again and copy-paste into that file from your completed spreadsheet. Make sure you save the file as XML Data (not XML Spreadsheet) when you are done. If you open the usersCompleted.xml file with notepad/VS it must look something like this:

    <Name>Jaques Joy<Name>
    <Language>French (France)<Language>
    <TimeZone>Pacific Standard Time<TimeZone>

Make sure you save your final user settings XML file with the same filename as specified by the usersCompletedFileName variable (see part one). Now you just need a method to upload the user preferences:

private static void UploadUserSettingsSpreadsheet(IOrganizationService service, string fileName)
    XmlDocument xDoc = new XmlDocument();
    foreach (XmlNode node in xDoc.DocumentElement.ChildNodes)
        XmlNode nameNode = node.SelectSingleNode("./Name");
        XmlNode idNode = node.SelectSingleNode("./Id");
        XmlNode languageNode = node.SelectSingleNode("./Language");
        XmlNode timeZoneNode = node.SelectSingleNode("./TimeZone");
        Guid userId = new Guid(idNode.InnerText);
        UserSettings userSettings = RetrieveUserSettings(service, userId);

        string timeZoneName = timeZoneNode.InnerText;
        string languageName = languageNode.InnerText;
        if (string.IsNullOrEmpty(timeZoneName) || !TimeZoneNameToCode.ContainsKey(timeZoneName))
            throw new ArgumentException("Invalid timezone");
        if (string.IsNullOrEmpty(languageName) || !LanguageNameToCode.ContainsKey(languageName))
            throw new ArgumentException("Invalid language");
        userSettings.TimeZoneCode = TimeZoneNameToCode[timeZoneName];
        userSettings.UILanguageId = LanguageNameToCode[languageName];
        userSettings.HelpLanguageId = LanguageNameToCode[languageName];


And voila, your user settings should be uploaded. If you want to verify that your changes have taken effect, you can re-generate the user settings XML from part two and it should have the updated user settings.

Finally, you can download the VS Solution I used here.


  1. Hi,
    UserSettings entity contains many other datetime related attributes, e.g. timezonedaylightbias,timezonedaylightday etc, what happens to those attributes if we update just TimeZoneCode?

  2. They should be updated automatically to the default for the timezone