如何更新给定用户列表的角色?

时间:2015-01-15 10:19:30

标签: c# dynamics-crm dynamics-crm-4

我试图将一大堆用户从一个业务部门转移到一个新设置的1.我不是任何一个CRM专家,而且我已被告知要移动我们首先需要存储现有角色的用户,然后将它们移动到新BU,然后恢复不具有BU特定的角色,然后修改那些角色。用户的示例是:

BU1
角色:
BU1Admin
BU1Read,只有
合同

将这些移至: BU2
角色:
BU2Admin
BU2Read,只有
合同

因此,在此示例中,用户需要将其管理员角色和只读角色修改为BU2,但合同保持不变。我最初的想法是构建一个查询来检索systemuserid以及角色名称,使用类似的东西:

            Dictionary<Guid, string> UserRoles = new Dictionary<Guid, string>();

            QueryExpression query = new QueryExpression();
            query.EntityName = "systemuserroles";
            ColumnSet cols = new ColumnSet();
            cols.Attributes = new string[] { "systemuserid", "roleid" };
            query.ColumnSet = cols;

            LinkEntity le = new LinkEntity();
            le.LinkFromEntityName = "systemuserroles";
            le.LinkFromAttributeName = "roleid";
            le.LinkToEntityName = "role";
            le.LinkToAttributeName = "roleid";

            LinkEntity le2 = new LinkEntity();
            le2.LinkFromEntityName = "systemuserroles";
            le2.LinkFromAttributeName = "systemuserid";
            le2.LinkToEntityName = "systemuser";
            le2.LinkToAttributeName = "systemuserid";

            // Find only users in BU1
            ConditionExpression ce = new ConditionExpression();
            ce.AttributeName = "businessunitid";
            ce.Operator = ConditionOperator.Equal;
            ce.Values = new string[] { BU1 Guid };

            le2.LinkCriteria = new FilterExpression();
            le2.LinkCriteria.Conditions = new ConditionExpression[] { ce };

            query.LinkEntities = new LinkEntity[] { le, le2 };

            try
            {
                //This call doesn't work and fails saying RetrieveMultiple doesn't support entities of type systemuserroles.
                BusinessEntityCollection UserRolesCollection = crmService.RetrieveMultiple(query);
                foreach (BusinessEntity be in UserRolesCollection.BusinessEntities)
                {
                     //Do my stuff here     
                }
            }
            catch (SoapException se)
            {
                throw new Exception("Error occurred." + se.Detail);
            }

我希望能够做的下一步是使用新角色更新用户。我甚至不知道这是否可以基于我对上述问题的解决。任何帮助将非常感激。我想知道在阅读this后,DynamicEntity在这里有用吗?

更新:

您似乎可以使用AssignUserRolesRole请求类here更新用户角色。但是,我现在仍然坚持检索位。我想知道我是否需要诉诸sql?

2 个答案:

答案 0 :(得分:1)

以下是用于移动用户的不受支持的SQL解决方案。我只是试了一下,一切似乎都运转正常。您可以先在开发环境中尝试一下,以证明它有效,或者它可能是您的混合解决方案的起点。

/* Switch Business Unit */
update su set businessunitid = (select top 1 businessunitid from businessunit where name = '[New Business Unit Name]')
--select fullname, businessunitidname 
from systemuser su
where businessunitidname =  '[Current Business Unit Name]'

/* Identifies users who have roles where the business unit does not match the user's business unit and updates them to match */
update bridge set roleid = newRole.roleid
--select su.fullname, oldRole.name, oldRole.businessunitidname, newRole.name, newRole.businessunitidname
from systemuser su
JOIN systemuserroles bridge ON su.systemuserid = bridge.systemuserid
JOIN [role] oldRole ON bridge.roleid = oldRole.roleid
JOIN [role] newRole ON oldRole.name = newRole.Name and newRole.BusinessUnitIdName = '[New Business Unit Name]'
where oldRole.BusinessUnitId <> su.BusinessUnitId

答案 1 :(得分:0)

我终于设法通过API找到了一种方法。它本质上是2个查询,1表示获取所有用户的systemuserid,第2个查询获取每个systemuserid的roleid。这将为我提供所有用户的当前角色。

我创建了一个字典,将旧角色guids映射到新角色guids。

然后我更改了他们的业务部门,它们摆脱了所有角色,并使用字典和以前存储的用户角色,然后我可以映射到每个用户的新角色。我为类似情况下的任何人提出了这个代码:

private void UpdateUsers()
{
    //Create mapping of old guid to new guid.
    Dictionary<Guid, Guid> LookupRoleGuids = new Dictionary<Guid, Guid>();
    //Add guid mapping
    LookupRoleGuids.Add(new Guid(Old Guid), new Guid(New Guid));

    QueryExpression query = new QueryExpression();
    query.EntityName = "systemuser";
    query.ColumnSet = new AllColumns();

    ConditionExpression ce2 = new ConditionExpression();
    ce2.AttributeName = "systemuserid";
    ce2.Operator = ConditionOperator.Equal;
    ce2.Values = new string[] { User Id }; //Can alter to retrieve for a BU

    FilterExpression filter = new FilterExpression();
    filter.Conditions = new ConditionExpression[] { ce2 };
    query.Criteria = filter;

    try
    {
        BusinessEntityCollection UserCollection = crmService.RetrieveMultiple(query);

        //store the roles of the Users.
        StoreUserRoles(UserCollection);

        foreach (BusinessEntity be in UserCollection.BusinessEntities)
        {
            //Update users BU.
            Guid newBu = new Guid(New BU Guid);
            systemuser su = (systemuser)be;
            SetBusinessSystemUserRequest setBUreq = new SetBusinessSystemUserRequest();
            setBUreq.BusinessId = newBu;
            setBUreq.UserId = su.systemuserid.Value;
            SecurityPrincipal assignee = new SecurityPrincipal();
            assignee.PrincipalId = new Guid(su.systemuserid.Value.ToString());
            setBUreq.ReassignPrincipal = assignee;
            SetBusinessSystemUserResponse assigned = (SetBusinessSystemUserResponse)crmService.Execute(setBUreq);

            //Get users existing roles
            if (UserRolesList.Count() > 0)
            {
                UserRoles ur = UserRolesList.Where(x => x.Value == su.systemuserid.Value)
                                            .Select(x => x).First();

                //Get new role guids based on mapping
                Guid[] roleguids = LookupRoleGuids.Where(x => ur.Roles.Contains(x.Key))
                                                  .Select(x => x.Value)
                                                  .ToArray();

                //Assign new roles 
                AssignUserRolesRoleRequest addRoles = new AssignUserRolesRoleRequest();
                addRoles.UserId = su.systemuserid.Value;
                addRoles.RoleIds = roleguids;
                crmService.Execute(addRoles);
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error occurred updating users BU or assigning new roles. Error: " + ex.Message);
    }
}

public void StoreUserRoles(BusinessEntityCollection UserRolesCollection)
{
    UserRolesList = new List<UserRoles>(); 

    foreach (BusinessEntity be in UserRolesCollection.BusinessEntities)
    {
        systemuser u = (systemuser)be;
        UserRoles ur = new UserRoles();
        ur.Username = u.domainname;
        ur.Value = u.systemuserid.Value;
        UserRolesList.Add(ur);
    }

    AddRolesToList(ref UserRolesList);
}

private void AddRolesToList(ref List<UserRoles> URList)
{
    //Get all roles for a given user guid
    QueryExpression query = new QueryExpression();
    query.EntityName = "role";
    ColumnSet cols = new ColumnSet();
    cols.Attributes = new string[] { "roleid" };
    query.ColumnSet = cols;

    LinkEntity le = new LinkEntity();
    le.LinkFromEntityName = "role";
    le.LinkToEntityName = "systemuserroles";
    le.LinkFromAttributeName = "roleid";
    le.LinkToAttributeName = "roleid";

    LinkEntity le2 = new LinkEntity();
    le2.LinkFromEntityName = "systemuserroles";
    le2.LinkToEntityName = "systemuser";
    le2.LinkFromAttributeName = "systemuserid";
    le2.LinkToAttributeName = "systemuserid";

    foreach(UserRoles ur in URList)
    {
        //loop through the list of userroles and alter the conditional expression with the user's guid.
        ConditionExpression ce = new ConditionExpression();
        ce.AttributeName = "systemuserid";
        ce.Operator = ConditionOperator.Equal;
        ce.Values = new string[] { ur.Value.ToString() };

        le2.LinkCriteria = new FilterExpression();
        le2.LinkCriteria.Conditions = new ConditionExpression[] { ce };

        le.LinkEntities = new LinkEntity[] { le2 };
        query.LinkEntities = new LinkEntity[] { le };

        try
        {
            BusinessEntityCollection RoleGuidsCollection = crmService.RetrieveMultiple(query);
            foreach (BusinessEntity be in RoleGuidsCollection.BusinessEntities)
            {
                role r = (role)be;
                ur.Roles.Add(r.roleid.Value);
            }
        }
        catch (SoapException se)
        {
            throw new Exception("Error occurred retrieving Role Ids for " + ur.Username + " (" + ur.Value + "). " + se.Detail.InnerXml);
        }
        catch (Exception ex)
        {
            throw new Exception("Error occurred retrieving Role Guids for " + ur.Username + " (" + ur.Value + "). " + ex.Message);
        }
    }
}

要为每个用户存储角色,我创建了一个名为UserRoles的类:

class UserRoles
{
    public string Username { get; set; }
    public Guid Value { get; set; }
    public List<Guid> Roles { get; set; }

    public UserRoles()
    {
        Roles = new List<Guid>();
    }
}

注意:这还没有经过全面测试,但似乎做了我想做的事情,这让我可以将用户移动到不同的BU并根据他们的旧设置为他们设置新角色的。