问题 我在哪里管理TFS用户的电子邮件地址?


在我的Team Foundation Server中,我有一个包含Team Project的集合。该团队项目有几个贡献者。以下代码行获得该项目的所有贡献者:

TfsTeamProjectCollection collection = new TfsTeamProjectCollection(new Uri("http://tfs:8080/tfs/CollectionName"));

IGroupSecurityService groupSecurityService = collection.GetService<IGroupSecurityService>();

Identity contributors = groupSecurityService.ReadIdentity(SearchFactor.AccountName, "[ProjectName]\\Contributors", QueryMembership.Expanded);

Identity[] members = groupSecurityService.ReadIdentities(SearchFactor.Sid, contributors.Members, QueryMembership.None);

每个身份 会员 有财产 邮件地址,在我的情况下等于string.Empty。

我在哪里管理这些邮件地址?

我的第一个想法是在开始 - >管理工具 - >计算机管理 - >用户中查看用户

我选择了其中一个用户并打开了他的属性。我以为TFS可能会有一个电子邮件属性。但我找不到一个。

然后我打开了TFS管理控制台,查找了组成员身份并导航到其中一个用户。也无法编辑属性。

有谁知道在哪里设置该电子邮件地址?


12318
2018-02-09 10:24


起源



答案:


好问题!有一个TFS作业计划每小时运行一次,以根据Active Directory中的详细信息更新存储在TFS中的安全身份信息。其中一些信息包括显示名称,安全标识符(SID),AD专有名称和电子邮件地址等。你可以通过查看来查找详细信息的缓存 tbl_security_identity_cache 配置数据库中的表。

警告查询或更改数据库会使您无法获得Microsoft的支持。除非Microsoft支持代表在有效支持案例的上下文中指示,否则建议您不要这样做。您实际上是通过使用TFS SDK来获取此信息。

如果您的TFS环境不在Active Directory环境中,则它将尝试从运行TFS的本地计算机同步信息。它没有关于要使用的电子邮件地址的详细信息,因此将留空。

从TFS 2010之后的下一版TFS开始,每个用户都可以使用Team Web Access在其配置文件中更新其通知电子邮件地址。


9
2018-02-09 22:04



谢谢你的详细解答。这些都是好消息。所以现在我可以在发布版本时自动向每个团队成员发送电子邮件。 :) - Christian
如果TFS未连接到AD,是否真的无法管理用户电子邮件地址?任何插件,API或类似的东西可以做这样的事情? - Xorandor
正确 - 在TFS 2005,TFS 2008和TFS 2010中。用户可以通过Team Web Access中的Profile Management更新下一版TFS中的通知电子邮件地址,但我不确定是否会有为管理员提供的UI可以更新它们。下一版TFS还没有完成,所以我们会看到!如果它以可以通过API编辑的方式存储,那么有人可能会构建一个自定义工具来执行它。 - Ed Blankenship
使用Tfs 2012,有没有办法知道使用哪些电子邮件 [会员的默认提醒地址] 何时设置团队提醒?看到我的整个问题 这里 - Urban Björkman


答案:


好问题!有一个TFS作业计划每小时运行一次,以根据Active Directory中的详细信息更新存储在TFS中的安全身份信息。其中一些信息包括显示名称,安全标识符(SID),AD专有名称和电子邮件地址等。你可以通过查看来查找详细信息的缓存 tbl_security_identity_cache 配置数据库中的表。

警告查询或更改数据库会使您无法获得Microsoft的支持。除非Microsoft支持代表在有效支持案例的上下文中指示,否则建议您不要这样做。您实际上是通过使用TFS SDK来获取此信息。

如果您的TFS环境不在Active Directory环境中,则它将尝试从运行TFS的本地计算机同步信息。它没有关于要使用的电子邮件地址的详细信息,因此将留空。

从TFS 2010之后的下一版TFS开始,每个用户都可以使用Team Web Access在其配置文件中更新其通知电子邮件地址。


9
2018-02-09 22:04



谢谢你的详细解答。这些都是好消息。所以现在我可以在发布版本时自动向每个团队成员发送电子邮件。 :) - Christian
如果TFS未连接到AD,是否真的无法管理用户电子邮件地址?任何插件,API或类似的东西可以做这样的事情? - Xorandor
正确 - 在TFS 2005,TFS 2008和TFS 2010中。用户可以通过Team Web Access中的Profile Management更新下一版TFS中的通知电子邮件地址,但我不确定是否会有为管理员提供的UI可以更新它们。下一版TFS还没有完成,所以我们会看到!如果它以可以通过API编辑的方式存储,那么有人可能会构建一个自定义工具来执行它。 - Ed Blankenship
使用Tfs 2012,有没有办法知道使用哪些电子邮件 [会员的默认提醒地址] 何时设置团队提醒?看到我的整个问题 这里 - Urban Björkman


以下是TFS 2013 Update 5

** WARNING ** Getting caught editing the TFS database directly
** will void your Microsoft Support Agreement. **
What follows is not for the uninitiated.  ** Proceed at your own risk. **

找到需要设置电子邮件地址的用户。可能有重复 Identities 表。我发现那些最高的 SequenceId 很活跃 Identities

Use Tfs_TFSConfiguration
SELECT i1.AccountName, i1.Id FROM tbl_Identity AS i1
LEFT OUTER JOIN tbl_Identity AS i2
    ON (i1.AccountName=i2.AccountName AND i1.SequenceId<i2.SequenceId)
WHERE i2.AccountName IS NULL
    AND i1.AccountName in ('<your first user>','<another user>','<and so on>')

这给出了最新的列表 Id(以GUID形式),您需要更新的帐户。必须将这些GUID重新格式化为 ArtifactId(s),这是一种转换的二进制格式。这是通过反转GUID的字节顺序(从低到高)或前三个部分中的每一个来完成的,但是按顺序保留最后两个部分。例如。:

Returned 'Id' GUID     =01020304-0506-0708-090A-0B0C0D0E0F10
Byte Swapped GUID      =04030201-0605-0807-090A-0B0C0D0E0F10
Reformatted 'ArtifacId'=0x0403020106050807090A0B0C0D0E0F10

接下来,你必须找到 PropertyId(s)TFS用于电子邮件通知。在TFS 2013 U5中,可以使用以下查询找到它:

USE Tfs_TFSConfiguration
SELECT Name, PropertyId FROM tbl_PropertyDefinition WHERE Name LIKE '%Address%'

这会给你的 PropertyId(s)for ConfirmedNotificationAddress 和 CustomNotificationAddresses;这是TFS 2013 U5用于发送通知电子邮件的两个属性字段。

接下来,你必须找到 InternalKindId为了 Identity TFS的框架 DatabaseCategory

USE Tfs_TFSConfiguration
SELECT Description, InternalKindId FROM tbl_PropertyArtifactKind
WHERE Description='Identity'

现在把它们放在一起,......

如果您的用户的配置记录已存在,您可以使用以下命令更新设置:

USE Tfs_TFSConfiguration
UPDATE tbl_PropertyValue SET LeadingStringValue='<user's notification email address>'
WHERE ArtifactId=<ArtifactId, reformatted from tbl_Identity query>
AND PropertyId IN ('<first PropertyId from tbl_PropertyDefinition>', '<second id>')

注意: 那 ArtifactId 是一个二进制值,基于半字节交换的数据库GUID,并且不匹配中的引用值 UPDATE 查询。即这部分查询看起来像:

WHERE ArtifactId=0x90D490F6BF7B31491CB894323F38A91F AND

下面我假设了 PartitionId 是'1';在继续简要扫描记录之前,应该先验证这一点 tbl_PropertyValue 表。
如果要加载尚未设置的配置设置:

USE Tfs_TFSConfiguration
INSERT INTO tbl_PropertyValue
    (PartitionId, ArtifactId, InternalKindId, Version, PropertyId, LeadingStringValue)
VALUES ('1', <ArtifactId, reformatted from tbl_Identity query>,
    '<InternalKindId from tbl_PropertyArtifactKind>',
    '0',
    '<first PropertyId from tbl_PropertyDefinition>', 
    '<user's notification email address>'),

    ('1', <ArtifactId, reformatted from tbl_Identity query>,
    '<InternalKindId from tbl_PropertyArtifactKind>',
    '0',
    '<second PropertyId from tbl_PropertyDefinition>', 
    '<user's notification email address>')

注意: 那 ArtifactId 必须是一个不带引号的二进制值,从返回的GUID转换而来 tbl_Identity 如上所述。
注意: 为每个创建两个记录 ArtifactId,每个一个 PropertyId

** WARNING ** Getting caught editing the TFS database directly
** will void your Microsoft Support Agreement. **
** Proceed at your own risk. **

(这对我有用,但是,我没有Microsoft支持协议来使其无效。)


3
2018-03-27 17:18





如果Active Directory未与TFS同步,并且假设您保留电子邮件地址的目的是发送通知,则可以使用 IEventService.GetEventSubscriptions() 方法。

var eventService = (IEventService)collection.GetService(typeof(IEventService));

foreach (var member in members)
{
    var subscription = eventService.GetEventSubscriptions(member.DisplayName).First();
    {
        if (subscription != null && string.IsNullOrEmpty(member.MailAddress))
            member.MailAddress = subscription.DeliveryPreference.Address;
    }
}

2
2018-02-09 23:01



分配 member.MailAddress = ...  是不是持久性,是否需要在之后调用保存/更新功能? - mhu


我相信它保存在Active Directory中。


1
2018-02-09 21:07





对于TFS2017 +,每个用户都可以在Web界面上拥有一个首选的电子邮件地址,可以在他们的个人资料中进行设置。

它可以覆盖或替换Active Directory中的电子邮件集。它还具有即时更改,无需同步的优点。

该字段将使用在Active Directory中设置的值进行初始化。似乎不再发生同步。


0
2017-07-12 18:41