Datenbanken erstellen und SQL-Befehle absetzen mit PowerShell


    Tags: , ,

    Microsoft SQL ServerEine SQL-Daten­bank erweist sich nicht nur bei der klassischen Anwen­dungs­ent­wicklung als prak­tisch, sondern kann auch den Scripts der System­verwaltung als Speicher dienen. Microsoft stellt daher für SQL Server ein PowerShell-Modul zur Verfügung, mit dem man in die Daten­bank schreiben und daraus lesen kann.

    Im ersten Schritt sollte man, falls noch nicht vorhanden, das PowerShell-Modul SqlServer installieren. Dies kann auch auf einer Workstation oder einem Server erfolgen, auf dem keine Komponente eines SQL-Servers läuft. Dort benötigt man zwar die Server Management Objects (SMO) Libraries, sie gehören aber zum Liefer­umfang des Moduls.

    SqlServer-Modul installieren

    Dazu führt man in der PowerShell-Konsole folgenden Befehl aus:

    Install-Module -Name SqlServer

    Sollte bereits eine ältere Version vorhanden sein, so lässt sich diese mit

    Install-Module -Name SqlServer -AllowClobber

    aktualisieren.

    PowerShell-Modul SqlServer von der Konsole installieren

    Falls man über keine administrativen Rechte verfügt, kann man das Modul SqlServer auch im Kontext des aktuellen Benutzers hinzufügen:

    Install-Module -Name SqlServer -Scope CurrentUser

    Praktische Anwendung: Temporäre AD-Gruppenmitgliedschaft

    Um einen Eindruck zu vermitteln, für welche Aufgaben der SQL-Zugriff in PowerShell geeignet sein könnte, setze ich hier eine einfache Lösung für die temporäre Mitglied­schaft von Benutzern in Gruppen des Active Directory um.

    Windows Server bietet ein solches Feature bekanntlich seit der Version 2016 selbst (siehe dazu mein Script für eine PowerShell-GUI, um Benutzer vorübergehend in eine AD-Gruppe aufzunehmen). Wenn Unter­nehmen aber noch nicht bereit sind, die Gesamt- und Funktions­ebene einer Domäne auf 2016 anzuheben, dann könnte man stattdessen vorgehen wie im Folgenden beschrieben.

    Microsoft SQL Server speichert dabei die Daten der User, welche einer Gruppe temporär zugewiesen werden, sowie den dafür vorgesehenen Zeitraum. Nach Ablauf dieser Frist werden die Konten wieder aus der Datenbank entfernt.

    Mit SQL Server verbinden, DB erstellen

    Bevor man loslegen kann, muss man das Modul mit

    Import-Module SqlServer

    importieren.

    PowerShell-Modul SqlServer von der ersten Verwendung importieren

    Im ersten Schritt verbindet man sich zum SQL Server und legt eine Datenbank sowie die erforderliche Tabelle an.

    Die beiden mittleren Zeilen erzeugen ein Server- bzw. ein Database-Objekt, als Parameter werden die Namen des SQL Servers und der Datenbank mitgegeben. Anschließend wird die Datenbank erstellt.

    Damit nun Daten in die Datenbank geschrieben werden können, lege ich eine entsprechende Tabelle mit den benötigten Attributen an. Dazu formuliere ich ein SQL-Statement und übergebe dieses neben Username und Passwort an Invoke-SQLcmd.

    Je nach Anforderung kann man unter CREATE TABLE natürlich beliebige Spalten anlegen. Nun lassen sich Daten in die Datenbank schreiben und wieder auslesen. Dies kann wie folgt geschehen:

    In meinem Beispiel bekommt der Benutzer mit der Variable $timetolive ein Zeitfenster von zwei Stunden ($timetolive), währenddessen er die ent­sprechenden Gruppen­berechtigungen nutzen darf. Dieser Wert ist natürlich beliebig anpassbar. Ich würde aber immer empfehlen, diesen auf Stundenbasis zu vergeben, auch dann, wenn der User diese Berechtigung vielleicht auch für Tage oder Woche behalten darf.

    Add-ADGroupMember nimmt dann den User in die gewünschte Gruppe auf. Gleichzeitig über­nehmen wir diesen Vorgang in unsere SQL-Datenbank. Wenn man den Beispiel-Code in ein produktiv genutztes Script aufnimmt, dann sollte man natürlich den Erfolg von Add-ADGroupMember prüfen, bevor man in die Datenbank schreibt.

    Möchten wir nun sehen, was wir mit unserem vorherigen Befehl in die Datenbank geschrieben haben, dann ist dies mit folgendem Befehl möglich:

    $SQLOutput = read-sqltabledata -ServerInstance 'EX01.firma.local' `
    -Databasename powershellDB -schemaname "dbo" -tablename "Users" `
    -columnname Benutzername,Zeit,Gruppe -outputas datatable

    Inhalt der Datenbank ausgeben

    Wir erkennen, dass unser Beispiel­benutzer die Berechtigungen einer Gruppe erhalten hat und wir sehen den Zeitstempel, für wie lange die Mitgliedschaft der Gruppe gültig wäre.

    Eintrag aus der Datenbank löschen

    Nun wird der User aber nicht wie unter Server 2016 automatisch aus der Gruppe entfernt, wenn die gesetzte Zeit verstrichen ist. Hierfür kann der Administrator sich jedoch eine geplante Aufgabe bauen, um eine gewisse Automatisierung zu erzielen.

    Für solche Fälle eignet sich eine Foreach-Schleife, weil davon auszugehen ist, dass die Tabelle später im praktischen Einsatz mehrere Benutzer enthalten wird, die irgendwelche Gruppen­berechtigung mit unter­schiedlichen Zeit­stempeln bekommen haben.

    Auch hier sind wieder 2 Aktionen erforderlich. Zum einen muss die Mitglied­schaft in der Gruppe des Active Direktory beendet werden, zum anderen muss der Eintrag in der SQL-Datenbank diese Aktion widerspiegeln. Ich habe mich in diesem Beispiel dazu entschieden, den Benutzer aus der Datenbank zu löschen.

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Roland Eich

    Roland Eich ist gelernter Fach­infor­matiker für System­inte­gration und in der IT seit über 14 Jahren zu Hause. Roland deckt auf­grund seiner Erfah­rungen ein breites Spek­trum der Microsoft-Produkt­palette ab.
    Zudem besitzt er ver­schiedene Zertifi­zierungen (MCITP, MCSA und MCSE, ITIL, PRINCE2).

    // Kontakt: E-Mail //

    Verwandte Beiträge

    Weitere Links

    5 Kommentare

    Hallo,

    ich erhalte schon im 1. Schritt folgenden Fehlermeldung .. was mache ich falsch?

    Danke und viele Grüße Nobby

    new-object : Ausnahme beim Aufrufen von ".ctor" mit 2 Argument(en): "Fehler bei SetParent von Datenbank "powershellDB". "
    In F:\dbtest.ps1:5 Zeichen:16
    + ... tabaseObj = new-object Microsoft.SqlServer.Management.Smo.Database ($ ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

    Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
    In F:\dbtest.ps1:6 Zeichen:1
    + $databaseObj.Create()
    + ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Guten Morgen,
    dazu müsste man mal sehen was bei Ihnen im Script genau steht.
    Teilen Sie dies doch gerne einmal mit uns.
    Grüße
    Roland Eich

    Ooops, das ging schnell :)

    #
    import-module sqlserver
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
    $serverObj = new-object Microsoft.SqlServer.Management.Smo.Server("EX01.firma.local")
    $databaseObj = new-object Microsoft.SqlServer.Management.Smo.Database ($serverObj, "powershellDB")
    $databaseObj.Create()

    Danke und Gruß Nobby

    Ist der Name so richtig? EX01.firma.local heißt Ihr SQL Server so?
    Grüße
    Roland Eich

    (Schäm)
    Sorry, man sollte auch nicht einfach so "copy und paste" machen sondern auch (versuchen) zu verstehen was da gemacht wird. Wobei mich "Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat" ratlos gemacht hat

    Läuft jetzt!

    Danke und viele Grüße Nobby