sqmSQLTool.psm1
|
<# =========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.183 Created on: 21.04.2026 15:37 Created by: Janke Organization: dtcSoftware Filename: sqmSQLTool.psm1 ------------------------------------------------------------------------- Module Name: sqmSQLTool =========================================================================== #> # ============================================================================= # SCHRITT 1: Modulkonfiguration als ERSTES initialisieren # (muss vor dem Laden der Funktionen und vor Get-sqmConfig-Aufrufen stehen) # ============================================================================= $script:sqmModuleConfig = @{ LogPath = "$env:ProgramData\sqmSQLTool\Logs" OutputPath = "$env:ProgramData\sqmSQLTool\Logs" CentralPath = $null OlaJobNameFull = "OlaHH-UserDatabases-FULL" OlaJobNameDiff = "OlaHH-UserDatabases-DIFF" OlaJobNameLog = "OlaHH-UserDatabases-LOG" OlaJobNameIndexOpt = "OlaHH IndexOptimize - USER_DATABASES" OlaJobNameIntUserDb = "OlaHH IntegrityCheck - USER_DATABASES" OlaJobNameIntSysDb = "OlaHH IntegrityCheck - SYSTEM_DATABASES" OlaJobNameSysDbBackup = "OlaHH-SystemDatabases-FULL" BackupDirectory = $null HpuDomainGroupMap = @() SsrsInstallerPath = $null AutoUpdate = $true UpdateRepository = 'W:\75084-Datenbanken\MSSQL\DEV\sqmSQLTool' ModuleVersion = '1.0.0' Language = 'de-DE' } # Aktuelle Version aus der Manifestdatei lesen $manifestPath = Join-Path $PSScriptRoot 'sqmSQLTool.psd1' if (Test-Path $manifestPath) { try { $manifestData = Import-PowerShellDataFile -Path $manifestPath -ErrorAction Stop $script:sqmModuleConfig['ModuleVersion'] = $manifestData.ModuleVersion } catch { } } # Persistierte Konfiguration laden (ueberschreibt Standardwerte) $configFile = Join-Path $env:APPDATA "MSSQLTools\config.json" if (Test-Path $configFile) { try { $userConfig = Get-Content $configFile -Raw | ConvertFrom-Json foreach ($key in $userConfig.PSObject.Properties) { $script:sqmModuleConfig[$key.Name] = $key.Value } } catch { Write-Warning "Konfiguration konnte nicht geladen werden: $($_.Exception.Message)" } } # String-Cache invalidieren (wird durch Get-sqmString bei erstem Zugriff neu befuellt) $script:_strings = $null # ============================================================================= # SCHRITT 2: dbatools-Verfuegbarkeit pruefen und einmalig laden # Robuste Pruefung: zuerst bereits geladen, dann expliziter Import-Versuch # ============================================================================= $script:dbatoolsAvailable = $false if (Get-Module -Name dbatools) { # dbatools bereits in der Session geladen (z.B. via RequiredModules) $script:dbatoolsAvailable = $true } else { try { Import-Module dbatools -ErrorAction Stop $script:dbatoolsAvailable = $true } catch { # dbatools nicht ladbar - nur warnen, Modul laedt trotzdem $script:dbatoolsAvailable = $false } } if (-not $script:dbatoolsAvailable) { Write-Warning "dbatools-Modul nicht gefunden. Funktionen die dbatools benoetigen sind nicht verfuegbar. Installation: Install-Module dbatools" } # ============================================================================= # SCHRITT 3: Private und Public Funktionen laden # ============================================================================= $PublicPath = Join-Path $PSScriptRoot 'Public' $PrivatePath = Join-Path $PSScriptRoot 'Private' Get-ChildItem -Path $PrivatePath -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue | ForEach-Object { . $_.FullName } Get-ChildItem -Path $PublicPath -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue | ForEach-Object { . $_.FullName } # ============================================================================= # SCHRITT 4: Logging-Bereitschaft pruefen (NACH Funktionsladung und Config-Init) # ============================================================================= $script:sqmLoggingReady = Test-sqmLoggingPath -Path (Get-sqmConfig -Key "LogPath") # ============================================================================= # SCHRITT 5: Public-Funktionen exportieren # ============================================================================= $allFunctions = Get-ChildItem -Path $PublicPath -Filter *.ps1 -ErrorAction SilentlyContinue | ForEach-Object { $_.BaseName } foreach ($func in $allFunctions) { if ($func -like "*-sqm*") { Export-ModuleMember -Function $func } } # Update-Funktionen explizit exportieren (definiert im PSM1, nicht in Public\) Export-ModuleMember -Function 'Test-sqmModuleUpdate', 'Update-sqmModule' # ============================================================================= # Update-Mechanismus # ============================================================================= <# .SYNOPSIS Prueft ob eine neuere Version des MSSQLTools-Moduls im konfigurierten Repository verfuegbar ist. .PARAMETER RepositoryPath Pfad zum Update-Repository (ueberschreibt die Konfiguration). .PARAMETER Credential Credentials fuer UNC-Freigaben. #> function Test-sqmModuleUpdate { [CmdletBinding()] param ( [string]$RepositoryPath = $script:sqmModuleConfig['UpdateRepository'], [System.Management.Automation.PSCredential]$Credential ) if (-not $RepositoryPath) { Write-Verbose "Kein Update-Repository konfiguriert." return $false } # Guard: check if the repository root is reachable before any path operations. # This prevents Join-Path from throwing when a drive letter (e.g. W:) does not exist. if (-not (Test-Path -Path $RepositoryPath -ErrorAction SilentlyContinue)) { Write-Verbose "Update-Repository nicht erreichbar: $RepositoryPath" return $false } try { $remoteVersionFile = Join-Path $RepositoryPath 'ModuleVersion.txt' if (Test-Path -Path $remoteVersionFile -ErrorAction SilentlyContinue) { $remoteVersion = (Get-Content -Path $remoteVersionFile -ErrorAction Stop).Trim() } else { $remoteManifest = Join-Path $RepositoryPath 'sqmSQLTool.psd1' if (Test-Path -Path $remoteManifest -ErrorAction SilentlyContinue) { $remoteData = Import-PowerShellDataFile -Path $remoteManifest -ErrorAction Stop $remoteVersion = $remoteData.ModuleVersion } else { Write-Verbose "Keine Versionsinformation im Repository gefunden." return $false } } $currentVersion = [version]$script:sqmModuleConfig['ModuleVersion'] $newVersion = [version]$remoteVersion return $newVersion -gt $currentVersion } catch { Write-Warning "Update-Pruefung fehlgeschlagen: $($_.Exception.Message)" return $false } } <# .SYNOPSIS Aktualisiert das MSSQLTools-Modul aus dem konfigurierten Repository. .PARAMETER RepositoryPath Pfad zum Update-Repository. .PARAMETER Credential Credentials fuer UNC-Freigaben. .PARAMETER Backup Sicherung vor dem Update erstellen (Standard: $true). .PARAMETER Force Update auch ohne neuere Version erzwingen. #> function Update-sqmModule { [CmdletBinding(SupportsShouldProcess = $true)] param ( [string]$RepositoryPath = $script:sqmModuleConfig['UpdateRepository'], [System.Management.Automation.PSCredential]$Credential, [switch]$Backup = $true, [switch]$Force ) $currentModulePath = $PSScriptRoot if (-not $RepositoryPath) { Write-Error "Kein Update-Repository konfiguriert. Bitte Set-sqmConfig -UpdateRepository <Pfad> ausfuehren." return } if (-not (Test-Path -Path $RepositoryPath -ErrorAction SilentlyContinue)) { Write-Error "Repository-Pfad '$RepositoryPath' nicht erreichbar." return } if (-not $Force -and -not (Test-sqmModuleUpdate -RepositoryPath $RepositoryPath)) { Write-Host "Keine neuere Version verfuegbar." -ForegroundColor Green return } if ($PSCmdlet.ShouldProcess("Modul aus '$RepositoryPath' aktualisieren", "Update")) { try { if ($Backup) { $backupDir = Join-Path $env:TEMP "MSSQLTools_Backup_$(Get-Date -Format 'yyyyMMdd_HHmsqm')" Copy-Item -Path $currentModulePath -Destination $backupDir -Recurse -Force -ErrorAction Stop Write-Host "Backup erstellt: $backupDir" -ForegroundColor Gray } Get-ChildItem -Path $RepositoryPath -Recurse -File | ForEach-Object { $relativePath = $_.FullName.Substring($RepositoryPath.Length).TrimStart('\') $targetFile = Join-Path $currentModulePath $relativePath $targetDir = Split-Path $targetFile -Parent if (-not (Test-Path $targetDir)) { New-Item -ItemType Directory -Path $targetDir -Force | Out-Null } Copy-Item -Path $_.FullName -Destination $targetFile -Force -ErrorAction Stop } Write-Host "Modul wurde aktualisiert." -ForegroundColor Green Write-Warning "Bitte PowerShell neu starten oder 'Remove-Module sqmSQLTool; Import-Module sqmSQLTool' ausfuehren." } catch { Write-Error "Update fehlgeschlagen: $($_.Exception.Message)" } } else { Write-Host "Update abgebrochen." -ForegroundColor Yellow } } # Auto-update on module import (only when AutoUpdate = $true, repository is configured and reachable) if ($script:sqmModuleConfig['AutoUpdate'] -and $script:sqmModuleConfig['UpdateRepository']) { $noUpdate = $env:MSSQLTOOLS_SKIP_AUTO_UPDATE -eq '1' $repoPath = $script:sqmModuleConfig['UpdateRepository'] $repoReachable = Test-Path -Path $repoPath -ErrorAction SilentlyContinue if (-not $noUpdate -and $repoReachable) { try { if (Test-sqmModuleUpdate) { Write-Host "New module version available. Running update..." -ForegroundColor Cyan Update-sqmModule -Force -Backup } } catch { Write-Verbose "Auto-update check failed: $($_.Exception.Message)" } } } |