bin/Public/Install-sqmOlaMaintenanceSolution.ps1
|
<#
.SYNOPSIS Installiert oder aktualisiert Ola Hallengrens Maintenance Solution auf einer SQL Server-Instanz. .DESCRIPTION Laedt die neueste Version der Maintenance Solution von GitHub herunter (https://github.com/olahallengren/sql-server-maintenance-solution/archive/refs/heads/main.zip), extrahiert die benoetigten Skripte und fuehrt sie in folgender Reihenfolge aus: 1. CommandExecute.sql 2. CommandLog.sql 3. DatabaseBackup.sql 4. DatabaseIntegrityCheck.sql 5. IndexOptimize.sql Die Installation erstellt ausschliesslich die Datenbankobjekte (Tabellen, Prozeduren), aber keine SQL Agent Jobs. Die Jobs werden spaeter mit den dafuer vorgesehenen Funktionen (z.?B. New-sqmOlaBackupJobs) erstellt. Vorhandene Installationen werden mit -Force / -Update ueberschrieben. .PARAMETER SqlInstance SQL Server-Instanz (Standard: aktueller Computername). .PARAMETER SqlCredential PSCredential fuer die Verbindung. .PARAMETER SourcePath Alternative Quelle fuer das ZIP-Archiv. Standard: GitHub-ZIP. .PARAMETER Force Vorhandene Installation ignorieren und neu installieren. .PARAMETER Update Alias fuer -Force. .PARAMETER ContinueOnError Bei Fehler mit naechster Instanz fortfahren. .PARAMETER EnableException Ausnahmen sofort ausloesen. .PARAMETER Confirm Bestaetigung vor der Installation anfordern. .PARAMETER WhatIf Zeigt, was passieren wuerde, ohne aenderungen vorzunehmen. .EXAMPLE Install-sqmOlaMaintenanceSolution -SqlInstance "SQL01" .EXAMPLE Install-sqmOlaMaintenanceSolution -SqlInstance "SQL01" -Force .NOTES Voraussetzungen: dbatools, Invoke-sqmLogging, Test-sqmOlaInstallation. Die Funktion laedt das ZIP-Archiv herunter und bereinigt alle temporaeren Dateien selbststaendig. #> function Install-sqmOlaMaintenanceSolution { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'None')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [string[]]$SqlInstance = @($env:COMPUTERNAME), [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$SqlCredential, [Parameter(Mandatory = $false)] [string]$SourcePath = "https://github.com/olahallengren/sql-server-maintenance-solution/archive/refs/heads/main.zip", [Parameter(Mandatory = $false)] [switch]$Force, [Parameter(Mandatory = $false)] [switch]$Update, [Parameter(Mandatory = $false)] [switch]$ContinueOnError, [Parameter(Mandatory = $false)] [switch]$EnableException ) begin { $functionName = $MyInvocation.MyCommand.Name if (-not (Get-Module -ListAvailable -Name dbatools)) { $errMsg = "dbatools-Modul nicht gefunden." Invoke-sqmLogging -Message $errMsg -FunctionName $functionName -Level "ERROR" throw $errMsg } $effForce = $Force -or $Update $allResults = [System.Collections.Generic.List[PSCustomObject]]::new() # SQL-Dateien in der benoetigten Reihenfolge $scriptFiles = @( "CommandExecute.sql", "CommandLog.sql", "DatabaseBackup.sql", "DatabaseIntegrityCheck.sql", "IndexOptimize.sql" ) } process { foreach ($instance in $SqlInstance) { $connParams = @{ SqlInstance = $instance } if ($SqlCredential) { $connParams['SqlCredential'] = $SqlCredential } $instanceResult = [PSCustomObject]@{ SqlInstance = $instance SourceUsed = $null Status = 'Unknown' Message = $null ExistingOla = $false Action = $null } try { Invoke-sqmLogging -Message "[$instance] Pruefe Ola-Installation ..." -FunctionName $functionName -Level "INFO" # Pruefen, ob Ola bereits installiert ist $olaCheck = Test-sqmOlaInstallation -SqlInstance $instance -SqlCredential $SqlCredential -RequiredSet Backup $instanceResult.ExistingOla = $olaCheck.IsInstalled if ($olaCheck.IsInstalled -and -not $effForce) { $msg = "Ola Maintenance Solution ist bereits installiert (gefunden: $($olaCheck.PresentObjects -join ', ')). Verwenden Sie -Force zum ueberschreiben." Invoke-sqmLogging -Message "[$instance] $msg" -FunctionName $functionName -Level "INFO" $instanceResult.Status = 'AlreadyInstalled' $instanceResult.Message = $msg $allResults.Add($instanceResult) continue } # Temporaeres Verzeichnis fuer Download und Extraktion $tempDir = Join-Path $env:TEMP "OlaInstall_$(Get-Random)" $zipFile = Join-Path $tempDir "main.zip" New-Item -ItemType Directory -Path $tempDir -Force | Out-Null try { # ZIP herunterladen Invoke-sqmLogging -Message "[$instance] Lade Ola-Skripte von $SourcePath herunter ..." -FunctionName $functionName -Level "INFO" Invoke-WebRequest -Uri $SourcePath -OutFile $zipFile -UseBasicParsing -ErrorAction Stop $instanceResult.SourceUsed = $SourcePath # ZIP extrahieren Invoke-sqmLogging -Message "[$instance] Extrahiere ZIP-Archiv ..." -FunctionName $functionName -Level "INFO" Expand-Archive -Path $zipFile -DestinationPath $tempDir -Force -ErrorAction Stop # Das extrahierte Verzeichnis (z.?B. sql-server-maintenance-solution-main) finden $extractedDir = Get-ChildItem -Path $tempDir -Directory | Where-Object { $_.Name -like "sql-server-maintenance-solution-*" } | Select-Object -First 1 if (-not $extractedDir) { throw "Konnte extrahiertes Verzeichnis nicht finden." } # Skripte in der definierten Reihenfolge ausfuehren $actionMsg = if ($olaCheck.IsInstalled -and $effForce) { "Aktualisiere Ola Maintenance Solution auf $instance" } else { "Installiere Ola Maintenance Solution auf $instance" } if ($PSCmdlet.ShouldProcess($instance, $actionMsg)) { Invoke-sqmLogging -Message "[$instance] Fuehre Ola-Installationsskripte aus ..." -FunctionName $functionName -Level "INFO" foreach ($scriptFile in $scriptFiles) { $scriptPath = Join-Path $extractedDir.FullName $scriptFile if (-not (Test-Path $scriptPath)) { Invoke-sqmLogging -Message "[$instance] Skript '$scriptFile' nicht gefunden - ueberspringe." -FunctionName $functionName -Level "WARNING" continue } Invoke-sqmLogging -Message "[$instance] Fuehre $scriptFile aus ..." -FunctionName $functionName -Level "VERBOSE" Invoke-DbaQuery @connParams -Database master -File $scriptPath -EnableException -ErrorAction Stop } Invoke-sqmLogging -Message "[$instance] Ola-Installation erfolgreich abgeschlossen." -FunctionName $functionName -Level "INFO" $instanceResult.Status = 'Success' $instanceResult.Action = if ($olaCheck.IsInstalled -and $effForce) { 'Updated' } else { 'Installed' } $instanceResult.Message = "Ola Maintenance Solution wurde erfolgreich ${actionMsg}. (Keine Jobs erstellt)." } else { $instanceResult.Status = 'WhatIf' $instanceResult.Message = "WhatIf: $actionMsg (keine Jobs)" } } finally { # Temporaere Dateien bereinigen if (Test-Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue } } } catch { $errMsg = "Fehler auf '$instance': $($_.Exception.Message)" Invoke-sqmLogging -Message $errMsg -FunctionName $functionName -Level "ERROR" $instanceResult.Status = 'Failed' $instanceResult.Message = $errMsg if (-not $ContinueOnError -and -not $EnableException) { throw } if ($EnableException) { throw $_ } } $allResults.Add($instanceResult) } } end { Invoke-sqmLogging -Message "$functionName abgeschlossen." -FunctionName $functionName -Level "INFO" return $allResults } } |