# Ensure the script is running with Administrative Privileges $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "[FAIL] This script must be run as an Administrator (Elevated Prompt)." -ForegroundColor Red; Exit } Clear-Host Write-Host "=================================================================" -ForegroundColor Cyan Write-Host " DOMINOPDF DIAGNOSTIC " -ForegroundColor Cyan Write-Host "=================================================================" -ForegroundColor Cyan Write-Host "" $Guid = "{AE19299E-0AD7-4AE7-8827-0F586771651D}" $RegistryErrors = 0 $EnvironmentErrors = 0 # ================================================================= # STAGE 1: REGISTRY ARCHITECTURE CHECKS # ================================================================= Write-Host ">>> Stage 1: Verifying Core Registry Architecture..." -ForegroundColor Cyan $AppIDPaths = @( "HKLM:\SOFTWARE\Classes\Wow6432Node\AppID\$Guid", "HKLM:\SOFTWARE\Classes\AppID\$Guid" ) foreach ($Path in $AppIDPaths) { if (Test-Path $Path) { $Props = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue if ($Props.PSObject.Properties.Name -contains "DllSurrogate") { Write-Host "[OK] AppID path and 'DllSurrogate' property exist at: $Path" -ForegroundColor Green } else { Write-Host "[FAIL] Key exists, but the 'DllSurrogate' string is missing at: $Path" -ForegroundColor Red; $RegistryErrors++ } } else { Write-Host "[FAIL] AppID path not found in registry tree: $Path" -ForegroundColor Red; $RegistryErrors++ } } $ClsidPath = "HKLM:\SOFTWARE\Classes\Wow6432Node\CLSID\$Guid" if (Test-Path $ClsidPath) { $Props = Get-ItemProperty -Path $ClsidPath -ErrorAction SilentlyContinue if ($Props.PSObject.Properties.Name -contains "AppID" -and $Props.AppID -eq $Guid) { Write-Host "[OK] CLSID correctly references AppID link: $Guid" -ForegroundColor Green } else { Write-Host "[FAIL] CLSID exists but is missing the correct 'AppID' link string." -ForegroundColor Red; $RegistryErrors++ } $ServerPath = "$ClsidPath\LocalServer32" if (Test-Path $ServerPath) { $ExePath = (Get-ItemProperty -Path $ServerPath)."(default)" if ($ExePath) { $CleanExePath = $ExePath.Trim('"') if (Test-Path $CleanExePath) { Write-Host "[OK] LocalServer32 binary target verified on disk: $CleanExePath" -ForegroundColor Green } else { Write-Host "[FAIL] Registry points to an executable that does not exist on disk: $CleanExePath" -ForegroundColor Red; $RegistryErrors++ } } } else { Write-Host "[FAIL] Missing subfolder key: LocalServer32" -ForegroundColor Red; $RegistryErrors++ } } else { Write-Host "[FAIL] Base CLSID folder not found at: $ClsidPath" -ForegroundColor Red; $RegistryErrors++ } # ================================================================= # STAGE 2: DOMINO ENVIRONMENT, IDENTITY, AND NOTES.INI CHECKS # ================================================================= Write-Host "" Write-Host ">>> Stage 2: Checking HCL Domino Environmental & Identity Layout..." -ForegroundColor Cyan # Find the service path to read notes.ini location and check service account $DominoService = Get-Service -Name "Lotus Domino Server", "Domino Server", "HCL Domino Server" -ErrorAction SilentlyContinue | Select-Object -First 1 if ($DominoService) { $ServiceName = $DominoService.Name $ServiceConfig = Get-CimInstance -ClassName Win32_Service -Filter "Name='$ServiceName'" $ServiceAccount = $ServiceConfig.StartName $ImagePath = $ServiceConfig.PathName Write-Host "[INFO] Detected Domino Running Under Service Account: $ServiceAccount" -ForegroundColor Yellow # RESTORED: Verify DCOM RunAs Identity Alignment against the Named Service Account $AppIDRegPath = "HKLM:\SOFTWARE\Classes\AppID\$Guid" $RunAsUser = (Get-ItemProperty -Path $AppIDRegPath -ErrorAction SilentlyContinue).RunAs if ($ServiceAccount -ne "LocalSystem") { if ($null -eq $RunAsUser) { Write-Host "[FAIL] Domino runs as named account, but DCOM properties identity is NOT set to 'This User'." -ForegroundColor Red $EnvironmentErrors++ } else { Write-Host "[OK] DCOM identity profile configuration is explicitly delegated to: $RunAsUser" -ForegroundColor Green } } else { Write-Host "[INFO] Domino runs as LocalSystem. Checking interactive desktop constraints..." -ForegroundColor Yellow } # Extract Domino Directory path safely from ImagePath or use fallback $DominoDir = "" if ($ImagePath -match '"([^"]+)"') { $DominoDir = Split-Path -Path $Matches[1] -Parent } else { $DominoDir = Split-Path -Path ($ImagePath.Split(' ')[0]) -Parent } # Locate and scan notes.ini configuration $NotesIniPath = Join-Path -Path $DominoDir -ChildPath "notes.ini" if (-not (Test-Path $NotesIniPath)) { $NotesIniPath = "C:\Program Files\HCL\Domino\notes.ini" # Common system default fallback } if (Test-Path $NotesIniPath) { Write-Host "[OK] Located active configuration profile: $NotesIniPath" -ForegroundColor Green $IniContent = Get-Content -Path $NotesIniPath $DisableScriptCOM = $IniContent | Where-Object { $_ -match "Disable_Script_COM\s*=\s*1" } if ($DisableScriptCOM) { Write-Host "[CRITICAL FAIL] 'Disable_Script_COM=1' is set inside notes.ini! LotusScript is blocked from using COM objects." -ForegroundColor Red $EnvironmentErrors++ } else { Write-Host "[OK] notes.ini does not contain any global COM execution blocks." -ForegroundColor Green } } else { Write-Host "[WARNING] Could not automatically open notes.ini. Ensure 'Disable_Script_COM=1' is NOT set inside it manually." -ForegroundColor Yellow } # Verify System Path visibility for Domino binaries $SysPath = [Environment]::GetEnvironmentVariable("Path", "Machine") if ($SysPath -like "*$DominoDir*") { Write-Host "[OK] Domino Program directory is registered in the global system path variables." -ForegroundColor Green } else { Write-Host "[WARNING] Domino Program folder is missing from the Windows System PATH. This can cause background DLL dependency errors." -ForegroundColor Yellow } } else { Write-Host "[WARNING] No active Domino Service found. Skipping service-specific checks." -ForegroundColor Yellow } # Check system profile folders $ProfilePaths = @( "C:\Windows\SysWOW64\config\systemprofile\Desktop", "C:\Windows\System32\config\systemprofile\Desktop" ) foreach ($FolderPath in $ProfilePaths) { if (Test-Path $FolderPath) { Write-Host "[OK] System profile workspace directory exists: $FolderPath" -ForegroundColor Green } else { Write-Host "[FAIL] Missing system directory needed for background printing: $FolderPath" -ForegroundColor Red; $EnvironmentErrors++ } } # ================================================================= # STAGE 3: LIVE RUNTIME INSTANTIATION TEST # ================================================================= Write-Host "" Write-Host ">>> Stage 3: Testing Live COM Activation..." -ForegroundColor Cyan if ($RegistryErrors -gt 0) { Write-Host "[WARNING] Core registry framework validation failed. Aborting activation test." -ForegroundColor Yellow Exit } if ($EnvironmentErrors -gt 0) { Write-Host "[INFO] Core registration looks good, but $EnvironmentErrors error(s) were flagged in the Domino environment layout." -ForegroundColor Yellow Write-Host "Proceeding with live COM activation test anyway to verify object health..." -ForegroundColor Yellow } try { $Type = [Type]::GetTypeFromCLSID($Guid) $ComInstance = [Activator]::CreateInstance($Type) if ($ComInstance -ne $null) { Write-Host "[SUCCESS] COM Object successfully instantiated via system surrogate (dllhost.exe)!" -ForegroundColor Green if ($EnvironmentErrors -gt 0) { Write-Host "[ATTENTION] Windows successfully activated the COM, but LotusScript will continue to fail until Stage 2 blocks are fixed." -ForegroundColor Yellow } [System.Runtime.InteropServices.Marshal]::ReleaseComObject($ComInstance) | Out-Null } } catch { Write-Host "[FAIL] Runtime instantiation failed!" -ForegroundColor Red Write-Host "Error Details: $_" -ForegroundColor Red } Write-Host "" Write-Host "=================================================================" -ForegroundColor Cyan