bin/Public/Set-sqmSsrsConfiguration.ps1
|
function Set-sqmSsrsConfiguration { <# .SYNOPSIS Konfiguriert SQL Server Reporting Services (SSRS) vollautomatisch. Unterstuetzt lokale und Remote-Installation sowie AlwaysOn-Umgebungen. .DESCRIPTION Fuehrt eine vollstaendige SSRS-Erst- oder Neukonfiguration durch. Unterstuetzt Native Mode und SharePoint Integrated Mode (automatische Erkennung). Konfigurierte Bereiche (einzeln deaktivierbar): - Dienstkonto (SetWindowsServiceIdentity) - Datenbank (anlegen, Rechte vergeben, Verbindung setzen) - URLs (ReportServer Web Service + Portal, nur Native Mode) - Verschluesselungsschluessel (BackupEncryptionKey) Bei AlwaysOn Availability Groups (AG) wird der Datenbankserver automatisch als Listener erkannt; die DB-Erstellung erfolgt auf dem Primary-Replikat, die Verbindung wird auf den Listener konfiguriert. Optional kann eine Policy-Based Management (PBM) Policy (z.B. 'Password Policy') vor der Datenbankerstellung deaktiviert und danach wieder aktiviert werden. .PARAMETER ComputerName SSRS-Server (lokal oder remote). Standard: $env:COMPUTERNAME. .PARAMETER InstanceName SSRS-Instanzname. Standard: 'MSSQLSERVER'. .PARAMETER DatabaseServer SQL Server-Instanz oder AG-Listener fuer die ReportServer-Datenbank. Standard: $ComputerName. .PARAMETER DatabaseName Name der ReportServer-Hauptdatenbank. Standard: 'ReportServer'. .PARAMETER ReportServerUrl URL fuer den ReportServer Web Service. Standard: 'http://+:80/ReportServer' .PARAMETER ReportsUrl URL fuer den Reports-Manager / Web Portal. Standard: 'http://+:80/Reports' .PARAMETER ServiceAccount Windows-Dienstkonto fuer SSRS (z.B. 'DOMAIN\user' oder 'NT SERVICE\...'). .PARAMETER ServiceAccountPassword Kennwort fuer -ServiceAccount (SecureString). Nicht noetig bei Dienstkonten. .PARAMETER DatabaseAuthType Authentifizierung fuer die DB-Verbindung: 'Windows' (Standard) oder 'SQL'. .PARAMETER DatabaseCredential PSCredential fuer SQL-Authentifizierung (nur bei -DatabaseAuthType SQL). .PARAMETER EncryptionKeyFile Pfad fuer das Encryption Key Backup (.snk). Ohne Angabe wird die Datei im OutputPath mit Namen 'SsrsEncryptionKey_<Instanz>_<Datum>.snk' abgelegt. .PARAMETER EncryptionKeyPassword Kennwort zum Schutz der Schluesseldatei (SecureString). Pflicht wenn ein Backup erstellt werden soll. .PARAMETER PbmPolicyName Name einer Policy-Based Management Policy (z.B. 'Password Policy'), die vor dem Erstellen der Datenbank deaktiviert und nach erfolgreicher Konfiguration wieder aktiviert wird. .PARAMETER SkipDatabase Datenbankkonfiguration ueberspringen. .PARAMETER SkipUrls URL-Konfiguration ueberspringen (nur Native Mode). .PARAMETER SkipServiceAccount Dienstkonto-Konfiguration ueberspringen. .PARAMETER SkipEncryptionKeyBackup Encryption Key Backup ueberspringen. .PARAMETER Credential PSCredential fuer die WinRM-Verbindung (nur bei Remote-Betrieb). .PARAMETER OutputPath Ausgabeverzeichnis fuer den Konfigurationsbericht und ggf. Schluesseldatei. Standard: Get-sqmDefaultOutputPath. .PARAMETER ContinueOnError Bei Fehler mit naechstem Schritt fortfahren (selten verwendet). .PARAMETER EnableException Ausnahmen sofort ausloesen. .PARAMETER Confirm Bestaetigung vor der Ausfuehrung anfordern. .PARAMETER WhatIf Zeigt, was passieren wuerde, ohne aenderungen vorzunehmen. .EXAMPLE Set-sqmSsrsConfiguration .EXAMPLE Set-sqmSsrsConfiguration -ComputerName "SSRS01" -DatabaseServer "AG_Listener" -PbmPolicyName "Password Policy" .NOTES Voraussetzungen: dbatools, Invoke-sqmLogging, Get-sqmDefaultOutputPath, Get-sqmConfig, Set-sqmSqlPolicyState WMI-Namespace: root\Microsoft\SqlServer\ReportServer\<Instanz>\v<Version>\Admin #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'None')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false)] [string]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [string]$InstanceName = 'MSSQLSERVER', [Parameter(Mandatory = $false)] [string]$DatabaseServer, [Parameter(Mandatory = $false)] [string]$DatabaseName = 'ReportServer', [Parameter(Mandatory = $false)] [string]$ReportServerUrl = 'http://+:80/ReportServer', [Parameter(Mandatory = $false)] [string]$ReportsUrl = 'http://+:80/Reports', [Parameter(Mandatory = $false)] [string]$ServiceAccount, [Parameter(Mandatory = $false)] [System.Security.SecureString]$ServiceAccountPassword, [Parameter(Mandatory = $false)] [ValidateSet('Windows', 'SQL')] [string]$DatabaseAuthType = 'Windows', [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$DatabaseCredential, [Parameter(Mandatory = $false)] [string]$EncryptionKeyFile, [Parameter(Mandatory = $false)] [System.Security.SecureString]$EncryptionKeyPassword, [Parameter(Mandatory = $false)] [string]$PbmPolicyName, [Parameter(Mandatory = $false)] [switch]$SkipDatabase, [Parameter(Mandatory = $false)] [switch]$SkipUrls, [Parameter(Mandatory = $false)] [switch]$SkipServiceAccount, [Parameter(Mandatory = $false)] [switch]$SkipEncryptionKeyBackup, [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$Credential, [Parameter(Mandatory = $false)] [string]$OutputPath = (Get-sqmDefaultOutputPath), [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 } Invoke-sqmLogging -Message "Starte $functionName auf $ComputerName" -FunctionName $functionName -Level "INFO" $result = [PSCustomObject]@{ ComputerName = $ComputerName InstanceName = $InstanceName SsrsMode = $null SsrsVersion = $null DatabaseServer = $DatabaseServer IsAgListener = $false AgPrimaryNode = $null ServiceAccountResult = 'Skipped' DatabaseResult = 'Skipped' UrlResult = 'Skipped' EncryptionKeyResult = 'Skipped' OverallStatus = 'Unknown' Message = $null ReportPath = $null } if (-not $DatabaseServer) { $result.DatabaseServer = $ComputerName } $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' $datestamp = Get-Date -Format 'yyyy-MM-dd' $safeComp = $ComputerName -replace '[\\/:*?"<>|]', '_' $safeInst = $InstanceName -replace '[\\/:*?"<>|]', '_' $isLocal = $ComputerName -in @($env:COMPUTERNAME, 'localhost', '127.0.0.1', '.') function _SecureToPlain([System.Security.SecureString]$s) { if (-not $s) { return '' } [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($s)) } $logLines = [System.Collections.Generic.List[string]]::new() function _Log($msg, $sev = 'INFO') { $logLines.Add("[$(Get-Date -Format 'HH:mm:ss')] [$sev] $msg") switch ($sev) { 'ERROR' { Invoke-sqmLogging -Message $msg -FunctionName $functionName -Level "ERROR" } 'WARNING' { Invoke-sqmLogging -Message $msg -FunctionName $functionName -Level "WARNING" } default { Invoke-sqmLogging -Message $msg -FunctionName $functionName -Level "VERBOSE" } } } } process { try { # CIM-Session $cimBase = @{ ErrorAction = 'Stop' } $cimSession = $null if ($isLocal) { _Log "Lokaler Betrieb - kein WinRM erforderlich." } else { _Log "Remote-Betrieb: Verbinde zu '$ComputerName' via WsMan..." $sessionOpts = New-CimSessionOption -Protocol Wsman $cimParams = @{ ComputerName = $ComputerName; SessionOption = $sessionOpts } if ($Credential) { $cimParams['Credential'] = $Credential } $cimSession = New-CimSession @cimParams -ErrorAction Stop $cimBase['CimSession'] = $cimSession _Log "CIM-Session hergestellt." } # SSRS WMI-Namespace $wmiConfig = $null $wmiVersion = $null $rsNamespace = 'root\Microsoft\SqlServer\ReportServer' $instNs = "$rsNamespace\$InstanceName" $versionNs = Get-CimInstance @cimBase -Namespace $instNs -ClassName '__NAMESPACE' -ErrorAction Stop | Where-Object { $_.Name -like 'v*' } | Sort-Object Name -Descending | Select-Object -First 1 -ExpandProperty Name if (-not $versionNs) { throw "Kein SSRS-Namespace unter '$instNs' gefunden." } $wmiVersion = $versionNs $adminNs = "$instNs\$versionNs\Admin" _Log "WMI-Namespace: $adminNs" $wmiConfig = Get-CimInstance @cimBase -Namespace $adminNs -ClassName 'MSReportServer_ConfigurationSetting' -ErrorAction Stop | Select-Object -First 1 if (-not $wmiConfig) { throw "MSReportServer_ConfigurationSetting nicht gefunden." } $isSharePoint = [bool]$wmiConfig.IsSharePointIntegrated $result.SsrsMode = if ($isSharePoint) { 'SharePointIntegrated' } else { 'NativeMode' } $result.SsrsVersion = $wmiVersion $result.InstanceName = $wmiConfig.InstanceName Write-Host "[$ComputerName] SSRS $wmiVersion | $($result.SsrsMode) | Instanz: $($result.InstanceName)" -ForegroundColor Cyan _Log "SSRS $wmiVersion | Modus: $($result.SsrsMode) | Dienstkonto: $($wmiConfig.WindowsServiceIdentityActual)" function _InvokeCim($method, [hashtable]$arguments, $desc) { _Log "WMI ? $method - $desc" $r = Invoke-CimMethod @cimBase -Namespace $adminNs -ClassName 'MSReportServer_ConfigurationSetting' -MethodName $method -Arguments $arguments -ErrorAction Stop if ($r.HRESULT -ne 0) { throw "$method (HRESULT 0x$($r.HRESULT.ToString('X8'))): $($r.Error)" } return $r } # AG-Listener-Erkennung $dbCreateServer = $result.DatabaseServer $isAgListener = $false $agPrimaryNode = $null if (-not $SkipDatabase) { try { $listenerCheck = Invoke-DbaQuery -SqlInstance $result.DatabaseServer -ErrorAction SilentlyContinue -Query @" SELECT ag.name AS AgName, agl.dns_name AS ListenerName, ar.replica_server_name AS PrimaryReplica FROM sys.availability_group_listeners agl JOIN sys.availability_groups ag ON ag.group_id = agl.group_id JOIN sys.dm_hadr_availability_group_states ags ON ags.group_id = ag.group_id JOIN sys.availability_replicas ar ON ar.group_id = ag.group_id AND ar.replica_id = ags.primary_replica WHERE agl.dns_name = @@SERVERNAME OR UPPER(agl.dns_name) = UPPER('$($result.DatabaseServer.Split('\')[0])') "@ if ($listenerCheck) { $isAgListener = $true $agPrimaryNode = $listenerCheck.PrimaryReplica | Select-Object -First 1 $result.IsAgListener = $true $result.AgPrimaryNode = $agPrimaryNode $dbCreateServer = if ($result.DatabaseServer -match '\\') { "$agPrimaryNode\$($result.DatabaseServer.Split('\')[1])" } else { $agPrimaryNode } Write-Host " ? AG-Listener erkannt: '$($result.DatabaseServer)' ? Primary: '$agPrimaryNode'" -ForegroundColor Cyan _Log "AG-Listener '$($result.DatabaseServer)' ? Primary '$agPrimaryNode'. DB-Erstellung auf: '$dbCreateServer'" } } catch { _Log "AG-Listener-Pruefung: $($_.Exception.Message) (kein Listener - wird als normaler Server behandelt)" } } $errorsOccurred = $false # 1. Dienstkonto if ($ServiceAccount -and -not $SkipServiceAccount) { Write-Host " [1/4] Dienstkonto konfigurieren: $ServiceAccount" -ForegroundColor Gray if ($PSCmdlet.ShouldProcess($ComputerName, "SSRS-Dienstkonto auf '$ServiceAccount' setzen")) { try { $useBuiltIn = $ServiceAccount -like 'NT SERVICE\*' -or $ServiceAccount -like 'NT AUTHORITY\*' -or $ServiceAccount -in @('LocalSystem', 'LocalService', 'NetworkService') $null = _InvokeCim 'SetWindowsServiceIdentity' @{ UseBuiltInAccount = $useBuiltIn Account = $ServiceAccount Password = (_SecureToPlain $ServiceAccountPassword) } "Dienstkonto '$ServiceAccount'" $result.ServiceAccountResult = 'OK' Write-Host " ? Dienstkonto gesetzt." -ForegroundColor Green _Log "Dienstkonto '$ServiceAccount' gesetzt." $wmiConfig = Get-CimInstance @cimBase -Namespace $adminNs -ClassName 'MSReportServer_ConfigurationSetting' -ErrorAction SilentlyContinue | Select-Object -First 1 } catch { _Log "Dienstkonto-Fehler: $($_.Exception.Message)" 'ERROR' $result.ServiceAccountResult = 'Failed' $errorsOccurred = $true if (-not $ContinueOnError -and $EnableException) { throw } } } else { $result.ServiceAccountResult = 'WhatIf' } } # 2. Datenbank (inkl. PBM-Policy Deaktivierung/Reaktivierung) if (-not $SkipDatabase) { $dbServerDisplay = if ($isAgListener) { "$($result.DatabaseServer) (Listener) ? Primary: $agPrimaryNode" } else { $result.DatabaseServer } Write-Host " [2/4] Datenbank konfigurieren: $DatabaseName auf $dbServerDisplay" -ForegroundColor Gray if ($PSCmdlet.ShouldProcess($ComputerName, "ReportServer-DB '$DatabaseName' konfigurieren")) { $pbmPolicyWasDisabled = $false try { # --- PBM-Policy deaktivieren (falls angegeben) --- if ($PbmPolicyName) { Write-Host " Deaktiviere PBM-Policy '$PbmPolicyName' ..." -ForegroundColor Gray $policyArgs = @{ SqlInstance = $dbCreateServer Policy = $PbmPolicyName State = 'Disable' ContinueOnError = $ContinueOnError EnableException = $EnableException } $null = Set-sqmSqlPolicyState @policyArgs $pbmPolicyWasDisabled = $true Write-Host " ? Policy deaktiviert." -ForegroundColor Green _Log "PBM-Policy '$PbmPolicyName' auf '$dbCreateServer' deaktiviert." } # --- Bestehende DB-Logik --- $dbExists = $false try { $dbCheck = Invoke-DbaQuery -SqlInstance $dbCreateServer -Query "SELECT name FROM sys.databases WHERE name = N'$DatabaseName'" -ErrorAction SilentlyContinue $dbExists = $null -ne $dbCheck } catch { $dbExists = $false } if (-not $dbExists) { _Log "Datenbank '$DatabaseName' nicht vorhanden auf '$dbCreateServer' - lege an..." $genResult = _InvokeCim 'GenerateDatabaseCreationScript' @{ DatabaseName = $DatabaseName Lcid = 1033 IsSharePoint = $isSharePoint } "DB-Erstellungs-Skript generieren" Invoke-DbaQuery -SqlInstance $dbCreateServer -Query $genResult.Script -EnableException -ErrorAction Stop | Out-Null _Log "Datenbank '$DatabaseName' + '${DatabaseName}TempDB' auf '$dbCreateServer' angelegt." Write-Host " Datenbank angelegt auf: $dbCreateServer" -ForegroundColor Gray } else { _Log "Datenbank '$DatabaseName' bereits vorhanden auf '$dbCreateServer'." } $isRemoteDb = ($ComputerName.Split('.')[0].ToUpper() -ne $dbCreateServer.Split('\\')[0].Split('.')[0].ToUpper()) -or $isAgListener $rightsResult = _InvokeCim 'GenerateDatabaseRightsScript' @{ DatabaseName = $DatabaseName AccountName = $wmiConfig.WindowsServiceIdentityActual IsRemote = $isRemoteDb IsWindowsAccount = ($DatabaseAuthType -eq 'Windows') } "Rechte-Skript generieren" if ($rightsResult.Script) { Invoke-DbaQuery -SqlInstance $dbCreateServer -Query $rightsResult.Script -EnableException -ErrorAction SilentlyContinue | Out-Null _Log "DB-Rechte fuer '$($wmiConfig.WindowsServiceIdentityActual)' auf '$dbCreateServer' gesetzt." if ($isAgListener) { _Log "AG-Info: DB-Rechte werden durch Synchronisation auf alle Secondaries repliziert." Write-Host " ? AG: Rechte werden auf Secondaries synchronisiert." -ForegroundColor Gray } } $dbAuthTypeInt = if ($DatabaseAuthType -eq 'SQL') { 1 } else { 2 } $dbUser = if ($DatabaseAuthType -eq 'SQL' -and $DatabaseCredential) { $DatabaseCredential.UserName } else { '' } $dbPwd = if ($DatabaseAuthType -eq 'SQL' -and $DatabaseCredential) { _SecureToPlain $DatabaseCredential.Password } else { '' } $null = _InvokeCim 'SetDatabaseConnection' @{ Server = $result.DatabaseServer DatabaseName = $DatabaseName CredentialsType = $dbAuthTypeInt Username = $dbUser Password = $dbPwd } "DB-Verbindung konfigurieren (Server: $($result.DatabaseServer))" $result.DatabaseResult = 'OK' Write-Host " ? Datenbank konfiguriert." -ForegroundColor Green _Log "SetDatabaseConnection: Server=$($result.DatabaseServer) / DB=$DatabaseName / Auth=$DatabaseAuthType" } catch { _Log "Datenbank-Fehler: $($_.Exception.Message)" 'ERROR' $result.DatabaseResult = 'Failed' $errorsOccurred = $true if (-not $ContinueOnError -and $EnableException) { throw } } finally { # --- PBM-Policy wieder aktivieren (falls zuvor deaktiviert) --- if ($pbmPolicyWasDisabled) { try { Write-Host " Reaktiviere PBM-Policy '$PbmPolicyName' ..." -ForegroundColor Gray $policyArgs = @{ SqlInstance = $dbCreateServer Policy = $PbmPolicyName State = 'Enable' ContinueOnError = $ContinueOnError EnableException = $EnableException } $null = Set-sqmSqlPolicyState @policyArgs Write-Host " ? Policy wieder aktiviert." -ForegroundColor Green _Log "PBM-Policy '$PbmPolicyName' auf '$dbCreateServer' reaktiviert." } catch { _Log "Fehler beim Reaktivieren der Policy: $($_.Exception.Message)" 'WARNING' # Kein Throw, um das Hauptresultat nicht zu gefaehrden } } } } else { $result.DatabaseResult = 'WhatIf' } } # 3. URLs (nur Native Mode) if (-not $SkipUrls) { if ($isSharePoint) { _Log "SharePoint Integrated Mode - URL-Konfiguration entfaellt." 'WARNING' $result.UrlResult = 'NotApplicable' } else { Write-Host " [3/4] URLs konfigurieren..." -ForegroundColor Gray if ($PSCmdlet.ShouldProcess($ComputerName, "URLs setzen: $ReportServerUrl | $ReportsUrl")) { try { $null = _InvokeCim 'ReserveURL' @{ Application = 'ReportServerWebService' UrlString = $ReportServerUrl Lcid = 1033 } "ReportServerWebService: $ReportServerUrl" $reportsApp = if ([int]($wmiVersion -replace 'v', '') -ge 14) { 'ReportServerWebApp' } else { 'ReportManager' } $null = _InvokeCim 'ReserveURL' @{ Application = $reportsApp UrlString = $ReportsUrl Lcid = 1033 } "${reportsApp}: $ReportsUrl" $result.UrlResult = 'OK' Write-Host " ? URLs konfiguriert: $ReportServerUrl | $ReportsUrl" -ForegroundColor Green _Log "URLs: $ReportServerUrl + $ReportsUrl ($reportsApp)" } catch { _Log "URL-Fehler: $($_.Exception.Message)" 'ERROR' $result.UrlResult = 'Failed' $errorsOccurred = $true if (-not $ContinueOnError -and $EnableException) { throw } } } else { $result.UrlResult = 'WhatIf' } } } # 4. Encryption Key Backup $effectiveKeyFile = $EncryptionKeyFile if (-not $SkipEncryptionKeyBackup -and $EncryptionKeyPassword) { if (-not $effectiveKeyFile) { $effectiveKeyFile = Join-Path $OutputPath "SsrsEncryptionKey_${safeInst}_${datestamp}.snk" if (-not (Test-Path $OutputPath)) { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } } Write-Host " [4/4] Encryption Key sichern..." -ForegroundColor Gray if ($PSCmdlet.ShouldProcess($ComputerName, "Encryption Key sichern nach '$effectiveKeyFile'")) { try { $keyResult = _InvokeCim 'BackupEncryptionKey' @{ Password = (_SecureToPlain $EncryptionKeyPassword) } "BackupEncryptionKey" $keyDir = Split-Path $effectiveKeyFile -Parent if ($keyDir -and -not (Test-Path $keyDir)) { New-Item -ItemType Directory -Path $keyDir -Force | Out-Null } [System.IO.File]::WriteAllBytes($effectiveKeyFile, $keyResult.KeyFile) $result.EncryptionKeyResult = 'OK' Write-Host " ? Key gesichert: $effectiveKeyFile" -ForegroundColor Green _Log "Encryption Key gesichert: '$effectiveKeyFile'" } catch { _Log "Key-Backup-Fehler: $($_.Exception.Message)" 'ERROR' $result.EncryptionKeyResult = 'Failed' $errorsOccurred = $true if (-not $ContinueOnError -and $EnableException) { throw } } } else { $result.EncryptionKeyResult = 'WhatIf' } } # Bericht schreiben if (-not (Test-Path $OutputPath)) { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } $reportFile = Join-Path $OutputPath "SsrsConfiguration_${safeComp}_${safeInst}_${datestamp}.txt" $result.ReportPath = $reportFile $agInfo = if ($isAgListener) { "AG-Listener: $($result.DatabaseServer) ? Primary: $agPrimaryNode" } else { 'Kein AG-Listener' } $lines = @( "# ================================================================" "# MSSQLTools - SSRS Konfigurationsbericht" "# Server : $ComputerName ($(if ($isLocal) { 'lokal' } else { 'remote' }))" "# Instanz : $InstanceName" "# SSRS-Modus : $($result.SsrsMode) | Version: $wmiVersion" "# DB-Server : $($result.DatabaseServer) | $agInfo" "# Erstellt : $timestamp" "# ================================================================" "" "Ergebnisse:" " Dienstkonto : $($result.ServiceAccountResult)" " Datenbank : $($result.DatabaseResult)" " URLs : $($result.UrlResult)" " Encryption Key : $($result.EncryptionKeyResult)" "" "Detail-Log:" ) + $logLines $lines | Out-File -FilePath $reportFile -Encoding UTF8 -Force $centralPath = Get-sqmConfig -Key 'CentralPath' if ($centralPath) { $centralFile = Join-Path $centralPath (Split-Path $reportFile -Leaf) if (-not (Test-Path $centralPath)) { New-Item -ItemType Directory -Path $centralPath -Force | Out-Null } Copy-Item -Path $reportFile -Destination $centralFile -Force -ErrorAction SilentlyContinue } $result.OverallStatus = if ($errorsOccurred) { 'PartialSuccess' } else { 'Success' } $result.Message = "Dienstkonto: $($result.ServiceAccountResult) | Datenbank: $($result.DatabaseResult) | URLs: $($result.UrlResult) | Key: $($result.EncryptionKeyResult)" Write-Host "" Write-Host "[$ComputerName] SSRS-Konfiguration: $($result.OverallStatus)" -ForegroundColor $(if ($errorsOccurred) { 'Yellow' } else { 'Green' }) Write-Host " Bericht: $reportFile" -ForegroundColor Gray } catch { $errMsg = "Schwerer Fehler auf $ComputerName : $($_.Exception.Message)" Invoke-sqmLogging -Message $errMsg -FunctionName $functionName -Level "ERROR" if ($EnableException) { throw } $result.OverallStatus = 'Failed' $result.Message = $errMsg } finally { if ($cimSession) { Remove-CimSession $cimSession -ErrorAction SilentlyContinue } } return $result } } |