#requires -RunAsAdministrator <# .SYNOPSIS Deploy PDF preview fix to multiple Glaztech computers remotely .DESCRIPTION Runs Fix-PDFPreview-Glaztech.ps1 on multiple remote computers via PowerShell remoting or prepares for deployment via GuruRMM .PARAMETER ComputerNames Array of computer names to target .PARAMETER Credential PSCredential for remote access (optional, uses current user if not provided) .PARAMETER UseGuruRMM Export script as GuruRMM task instead of running directly .EXAMPLE .\Deploy-PDFFix-BulkRemote.ps1 -ComputerNames "PC001","PC002","PC003" .EXAMPLE .\Deploy-PDFFix-BulkRemote.ps1 -ComputerNames (Get-Content computers.txt) .EXAMPLE .\Deploy-PDFFix-BulkRemote.ps1 -UseGuruRMM Generates GuruRMM deployment package #> param( [string[]]$ComputerNames = @(), [PSCredential]$Credential, [switch]$UseGuruRMM, [string[]]$ServerNames = @("192.168.8.62"), [string[]]$AdditionalPaths = @() ) $ScriptPath = Join-Path $PSScriptRoot "Fix-PDFPreview-Glaztech.ps1" if (-not (Test-Path $ScriptPath)) { Write-Host "[ERROR] Fix-PDFPreview-Glaztech.ps1 not found in script directory" -ForegroundColor Red exit 1 } if ($UseGuruRMM) { Write-Host "[OK] Generating GuruRMM deployment package..." -ForegroundColor Green Write-Host "" $GuruRMMScript = @" # Glaztech PDF Preview Fix - GuruRMM Deployment # Auto-generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss") `$ScriptContent = @' $(Get-Content $ScriptPath -Raw) '@ # Save script to temp location `$TempScript = "`$env:TEMP\Fix-PDFPreview-Glaztech.ps1" `$ScriptContent | Out-File -FilePath `$TempScript -Encoding UTF8 -Force # Build parameters `$Params = @{} "@ if ($ServerNames.Count -gt 0) { $ServerList = ($ServerNames | ForEach-Object { "`"$_`"" }) -join "," $GuruRMMScript += @" `$Params['ServerNames'] = @($ServerList) "@ } if ($AdditionalPaths.Count -gt 0) { $PathList = ($AdditionalPaths | ForEach-Object { "`"$_`"" }) -join "," $GuruRMMScript += @" `$Params['UnblockPaths'] = @($PathList) "@ } $GuruRMMScript += @" # Execute script (includes automatic Explorer restart) & `$TempScript @Params # Cleanup Remove-Item `$TempScript -Force -ErrorAction SilentlyContinue "@ $GuruRMMPath = Join-Path $PSScriptRoot "GuruRMM-Glaztech-PDF-Fix.ps1" $GuruRMMScript | Out-File -FilePath $GuruRMMPath -Encoding UTF8 -Force Write-Host "[SUCCESS] GuruRMM script generated: $GuruRMMPath" -ForegroundColor Green Write-Host "" Write-Host "To deploy via GuruRMM:" -ForegroundColor Cyan Write-Host "1. Log into GuruRMM dashboard" Write-Host "2. Create new PowerShell task" Write-Host "3. Copy contents of: $GuruRMMPath" Write-Host "4. Target: Glaztech Industries (Client ID: d857708c-5713-4ee5-a314-679f86d2f9f9)" Write-Host "5. Execute on affected computers" Write-Host "" Write-Host "GuruRMM API Key: grmm_Qw64eawPBjnMdwN5UmDGWoPlqwvjM7lI" -ForegroundColor Yellow exit 0 } if ($ComputerNames.Count -eq 0) { Write-Host "[ERROR] No computer names provided" -ForegroundColor Red Write-Host "" Write-Host "Usage examples:" -ForegroundColor Yellow Write-Host " .\Deploy-PDFFix-BulkRemote.ps1 -ComputerNames 'PC001','PC002','PC003'" Write-Host " .\Deploy-PDFFix-BulkRemote.ps1 -ComputerNames (Get-Content computers.txt)" Write-Host " .\Deploy-PDFFix-BulkRemote.ps1 -UseGuruRMM" exit 1 } Write-Host "[OK] Deploying PDF fix to $($ComputerNames.Count) computers..." -ForegroundColor Green Write-Host "" $Results = @() $ScriptContent = Get-Content $ScriptPath -Raw foreach ($Computer in $ComputerNames) { Write-Host "[$Computer] Connecting..." -ForegroundColor Cyan try { # Test connectivity if (-not (Test-Connection -ComputerName $Computer -Count 1 -Quiet)) { Write-Host "[$Computer] [ERROR] Cannot reach computer" -ForegroundColor Red $Results += [PSCustomObject]@{ ComputerName = $Computer Status = "Unreachable" PDFsUnblocked = 0 ConfigChanges = 0 Error = "Cannot ping" } continue } # Build parameters $RemoteParams = @{} if ($ServerNames.Count -gt 0) { $RemoteParams['ServerNames'] = $ServerNames } if ($AdditionalPaths.Count -gt 0) { $RemoteParams['UnblockPaths'] = $AdditionalPaths } # Execute remotely $InvokeParams = @{ ComputerName = $Computer ScriptBlock = [ScriptBlock]::Create($ScriptContent) ArgumentList = $RemoteParams } if ($Credential) { $InvokeParams['Credential'] = $Credential } $Result = Invoke-Command @InvokeParams -ErrorAction Stop Write-Host "[$Computer] [SUCCESS] PDFs: $($Result.PDFsUnblocked), Changes: $($Result.ConfigChanges)" -ForegroundColor Green $Results += [PSCustomObject]@{ ComputerName = $Computer Status = "Success" PDFsUnblocked = $Result.PDFsUnblocked ConfigChanges = $Result.ConfigChanges Error = $null } # Note: Explorer restart is now handled by the main script automatically } catch { Write-Host "[$Computer] [ERROR] $($_.Exception.Message)" -ForegroundColor Red $Results += [PSCustomObject]@{ ComputerName = $Computer Status = "Failed" PDFsUnblocked = 0 ConfigChanges = 0 Error = $_.Exception.Message } } Write-Host "" } # Summary Write-Host "========================================" Write-Host "DEPLOYMENT SUMMARY" Write-Host "========================================" $Results | Format-Table -AutoSize $SuccessCount = ($Results | Where-Object { $_.Status -eq "Success" }).Count $FailureCount = ($Results | Where-Object { $_.Status -ne "Success" }).Count Write-Host "" Write-Host "Total Computers: $($Results.Count)" Write-Host "Successful: $SuccessCount" -ForegroundColor Green Write-Host "Failed: $FailureCount" -ForegroundColor $(if ($FailureCount -gt 0) { "Red" } else { "Green" }) # Export results $ResultsPath = Join-Path $PSScriptRoot "deployment-results-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv" $Results | Export-Csv -Path $ResultsPath -NoTypeInformation Write-Host "" Write-Host "Results exported to: $ResultsPath"