SSIS: Benutzer-Import aus einem Active-Directory
avatar

Viele Business-Anwendungen verfügen über ein Berechtigungsmodell basierend auf Gruppen und Benutzern, um bestimmte Anwender für verschiedene Funktionen freizuschalten.
Gerade im Unternehmensumfeld existieren diese Benutzer und Gruppen meist auch schon innerhalb des Active-Directory.
Eine Importfunktion für diese Benutzer und Gruppen spart in einem solchen Fall eine Menge Verwaltungsaufwand.

Um nun die Einträge vom Active Directory in die Datenbank zu kopieren gibt es 3 mögliche Ansätze, von denen bei meinen Tests jedoch nur einer funktionierte:

  • Verwendung eines Linked Server via „OpenQuery()“
  • Erstellen einer ADO.NET-Datenquelle, bei der als Provider „OLE DB Provider for Microsoft Directory Services“ ausgewählt wird
  • Erstellung eines Skript-Tasks

Nachdem die Methode „Linked-Server“ bei mir mit einer Fehlermeldung „Server not found“ fehlschlug, probierte ich die Variante über die Datenquelle aus.
Obwohl zur Design-Time und in der Query-Vorschau noch alles sehr vielversprechend aussah, musste ich beim Ausführen leider feststellen, dass SSIS den Dienst mit einem „Failure without Error-Message“ quittierte.

Ob diese Fehler an einer speziellen Konfiguration meines Active Directory lagen oder eine andere Ursache hatten konnte ich leider nicht feststellen.

Die nachfolgend beschriebene Erstellung des Skript-Tasks führte bei mir  zum Erfolg.

Vorgehen

Innerhalb eines Datenflusstask wird die Skriptkomponente auf die Arbeitsfläche gezogen, als Komponententyp muss „Quelle“ ausgewählt werden.

skriptkomp3

Als nächstes wird in diesem Datenflusstask eine neue Variable namens „AD_Server“ angelegt, diese speichert die URL des verwendeten Active-Directory-Servers:

var

Nach einem Doppelklick auf die Skriptkomponente gelangt man in deren Einstellungen.
Hier müssen die Sprache (in meinem Fall C#) und als ReadOnly-Variable die zuvor angelegte „Ad_Server“-Variable ausgewählt werden.

Nach einem Klick auf „Skript bearbeiten“ gelangt man in eine Entwicklungsumgebung.

In der Klasse “ScriptMain” die von “UserComponent” abgeleitet ist, werden 3 Methoden überschrieben.
Die Namen der Methoden “PreExecute()”, “PostExecute()” und “CreateNewOutputRows()” dürften selbsterklärend sein.

Für unsere Zwecke benötigen wir die Methode “CreateNewOutputRows()“ in der Code eingefügt werden muss.
Das Gesamtskript enthält dann:

  1. using System; 
  2. using System.Data; 
  3. using Microsoft.SqlServer.Dts.Pipeline.Wrapper; 
  4. using Microsoft.SqlServer.Dts.Runtime.Wrapper; 
  5. using System.DirectoryServices.AccountManagement; 
  6. using System.DirectoryServices; 
  7. using System.Collections.Generic; 
  8.  
  9. [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] 
  10. public class ScriptMain : UserComponent 
  11.     public override void PreExecute() 
  12.     { 
  13.         base.PreExecute(); 
  14.     } 
  15.  
  16.     public override void PostExecute() 
  17.     { 
  18.         base.PostExecute(); 
  19.     } 
  20.  
  21.     public override void CreateNewOutputRows() 
  22.     { 
  23.         // Active-Directory-Context erzeugen 
  24.         string domain = this.Variables.ADServer; 
  25.         using (PrincipalContext ctx =
  26.                new PrincipalContext(ContextType.Domain, domain)
  27.         ) 
  28.         { 
  29.             // Liste der Gruppen aus denen Benutzer geholt werden sollen 
  30.             List<string> groups = new List<string>(); 
  31.             groups.Add(„U-GROUP1“); 
  32.             groups.Add(„U-GROUP2“); 
  33.              
  34.             // Pro Gruppe 
  35.             foreach (string group in groups) 
  36.             { 
  37.                 // …Mitglieder aus dieser Gruppe holen 
  38.                 GroupPrincipal gp = GroupPrincipal.FindByIdentity(ctx, group); 
  39.                 PrincipalSearchResult<Principal> members = gp.GetMembers(); 
  40.  
  41.                 // Daten jedes Mitarbeiters holen 
  42.                 foreach (Principal result in members) 
  43.                 { 
  44.                     // Daten in OutputBuffer speichern 
  45.                     Output0Buffer.AddRow(); 
  46.                     Output0Buffer.memberOf = group; 
  47.  
  48.                     DirectoryEntry de =
  49.                         (DirectoryEntry)result.GetUnderlyingObject();
  50.                     Output0Buffer.sn = de.Properties[„sn“].Value.ToString(); 
  51.                     Output0Buffer.givenName =
  52.                         de.Properties[„givenName“].Value.ToString(); 
  53.                     Output0Buffer.sAMAccountName =
  54.                         de.Properties[„samAccountName“].Value.ToString(); 
  55.                 } 
  56.             } 
  57.         } 
  58.     } 
  59.  
Der Code gliedert sich im Grunde in folgende Schritte:

– Zeile 25-28:
Active-Directory-Context erzeugen, mit dem der Zugriff auf die Gruppen und Benutzer erfolgt

– Zeile 31-33:
Liste der Gruppen erstellen aus denen Benutzer geholt werden sollen

– Zeile 36:
Mitglieder aus der aktuellen Gruppe holen

– Zeile 38-59:
Daten des Mitarbeiters aus dem jeweiligen Schleifendurchlauf holen und in die Output0Buffer-Variable schreiben

Nachdem dieses Skript erstellt und kompiliert wurde, sind im Eigenschaften-Fenster unter dem Tab „Eingaben und Ausgaben“ die Ausgabespalten aus den Zeilen 47 bis 58 zu sehen.

Die von der Skriptkomponente gelieferte Ausgabe kann nun auf dem üblichen Weg im SSIS-Datenflusstask weiterverarbeitet werden.

Fazit und Ausblick

Für meine Aufgabe stellt die Erstellung des Skripttasks eine schnelle und einfache Möglichkeit dar, bestehende AD-Benutzer mit der Anwendung zu synchronisieren.
Aufgrund der aktuellen Gruppe der Benutzer konnte ich so spezielle Berechtigungen in meiner User-Tabelle setzen.

Links zum Thema

1. http://dataqueen.unlimitedviz.com/2012/09/get-around-active-directory-paging-on-ssis-import/

2 Gedanken zu “SSIS: Benutzer-Import aus einem Active-Directory
avatar

  1. Pingback: SSIS: Benutzer-Import aus einem Active-Directory - SharePoint Blogs in German - Bamboo Nation

Schreibe einen Kommentar