我试图将一大堆用户从一个业务部门转移到一个新设置的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?
答案 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并根据他们的旧设置为他们设置新角色的。