2009-09-10 10 views
8

Gibt es eine Möglichkeit, einen verwaisten Benutzer in einer SQL 2005/2008-Datenbank mit SQL SMO zu reparieren?Verwaiste Benutzer mit SQL SMO reparieren?

Sie können durch Auflisten durch den Benutzer Benutzer relativ leicht verwaiste finden und auf der Suche nach einer leeren User.Login Eigenschaft:

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; 
    } 

Leider ist das Update nicht so einfach ist, die User.Login Eigenschaft auf die entsprechenden Server-Login als Einstellung Name. User.Login hat einen Setter, aber ich weiß nicht, wie ich das zurück zum Server propagieren kann. Es wird nur angezeigt, wenn Sie eine neue User erstellen.

Ich überlegte, den Benutzer aus der Datenbank zu löschen und die Server-Anmeldung erneut an die Datenbank zu binden, aber das bringt zusätzliche Komplikationen mit sich. Komplikationen wie das Neuzuweisen von Standardschemas, Rollen und, wenn sie ein eigenes Schema in der Datenbank besitzen, gibt es mehr Probleme beim Durchlaufen dieser Änderungen. Es ist genug, um Sie machen wollen, die SQL-inline und mit ihm getan werden:

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

Aber ich würde es vorziehen, nicht um einen Anruf zu einem System gespeicherten Prozedur inline.

Irgendwelche Vorschläge?

Antwort

5

Leider ist SMO nicht viel besser als SQL-DMO für die Bereitstellung von Methoden, die zur Verfügung stehen sollte. Du wirst SQL in-line verwenden:

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

oder

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

Das ist ziemlich genau das, was ich aus der Antwort von gbn und den bisherigen Kommentaren geschlossen habe: Das fühlt sich an wie eine Antwort - stehlen, aber soweit ich das beurteilen kann, ist es die richtige Antwort. – Yoopergeek

+0

Heads-up, die MSDN-Dokumentation, http://msdn.microsoft.com/en-us/library/ms174378.aspx, gibt an, dass diese Methode in zukünftigen Versionen von SQL Server entfernt wird und den Alter User, der als Yoopergeek angegeben unten funktioniert nicht mit SMO. – Despertar

2

Von T-SQL ALTER LOGIN ... WITH LOGIN = ...

LOGIN = login_name

Re-Karten einen Benutzer einen anderen Login durch die Security Identifier (SID) des Benutzers Ändern der SID Login anzupassen. Jetzt

, ich habe es nicht versucht, weil ich SIDs über Server synchronisieren würde (und selten verwenden SQL in diesen Tagen Logins)

jedoch diese Karten an die User.Alter Method.

So könnte es funktionieren ...

Wenn es nicht das gleiche Login verwenden mag, ich rechne Sie auf einem anderen Login-Karte könnte und zurück.

+1

Excellent Vorschlag. Nicht sicher, wie ich die User.Alter() -Methode verpasst habe. Es sieht jedoch so aus, als ob Sie User.Login einstellen und dann User.Alter() aufrufen. Es wird eine FailedOperationException ausgelöst, die besagt: "Alter für Benutzer 'MyOrphanedUser' ist fehlgeschlagen." Die FailedOperationException hat eine innere Ausnahme vom Typ SmoException, die besagt: "Das Ändern der Login-Eigenschaft des User-Objekts ist nicht zulässig.Sie müssen das Objekt mit der gewünschten Eigenschaft löschen und neu erstellen. "Vielleicht ist es einfach nicht möglich, die SMO-API zu deaktivieren. – Yoopergeek

+0

Entschuldigung," Ich habe es nicht versucht " – gbn

+5

einfach Smo.Database.ExecuteNonQuery (" Alter User FOO mit Login FooLogin "). – RBarryYoung