由于没有解决方案奏效,我决定从编码的角度看看可以做些什么。结果证明是直截了当的。 注意:请确保在编码方法之前检查下面提供的解决方案,因为 Azure DevOps Server 应该会自动刷新身份。
首先,我找到了一篇关于按名称查找用户的 Stack Overflow 文章:
TFS get user by name
这可用于使用 ReadIdentity 方法通过显示名称和其他属性来获取用户或组。
同样的 IIDentityServiceProvider 上还有一个名为 RefreshIdentity 的方法。当使用用户的 IdentityDescriptor 调用此方法时,会强制立即从其提供者刷新身份。请参阅此处的文档:
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/ff734945(v=vs.120)?redirectedfrom=MSDN
如果刷新成功,此方法返回 true,如果刷新失败,则返回 false。刷新也可能引发异常。例如,名为“Project Collection Build Service”的 Azure DevOps 标识在检索时被列为用户,但此标识在刷新时会引发异常。
使用这些方法,可以构建一个完整的工具来修复单个用户的身份,或者扫描“项目集合有效用户”组中的所有用户并刷新整个系统。使用此工具,我们能够修复 Azure DevOps Server 和 Active Directory 之间的同步问题。
下面是一些示例代码,展示了如何使用这些方法:
string rootSourceControlUrl = "TODO: Root URL of Azure DevOps";
string projectCollection = "TODO: Individual project collection within Azure DevOps";
TfsTeamProjectCollection tfsCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri($"{rootSourceControlUrl}/{projectCollection}"));
IIdentityManagementService ims = (IIdentityManagementService)tfsCollection.GetService(typeof(IIdentityManagementService));
TeamFoundationIdentity foundUser = ims.ReadIdentity(IdentitySearchFactor.DisplayName,
"TODO: Display name of user", MembershipQuery.Direct,
ReadIdentityOptions.ExtendedProperties);
if(foundUser != null)
{
try
{
if (ims.RefreshIdentity(foundUser.Descriptor))
{
// Find the user by its original IdentityDescriptor, which shouldn't change during the refresh
TeamFoundationIdentity refreshedUser = ims.ReadIdentity(foundUser.Descriptor,
MembershipQuery.Direct, ReadIdentityOptions.ExtendedProperties);
// TODO : Display changes from foundUser to refreshedUser, using individual properties
// and the method foundUser.GetProperties(), which returns an
// IEnumerable<KeyValuePair<string, object>> collection.
}
else
{
// TODO : Notify that user failed to refresh
}
}
catch(Exception exc)
{
// TODO : Notify that exception occurred
}
}
else
{
// TODO : Notify that user was not found
}