If you’ve ever dug into the security tables of Sitecore you’ll discover its based on the aspnet membership tables which are typically stored in core.
Recently we needed to export all the users that are in a certain role – it turned out it was easier than expected.
The outcome is that when you view the members of a certain role you can now export to a csv.
There are a few things you need to update to enable the additional ‘Export’ button.
- Update the xaml view for the members popup
- Patch in the new command
- Create a new sitecore command for generating the export
1. Update the xaml view for the members popup
If you navigate to ‘\sitecore\shell\Applications\Security\RoleManager’ and edit ‘ViewMembers.xaml.xml’ you should be able to see 2 buttons – the new one added below:
1 2 3 4 5 6 |
<Border runat="server"> <Button Header="Add" ID="Add" Click="rolemanager:addmember" runat="server" /> <Button Header="Remove" ID="Remove" Click="rolemanager:removemember" runat="server" /> <Button Header="Export" ID="Export" Click="rolemanager:exportusers" runat="server" /> </Border> |
A tip for tracking down the xaml file in question – if you fire up either fiddler/chrome developer tools/firebug and open up the members panel and have a look at the pages being loaded you should see something like:
After the ~ you can see /xaml/Sitecore.Shell.Applications.Security.RoleManager.ViewMembers.aspx – this mimics the folder structure with fullstops replaced by folders.
2. Patch in the new command
Using sitecore patch files, create the new command reference
1 2 3 4 |
<commands> <command name="rolemanager:exportusers" type="###.Shell.Framework.Commands.RoleManager.ExportUsers, ###.Sitecore"/> </commands> |
3. Create a new sitecore command for generating the export
Now you just need the code. The example below allows for profile information to be included in the export, simply update the ProfileFields array to include the properties you want. ComputedFields allows you to amalgamate or process other fields to gather more information as needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
using System; using System.Linq; using Sitecore.Diagnostics; using Sitecore.Security; using Sitecore.Security.Accounts; using Sitecore.Shell.Framework.Commands; using Sitecore.Shell.sitecore.shell.Applications.MarketingAutomation.Utils; using Sitecore.Web; using Sitecore.Web.UI.Sheer; using System.Collections.Generic; namespace ###.Shell.Framework.Commands.RoleManager { public class ExportUsers : Command { protected class UserInRole { public UserInRole(string email, UserProfile userProfile) { Email = email; UserProfile = userProfile; } public string Email { get; set; } public UserProfile UserProfile { get; set; } public static string[] ProfileFields { get { return new[] { "CountryId", "CountryName","DateSubscribed", "Firstname", "Lastname" }; } } internal static List<ComputedField> ComputedFields { get { return new List<ComputedField> { new ComputedField("FullName", profile => String.Concat(profile["Firstname"], " ", profile["Lastname"])) }; } } public static string CsvHeader() { return string.Concat("Email", ",", string.Join(",", ProfileFields.Concat(ComputedFields.Select(a => a.Header)))); } public string ToStringCsv() { return string.Concat(Email, ",", string.Join(",", ProfileFields.Select(key => Clean(UserProfile[key])) .Concat( ComputedFields.Select(a => Clean(a.Action(UserProfile)))))); } private static string Clean(string value) { return value.Replace(",", ""); } internal class ComputedField { public ComputedField(string header, Func<UserProfile, string> action) { Header = header; Action = action; } public string Header { get; private set; } public Func<UserProfile, string> Action { get; private set; } } } public override void Execute(CommandContext context) { Assert.ArgumentNotNull(context, "context"); string queryString = WebUtil.GetQueryString("ro"); IEnumerable<UserInRole> users = LoadUsers(queryString); string filename = "users_in_role_" + Clean(queryString) + DateTime.Now.ToString("_yyyyMMdd_HHmmss") + ".csv"; string file = CsvExporter.ExportToFile(users, filename, UserInRole.CsvHeader, (s) => s.ToStringCsv()); SheerResponse.Download(file); } private string Clean(string queryString) { return queryString.Replace("\\", "-").Replace("/", "-").Replace(" ", "-"); } private IEnumerable<UserInRole> LoadUsers(string roleName) { List<UserInRole> users = new List<UserInRole>(); Role role = Role.FromName(roleName); foreach ( Account account in Sitecore.Context.User.Domain.LocallyManaged ? RolesInRolesManager.GetRoleMembers(role, false, Sitecore.Context.User.Delegation.GetManagedDomains()) : RolesInRolesManager.GetRoleMembers(role, false)) { User user = User.FromName(account.Name, false); if (user != null) { users.Add(new UserInRole(user.Profile.Email, user.Profile)); } } return users; } } } |
Hi there,
I’m trying to export about 100 users from Sitecore and your blog post is really helpful. However, I am slightly stuck – disclosure: I am a Sitecore novice – and I had a couple of very quick questions. 1. the hashes in the namespace and command name, they should be replaced with what, the name of the website folder in inetpub? 2. Vis Studio is throwing an error with Sitecore.Shell.sitecore.shell.Applications.MarketingAutomation.Utils (and Sitecore.Shell.Applications.MarketingAutomation.Utils), is that the correct using statement? Finally 3. Vis Studio saying CsvExported doesn’t exist in the current context, where can I find it?
Sorry again if these questions are beyond dumb.
Paul
The ### are simply to mask out the namespaces I used in the project. They could be anything you want but I suspect would want to mimic the pattern you already have.
The automation tools are in the Sitecore.Shell.MarketingAutomation.dll – have you got that referenced?