Daten per PowerShell aus einer Oracle Datenbank als XML ausgeben und mit Active Directory abgleichen

In diesem Beitrag möchte ich zeigen, wie man Daten aus einer Datenbank liest und das Abfrageergebnis als Dokument speichert. Dieses Dokument soll dann dazu genutzt werden, einzelne Benutzerattribute im zu aktualisieren und somit die richtige Datenbasis für den Organisationsbrowser zu schaffen.

Ich habe dies per realisiert und kann somit das Script per geplanten Task (Windows Aufgabenplanung) ausführen.

Das folgende Szenario ist die Grundlage: Ein Unternehmen pflegt seine Benutzerdaten in einer Oracle Datenbank. Diese Daten werden ständig aktualisiert und sollen nun ausgelesen, als XML Dokument gespeichert und mit dem Active Directory (AD) abgeglichen werden. Interessant sind dabei also besonders die Daten Manger, also wer ist der Vorgesetzte der Person und außerdem noch der Wert Abteilung. Für jeden Mitarbeiter aus der Oracle Datenbank soll im AD der Vorgesetze und die Abteilung gesetzt werden. Somit kann im Nachhinein auch der Organisationsbrowser in SharePoint ordentlich genutzt werden.

Für das bessere Verständnis, habe das Ganze in zwei Schritten realisiert. Im ersten Schritt werden diese Daten aus Oracle gelesen und in ein XML Dokument gespeichert. Im zweiten Schritt greift ein anderes PowerShell Script auf dieses XML Dokument zu, liest die Daten und aktualisiert das Active Directory.

Voraussetzung: Für die Datenbankabfrage muss ein Oracle Treiber installiert sein. Diesen gibt es in Version 32bit und 64bit. Im diesem Szenario ist auf Server 1 der 32bit-Oracle-Treiber installiert.

Hinweis: Sollte der Oracle 32bit Treiber installiert sein, so muss auch PowerShell als 32bit Version genutzt werden. Die PowerShell Versionen findet man in folgenden Verzeichnissen:

  • 32-bit PowerShell    
    C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
  • 64-bit PowerShell    
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Teil 1 und Script 1 – Daten per PowerShell aus Oracle lesen und als XML speichern:

Für die Abfrage der Daten aus Oracle-DB als XML nutze ich das Package dbms_xmlgen und hole die Daten per Funktion getxml als XML aus der Datenbank.

Da ich für mein Script ohnehin PowerShell nutze, werde ich dort die Abfrage einbauen und das Abfrageergebnis (XML) auch gleich in eine Datei schreiben.

$connDataSource = „Data Source=//TestServer:1521/Personal.Testserver“
$connID = „USER ID=MyUserID“
$connPW = „Password=MyPassword“
$connSecurity = „Integrated Security=no“
$global:outDatei = „d:\ora.xml“
# Für die Verbindung wird der Oracle Data Provider für .NET benötigt
# Wenn dieser Installiert ist, dann braucht er nur noch geladen werden
# Entweder lädt man ihn direkt aus dem folgenden Verzeichnis:
# C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0
# oder man legt die DLL mit in das Scriptverzeichnis, so wie hier
[Reflection.Assembly]::LoadFile(„d:\System.Data.OracleClient.dll“)
# alternativ geht es auch so:
# [System.Reflection.Assembly]::LoadWithPartialName(„System.Data.OracleClient“)

# folgende Funktion erstellt eine Datei mit XML-Inhalt
# XML-Inhalt wird beim Aufruf an diese Funktion übergeben und in Datei geschrieben
function createXML($inhalt) {
$inhalt | Out-File $global:outDatei -Encoding ASCII
}
# Connection-String für die Verbindung zu Oracle
$connectionString = „$connDataSource; $connID; $connPW; $connSecurity“
# Verbindung zu Oracle erstellen
$connection = New-Object System.Data.OracleClient.OracleConnection($connectionString)
# Abfrage erstellen
$queryString = „select dbms_xmlgen.getxml (’select Name, Vorname, UserID, abt_bez as „“ABT-BEZ““, abt as Abteilung, ManagerID, from Personal.v_person‘) xml from dual“
# Abfrage mit der Oracle-Verbindung verknüpfen
$command = new-Object System.Data.OracleClient.OracleCommand($queryString, $connection)
# Oracle-Verbindung öffnen
$connection.Open()
# Daten abfragen und in Variable $users schreiben
$users = $command.ExecuteScalar()
# Funktion createXML aufrufen und Daten übergeben
createXML($users)
# Oracle-Verbindung schließen
$connection.Close()
# Variable $users leeren
Clear-Variable -Name users

Teil 2 und Script 2 – Daten per PowerShell aus XML lesen und mit Active Directory abgleichen:

Mit dem zweiten Script importiere ich die Daten aus der XML-Datei erst einmal in ein Array. Diesen Zwischenschritt muss man nicht machen. Ich brauchte dies aber an anderer Stelle und habe hier gleich mit integriert. So lernt man nebenbei noch die Arbeit mit einem Array kennen 😉

Nach dem Import der XML-Daten in das Array, sortiere ich die Werte im Array aufsteigend nach Feld Abteilung (Index 2) und gebe das sortierte Array wieder in ein neues Array aus. Achten Sie darauf, dass der Index bei 0 beginnt.

Das gefüllte Array gleiche ich dann mit dem Active Directory ab, wobei ich als Schlüsselfeld aus dem XML Dokument das Attribut UserID und im AD das Attribut sAMAccountName nutze. Für jeden User, der aus dem XML Dokument kommt, wird der Manager (AD-Attribut manager) und die Abteilung (AD-Attribut department) geschrieben.

Nachdem die Attributwerte im Active Directory nun gesetzt sind, starte ich die Profilsynchronisierung der Benutzerprofile auf dem SharePoint Server. Nach der Synchronisierung zeigt mir der Organisationsbrowser jetzt auch zu jedem Mitarbeiter den Vorgesetzten und die Abteilung an.

# Active-Directory-Modul in PowerShell laden
Import-Module ActiveDirectory
# Variablen initialisieren
$nL = [Environment]::NewLine # Variable für Zeilenumbruch definieren
$xmlDatei = „d:\ora.xml“ # Pfad + Datei für Ausgabe festlegen
$arr = @() # dynamisches Array erstellen
# XML-Datei einlesen
# der Cast-Operator [xml] liest die XML-Datei auch als XML-Dokument ein
# und bietet dadurch einen einfachen Zugriff auf die Elemente
[xml]$users = Get-Content $xmlDatei
# Daten in das Array ausgeben
foreach ($user in $users.ROWSET.ROW) {
$Name = $user.NAME
$Vorname = $user.VORNAME
$Abt = $user.ABTEILUNG
$UserID = $user.USERID
$AbtBez = $user.“ABT-BEZ“
$ManID = $user.MANAGERID
# Array füllen – jeden Datensatz an das Array anhängen
$arr += ,@($Name, $Vorname, $Abt, $UserID, $ManID, $AbtBez)
}
# Array nach Abteilung sortieren und in neues Array schreiben
$arr_by_abt = $arr | Sort-Object @{expression={$_[2]};Ascending=$true}
# neues, sortiertes Array auslesen
ForEach($ma in $arr_by_abt) {
# Variablen für Werte aus dem Array
$SAN = $ma[3] # SamAccountName User
$MID = $ma[4] # SamAccountName Manager
$ABT = $ma[2] # Department
# Attribute für den aktuell gelesenen User im AD ändern
Set-aduser identity $SAN -manager $MID -Department $ABT
}

Man kann im Script natürlich noch einiges vereinfachen. Aus Gründen der Übersicht habe ich aber bewusst darauf verzichtet.

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.