使用 SQL SMO 修复孤立用户?

Posted

技术标签:

【中文标题】使用 SQL SMO 修复孤立用户?【英文标题】:Fixing Orphaned Users with SQL SMO? 【发布时间】:2010-11-27 06:51:09 【问题描述】:

有没有办法使用 SQL SMO 修复 SQL 2005/2008 数据库中的孤立用户?

通过枚举用户并查找空的User.Login 属性,您可以相对容易地找到孤立用户:

using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;    
public static IList<string> GetOrphanedUsers(Server smoServer, string database) 
       Database db = smoServer.Databases[database];

       List<string> orphanedUsers = new List<string>();
       foreach (User user in db.Users) 
          if (!user.IsSystemObject && user.Login == string.Empty) 
             orphanedUsers.Add(user.Name);
          
       

       return orphanedUsers;
    

不幸的是,修复并不像将User.Login 属性设置为匹配的服务器登录名那么简单。 User.Login 确实有一个 setter,但我不知道有一种方法可以将它传播回服务器。它仅在您创建新的User 时才可用。

我考虑从数据库中删除用户并将服务器登录重新绑定到数据库,但随之而来的是额外的复杂性。诸如重新分配默认架构、角色以及如果他们在数据库中拥有架构等复杂情况,当您通过这些更改进行级联时,您会遇到更多麻烦。足以让您想要内联 SQL 并完成它:

ServerConnection server = new ServerConnection("MyBox\SQLInstance");
Database db = server.Databases["MyDatabase"];
db.ExecuteNonQuery("sp_change_users_login 'auto_fix', 'ORPHANED_USERNAME'")

但是,我不希望内联对系统存储过程的调用。

有什么建议吗?

【问题讨论】:

【参考方案1】:

不幸的是,在提供应该可用的方法方面,SMO 并不比 SQL-DMO 好多少。您将不得不使用内联 SQL:

db.ExecuteNonQuery("sp_change_users_login 'auto_fix', 'ORPHANED_USERNAME'")

db.ExecuteNonQuery("sp_change_users_login 'update_one', 'ORPHANED_USERNAME', 'ORPHANED_USERNAME'")

【讨论】:

这几乎就是我从 gbn 的回答和迄今为止的 cmets 得出的结论。这感觉像是在偷答案,但据我所知,这是正确的答案。 请注意,MSDN 文档msdn.microsoft.com/en-us/library/ms174378.aspx 指出,此方法将在 SQL Server 的未来版本中删除,并用于使用 Alter 用户,正如 Yoopergeek 下面所述SMO。【参考方案2】:

来自 T-SQL ALTER LOGIN ... WITH LOGIN = ...

登录 = 登录名

将用户重新映射到 通过更改用户的另一个登录 安全标识符 (SID) 以匹配 登录的 SID。

现在,我还没有尝试过,因为我会跨服务器同步 SID(现在很少使用 SQL 登录)

但是,这映射到User.Alter Method。

所以,它可能会起作用......

如果它不喜欢使用相同的登录名,我认为您可以映射到另一个登录名并返回。

【讨论】:

很好的建议。不知道我是如何错过 User.Alter() 方法的。但是,它看起来像设置 User.Login,然后调用 User.Alter() 是不允许的。它抛出一个 FailedOperationException 说明:“用户 'MyOrphanedUser' 的更改失败。” FailedOperationException 有一个 SmoException 类型的内部异常,它声明:“不允许修改 User 对象的 Login 属性。您必须删除并重新创建具有所需属性的对象。”也许根本不可能通过 SMO API 解除孤儿? 只做 Smo.Database.ExecuteNonQuery("Alter User FOO With Login FooLogin"). 这就是我最初希望避免的——将 SQL 内联到数据库中。但是,这就是我最终选择的路线。但是,我使用的是我提到的问题的“sp_change_users_login”系统存储过程。【参考方案3】:

对我来说,这个语法很好用

    db.ExecuteNonQuery("sp_change_users_login 'Auto_Fix', 'login_from_Report', NULL, 'p@ssword123!'")

我在这里找到它:http://dbadiaries.com/using-sp_change_users_login-to-fix-sql-server-orphaned-users#sthash.Q85ewEr9.dpuf

【讨论】:

以上是关于使用 SQL SMO 修复孤立用户?的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver孤立用户解决

sql server中的孤立用户

SQL Server数据库中还原孤立用户的方法集合

用sp_change_users_login消除Sql Server的孤立用户

SQL Server孤立账户解决办法

使用 Powershell 清理孤立的 Active Directory 用户配置文件文件夹