Desired State Configuration #2 – Erste Schritte zur SQL Server Installation

Unsplash.com - Photo by Alex Jones

EDIT:
Falls ihr nach einer fertigen Lösung sucht, bitte geduldet euch… ich erläutere hier meinen Projekt-Verlauf, wie ich wann wie vorgegangen bin… als letzten Blogbeitrag werde ich die „fertige“ Lösung vorstellen.

Vielen Dank für euer Verständnis

Nach meinem ersten Beitrag – den Vorbereitungen zur Nutzung von Desired State Configuration (DSC) – kann man nun die erste Schritte zur Installation eines SQL Servers einleiten. Was benötigen wir also für Voraussetzungen für die Installation eines SQL Servers auf einem neuen Windows Server?

Zu meiner Test-Umgebung… ich nutze für die Entwicklung meiner Skripte in diesem Fall eine Dev-Umgebung in Azure bestehend aus mindestens zwei Windows Servern. Ich nutze einen Server als Domänencontroller und die zweite Maschine als SQL Server, um hier meine Skripte zu testen und die Funktion zu testen. Einen oder mehrere Server kann und werde ich nach Bedarf ausrollen, um eben meine Demos zu halten bzw meine Skripte zu entwickeln und testen.

Entwicklungs-Umgebung für Ola Hallengren und Powershell-Skripte

Voraussetzungen für die Installation

Um eine einfache SQL Server Installation – im Sinne meines Kunden-Projektes – auf einem neuen Server durchzuführen benötigen wir dreierlei Dinge:

  • .NET Framework 4.5 (Minimum)
  • Installations-Medium SQL Server 2017 Standard Edition
  • und das letzte Update im Sinne des letzten Cumulative Updates

Um das Installations-Medium auf dem neuen Server bereitzustellen, bedarf es mindestens eines Ordner auf irgendeinem Laufwerk. Nun gibt es mehrere Möglichkeiten diesen Ordner bereitzustellen…

  • manuelle Anlage des Ordners
  • Anlage des Ordners mittels DSC
  • Anlage des Ordners mittels Powershell

Da wir ins diesem Projekt, dieser Beitragsserie bestrebt sind alles zu automatisieren, fällt natürlich das manuelle Anlegen des Ordners weg. Je nach dem wie man vorgehen möchte, welche Voraussetzungen man erfüllen muss/möchte bzw in welcher Reihenfolge man vorgehen möchte, kann man nun wählen zwischen Desired State Configuration oder Powershell. In diesem Projekt möchte ich darstellen, wie man nun zur erst auf dem Zielserver ein entsprechendes Verzeichnis anlegt und dann dort mit einfachen Mitteln das Installationsmedium ablegt.

Anlage des Ordners mit Powershell

Um mein Vorhaben zu realisieren, müsste ich theoretisch erst eine Desired State-Configuration für die Folder-Anlage erstellen sowie implementieren und die Kopier-Aktion starten, dann die eigentliche Installation starten, das versuche ich erst in einem zweiten Schritt, jetzt starte ich mit der „einfacheren“ Vorgehensweise. Dazu nutze ich das „Invoke-Command“ und prüfe ob der Ordner auf dem Zielserver vorhanden ist oder nicht, wenn nicht wird der Ordner neu angelegt.

Invoke-Command -ComputerName $NodeName -ScriptBlock { 
param ($LocalInstallFolder)
if (!(Test-Path -Path $LocalInstallFolder )) {
    New-Item -ItemType directory -Path $LocalInstallFolder | Out-Null
} else {
    Remove-Item -Recurse -Force $LocalInstallFolder
    New-Item -ItemType directory -Path $LocalInstallFolder | Out-Null
} -ArgumentList "D:\$LocalInstallFolder\"

Warum lösche ich erst das Zielverzeichnis? Na klar, wenn ich das Skript mehrfach ausführe, dann muss immer das aktuelle Installationsmedium und das aktuelle Update dort bereit liegen, daher wird erst einmal das Verzeichnis gelöscht, um dann neu erstellt zu werden.
Wenn die Ziel-Verzeichnisse vorhanden sind, dann kann man die benötigeten Dateien/Verzeichnisse kopieren.

Kopieren des Installationsmediums

Anfänglich hatte ich meine Dateien alle mit „Copy-Item“ vom Netzlaufwerk auf den Zielserver kopiert, da ich aber doch recht viel mit der Powershell ISE entwickel, fehlte mir eine „Fortschrittsanzeige“… daher bin ich später auf „Start-BitsTransfer“ umgestiegen.

Write-host "Copy SQL-Image to"$NodeName.ToUpper()
$DestinationPath = "\\$NodeName\d$\$LocalInstallFolder\"
Start-BitsTransfer -Source ..\SQL\* -Destination $DestinationPath -Description "..\SQL\* will be moved to $DestinationPath" -DisplayName "Copy SQL-Image" 
Start-BitsTransfer -Source ..\SQL\Updates\* -Destination "$DestinationPath\Updates\" -Description "..\SQL\Updates\* will be moved to $DestinationPath" -DisplayName "Copy SQL-Updates" 

Aber das war mir dann irgendwie auch zu aufwendig und kompliziert, so irgendwie „Work-around“… aber zu mindestens funktionierte es 😉 Genauso bin ich vorgegangen, als die notwendigen Powershell-Module auf den Zielserver kopiert habe. Aber mit jedem Tag und jedem weiteren Versuch sich mit Desired State Configuration auseinanderzusetzen, lernt man dazu.
So bin ich jetzt dazu übergegangen auch dieses vorbereitende Kopieren mittels DSC zu realisieren.

Configuration CopyInstallationMedia
{
    Node $AllNodes.where{ $_.Role.Contains("SqlServer") }.NodeName
    {
        File InstallationFolder 
        {
            Ensure = 'Present'
            Type = 'Directory'
            SourcePath = "\\dc1\NetworkShare\SQL\"
            DestinationPath = "D:\SQL2017\"
            Recurse = $true
        }
    
        File PowershellModules 
        {
            Ensure = 'Present'
            Type = 'Directory'
            SourcePath = "\\dc1\NetworkShare\Modules\"
            DestinationPath = "C:\Windows\system32\WindowsPowerShell\v1.0\Modules\"
            Recurse = $true
        }
    }
}

Clear-Host
$OutputPath = "\\dc1\DSC-ConfigShare"
CopyInstallationMedia -OutputPath "$OutputPath\CopyInstallationMedia\"    

Start-DscConfiguration -ComputerName sqlvm02 -Path \\DC1\DSC-ConfigShare\CopyInstallationMedia -Wait -Verbose -Force

Aufbau meiner DSC-Konfigurationen

Ich habe mir zwecks besserer Übersicht und vereinfachtem, schrittweisem Ausprobieren sowie Nachvollziehbarkeit mehrere Abschnitte in meiner Desired-State-Configuration angelegt. Die jeweilige Konfiguration kann ich nun gezielt und einzeln aufrufen und „verfeinern“.

Configuration CopyInstallationMedia
{
    Node $AllNodes.where{ $_.Role.Contains("SqlServer") }.NodeName
    {
        File InstallationFolder 
        {
            ...
        }

        File PowershellModules 
        {
            ...
        }

        Configuration ConfigureSQL
        {
            ...
        }
}

Natürlich bedarf es auch einiger Parameter, die man nicht ungeachtet lassen darf, diese werden eingangs des Skriptes definiert. In meinen Fall benötige ich zur Installation und späteren Konfiguration zumindest den Pfad wo die Installationsmedien zentral abgelegt werden und den Zielserver, wo die DSC-Konfiguration ausgerollt werden soll.

param
(
    # Path where all Install media will be located
    [Parameter(Mandatory=$true)]
    [String]
    $InstallPath,

    # Computer name to install SQL Server On
    [Parameter(Mandatory=$true)]
    [String]
    $ComputerName
)

Nachdem ich nun die Konfiguration unterteilt und definiert habe, kann ich notwendige Skripte bzw Module hinzufügen und das Erstellen der MOF-Files einleiten. Anhand dieser MOF-Files wird dann die IST-Konfiguration mit der SOLL-Konfiguration abgeglichen und entsprechend korrigiert. Da sich zwischen letztmaligen Erstellen der MOF-Files und „Jetzt“ etwas an der SOLL-Konfiguration geändert haben könnte, lasse ich sicherheitshalber immer die Files neu erstellen, um diese direkt im Anschluss auf den Zielserver auszurollen. Zur näheren Erläuterung meines Skript-Abschnittes… Ich rufe die jeweilige Konfiguration auf, weise ihr eine Konfigurationsdatei hinzu und definiere einen Pfad für die Ablage der MOF-Files. Als Abschluss wird die jeweilige SOLL-Konfiguration vom zentralen Ablageort auf den Zielserver ausgerollt.
Wie man nun auch nachvollziehen kann, bin ich in der Lage die einzelnen Schritte auch separat für Debug-Zwecke auszuführen, entweder manuell nacheinander oder nur einzelne Konfigurationen wie zum Beispiel die bloße Konfiguration eines SQL Servers.

Write-host "Starting DSC process on"$NodeName.ToUpper()
Import-Module $PSScriptRoot\ConfigureSQLServer.psm1 -Force

## Create MOF-Files
$OutputPath = "\\dc1\DSC-ConfigShare"
CopyInstallationMedia -ConfigurationData \\dc1\NetworkShare\scripts\configData.psd1 -OutputPath "$OutputPath\CopyInstallationMedia\"
SQLInstall -ConfigurationData \\dc1\NetworkShare\scripts\configData.psd1 -OutputPath "$OutputPath\SQLInstall\"
ConfigureSQL -ConfigurationData \\dc1\NetworkShare\scripts\configData.psd1 -OutputPath "$OutputPath\SQLConfig\"

## Use MOF-Files to establish desired state configuration
Start-DscConfiguration -ComputerName $Computername -Path \\DC1\DSC-ConfigShare\CopyInstallationMedia -Wait -Verbose -Force     
Start-DscConfiguration -ComputerName $Computername -Path \\DC1\DSC-ConfigShare\SQLInstall -Wait -Verbose -Force     
Start-DscConfiguration -ComputerName $Computername -Path \\DC1\DSC-ConfigShare\SQLConfig -Wait -Verbose -Force

So sieht dann meine Ordner-Struktur bzw Datei-Struktur auf dem zentralen Server aus, für jede SOLL-Konfiguration gibt es einen Ordner und für jeden Zielserver eine einzelne Datei.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

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