Public/Update-sqmModule.ps1
|
<# .SYNOPSIS Updates the sqmSQLTool module from GitHub, PSGallery or a UNC share. .DESCRIPTION Downloads and installs the latest version of sqmSQLTool from the specified source. Process: 1. Check if update is available (via Test-sqmModuleUpdate) 2. Create backup of current installation 3. Download/copy new version 4. Unblock all files (remove Zone.Identifier ADS) 5. Verify import succeeds 6. Report installed version Sources: - GitHub : Downloads latest release ZIP from GitHub Releases - PSGallery: Installs via Install-Module / Update-Module - UNC : Copies from share using robocopy (same as Update.ps1) .PARAMETER Source Update source. Valid values: GitHub, PSGallery, UNC. Default: GitHub .PARAMETER RepositoryPath UNC path for UNC source. Default: W:\75084-Datenbanken\MSSQL\DEV\sqmSQLTool .PARAMETER Destination Installation path for the module. Default: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\sqmSQLTool (or %ProgramFiles%\WindowsPowerShell\Modules\sqmSQLTool) .PARAMETER Force Install even if no newer version is available. .PARAMETER EnableException Throw exceptions immediately. .EXAMPLE Update-sqmModule .EXAMPLE Update-sqmModule -Source GitHub -Force .EXAMPLE Update-sqmModule -Source UNC -RepositoryPath "\\fileserver\dba\sqmSQLTool" .NOTES Requires administrator rights for installation to Program Files. GitHub source requires internet access. UNC source requires network access to the share. #> function Update-sqmModule { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false)] [ValidateSet('GitHub', 'PSGallery', 'UNC')] [string]$Source = 'GitHub', [Parameter(Mandatory = $false)] [string]$RepositoryPath = 'W:\75084-Datenbanken\MSSQL\DEV\sqmSQLTool', [Parameter(Mandatory = $false)] [string]$Destination = "$env:ProgramFiles\WindowsPowerShell\Modules\sqmSQLTool", [Parameter(Mandatory = $false)] [switch]$Force, [Parameter(Mandatory = $false)] [switch]$EnableException ) $functionName = $MyInvocation.MyCommand.Name Invoke-sqmLogging -Message "Starte $functionName - Source: $Source" -FunctionName $functionName -Level "INFO" try { # --------------------------------------------------------------- # 1. Update pruefen # --------------------------------------------------------------- $checkResult = switch ($Source) { 'GitHub' { Test-sqmUpdateViaGitHub -EnableException:$EnableException } 'PSGallery' { Test-sqmUpdateViaPSGallery -EnableException:$EnableException } 'UNC' { Test-sqmUpdateViaUNC -RepositoryPath $RepositoryPath -EnableException:$EnableException } } if ($checkResult.Status -ne 'OK') { throw "Versionspruefung fehlgeschlagen: $($checkResult.ErrorMessage)" } if (-not $Force -and -not $checkResult.UpdateAvailable) { Write-Host "sqmSQLTool ist bereits aktuell (v$($checkResult.LocalVersion))." -ForegroundColor Green return [PSCustomObject]@{ Status = 'UpToDate' LocalVersion = $checkResult.LocalVersion RemoteVersion = $checkResult.RemoteVersion } } $action = "sqmSQLTool v$($checkResult.LocalVersion) -> v$($checkResult.RemoteVersion) via $Source" if (-not $PSCmdlet.ShouldProcess('sqmSQLTool', $action)) { return $null } # --------------------------------------------------------------- # 2. Backup # --------------------------------------------------------------- if (Test-Path $Destination) { $backupDir = "$Destination`_Backup_$(Get-Date -Format 'yyyyMMdd_HHmm')" Invoke-sqmLogging -Message "Erstelle Backup: $backupDir" -FunctionName $functionName -Level "INFO" Copy-Item -Path $Destination -Destination $backupDir -Recurse -Force } # --------------------------------------------------------------- # 3. Update installieren # --------------------------------------------------------------- switch ($Source) { 'GitHub' { if (-not $checkResult.DownloadUrl) { throw "Kein Download-URL in GitHub Release gefunden." } $tmpZip = Join-Path $env:TEMP "sqmSQLTool_update.zip" $tmpDir = Join-Path $env:TEMP "sqmSQLTool_update" Invoke-sqmLogging -Message "Lade herunter: $($checkResult.DownloadUrl)" -FunctionName $functionName -Level "INFO" Invoke-WebRequest -Uri $checkResult.DownloadUrl -OutFile $tmpZip -UseBasicParsing -ErrorAction Stop if (Test-Path $tmpDir) { Remove-Item $tmpDir -Recurse -Force } Expand-Archive -Path $tmpZip -DestinationPath $tmpDir -Force # Modul-Ordner im ZIP finden $moduleFolder = Get-ChildItem $tmpDir -Recurse -Filter 'sqmSQLTool.psd1' | Select-Object -First 1 | Split-Path -Parent if (-not $moduleFolder) { throw "sqmSQLTool.psd1 nicht im ZIP gefunden." } if (-not (Test-Path $Destination)) { New-Item -ItemType Directory -Path $Destination -Force | Out-Null } Copy-Item -Path "$moduleFolder\*" -Destination $Destination -Recurse -Force # Aufraumen Remove-Item $tmpZip -Force -ErrorAction SilentlyContinue Remove-Item $tmpDir -Recurse -Force -ErrorAction SilentlyContinue } 'PSGallery' { $installedModule = Get-Module -ListAvailable -Name sqmSQLTool -ErrorAction SilentlyContinue | Select-Object -First 1 if ($installedModule) { Invoke-sqmLogging -Message "Update-Module sqmSQLTool via PSGallery" -FunctionName $functionName -Level "INFO" Update-Module -Name sqmSQLTool -Force -ErrorAction Stop } else { Invoke-sqmLogging -Message "Install-Module sqmSQLTool via PSGallery" -FunctionName $functionName -Level "INFO" Install-Module -Name sqmSQLTool -Force -ErrorAction Stop } } 'UNC' { Invoke-sqmLogging -Message "Kopiere von UNC: $RepositoryPath" -FunctionName $functionName -Level "INFO" & robocopy $RepositoryPath $Destination /E /NJH /NJS /NDL /COPY:DAT /XD .git /XF .gitignore README.md LICENSE Install.cmd Install.ps1 Update.cmd Update.ps1 if ($LASTEXITCODE -ge 8) { throw "robocopy fehlgeschlagen (ExitCode $LASTEXITCODE)" } } } # --------------------------------------------------------------- # 4. Zone.Identifier entfernen # --------------------------------------------------------------- Get-ChildItem -Path $Destination -Recurse -File -ErrorAction SilentlyContinue | ForEach-Object { Unblock-File -Path $_.FullName -ErrorAction SilentlyContinue } # --------------------------------------------------------------- # 5. Import testen # --------------------------------------------------------------- Remove-Module sqmSQLTool -ErrorAction SilentlyContinue Import-Module sqmSQLTool -Force -ErrorAction Stop $newVersion = (Get-Module sqmSQLTool).Version Invoke-sqmLogging -Message "sqmSQLTool v$newVersion erfolgreich installiert." -FunctionName $functionName -Level "INFO" Write-Host "sqmSQLTool v$newVersion erfolgreich aktualisiert." -ForegroundColor Green return [PSCustomObject]@{ Status = 'Updated' Source = $Source OldVersion = $checkResult.LocalVersion NewVersion = $newVersion Destination = $Destination BackupPath = if ($backupDir) { $backupDir } else { $null } } } catch { $errMsg = "Update fehlgeschlagen: $($_.Exception.Message)" Invoke-sqmLogging -Message $errMsg -FunctionName $functionName -Level "ERROR" if ($EnableException) { throw } Write-Error $errMsg return [PSCustomObject]@{ Status = 'Failed' Source = $Source ErrorMessage = $errMsg } } } |