param( [object]$Config, [string]$LogFile ) $ErrorActionPreference = "Continue" function Write-Log { param([string]$Message, [string]$Level = "INFO") $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message" Add-Content -Path $LogFile -Value $line -Encoding UTF8 } $ScriptDir = "C:\Windows\Setup\Scripts" $RenderScript = "$ScriptDir\DesktopInfo-Render.ps1" $BmpPath = "$ScriptDir\desktopinfo.bmp" if (-not (Test-Path $ScriptDir)) { New-Item -ItemType Directory -Path $ScriptDir -Force | Out-Null } # ----------------------------------------------------------------------- # Read display settings from config # ----------------------------------------------------------------------- $fontSize = 13 $fontColor = "#FFFFFF" $position = "bottomRight" if ($Config -and $Config.desktopInfo) { if ($Config.desktopInfo.fontSize) { $fontSize = [int]$Config.desktopInfo.fontSize } if ($Config.desktopInfo.fontColor) { $fontColor = $Config.desktopInfo.fontColor } if ($Config.desktopInfo.position) { $position = $Config.desktopInfo.position } } # ----------------------------------------------------------------------- # Write the rendering script (runs on every logon as the user) # ----------------------------------------------------------------------- Write-Log "Writing DesktopInfo render script to $RenderScript" -Level INFO $renderContent = @" # DesktopInfo-Render.ps1 # Collects system info and renders it onto the desktop wallpaper. # Runs on every user logon via Scheduled Task. `$ErrorActionPreference = "Continue" Add-Type -AssemblyName System.Drawing Add-Type -TypeDefinition @' using System; using System.Runtime.InteropServices; public class WallpaperApi { [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); } '@ -ErrorAction SilentlyContinue # ----------------------------------------------------------------------- # Collect system info # ----------------------------------------------------------------------- `$hostname = `$env:COMPUTERNAME `$username = `$env:USERNAME `$ipAddress = (Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { `$_.IPAddress -ne "127.0.0.1" -and `$_.PrefixOrigin -ne "WellKnown" } | Select-Object -First 1).IPAddress if (-not `$ipAddress) { `$ipAddress = "N/A" } `$osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue `$osName = if (`$osInfo) { `$osInfo.Caption -replace "Microsoft ", "" } else { "Windows" } `$osBuild = if (`$osInfo) { `$osInfo.BuildNumber } else { "" } # Deployment date = when script was first run, stored in registry `$deployRegPath = "HKLM:\SOFTWARE\X9\Deployment" `$deployDate = (Get-ItemProperty -Path `$deployRegPath -Name "DeployDate" -ErrorAction SilentlyContinue).DeployDate if (-not `$deployDate) { `$deployDate = "N/A" } # ----------------------------------------------------------------------- # Build info lines # ----------------------------------------------------------------------- `$lines = @( "Computer : `$hostname" "User : `$username" "IP : `$ipAddress" "OS : `$osName (build `$osBuild)" "Deployed : `$deployDate" ) # ----------------------------------------------------------------------- # Render bitmap # ----------------------------------------------------------------------- Add-Type -AssemblyName System.Windows.Forms -ErrorAction SilentlyContinue `$screen = [System.Windows.Forms.Screen]::PrimaryScreen `$width = if (`$screen) { `$screen.Bounds.Width } else { 1920 } `$height = if (`$screen) { `$screen.Bounds.Height } else { 1080 } `$bmp = New-Object System.Drawing.Bitmap(`$width, `$height) `$g = [System.Drawing.Graphics]::FromImage(`$bmp) # Background: solid accent color #223B47 `$bgColor = [System.Drawing.ColorTranslator]::FromHtml("#223B47") `$g.Clear(`$bgColor) # Font and colors `$fontFamily = "Consolas" `$fontSize = $fontSize `$font = New-Object System.Drawing.Font(`$fontFamily, `$fontSize, [System.Drawing.FontStyle]::Regular) `$brush = New-Object System.Drawing.SolidBrush([System.Drawing.ColorTranslator]::FromHtml("$fontColor")) `$shadowBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(180, 0, 0, 0)) # Measure text block `$lineHeight = `$font.GetHeight(`$g) + 4 `$blockH = `$lines.Count * `$lineHeight `$maxWidth = (`$lines | ForEach-Object { `$g.MeasureString(`$_, `$font).Width } | Measure-Object -Maximum).Maximum # Position `$margin = 24 `$pos = "$position" `$x = switch -Wildcard (`$pos) { "*Right" { `$width - `$maxWidth - `$margin } "*Left" { `$margin } default { `$margin } } `$y = switch -Wildcard (`$pos) { "bottom*" { `$height - `$blockH - `$margin } "top*" { `$margin } default { `$height - `$blockH - `$margin } } # Draw shadow then text foreach (`$line in `$lines) { `$g.DrawString(`$line, `$font, `$shadowBrush, (`$x + 1), (`$y + 1)) `$g.DrawString(`$line, `$font, `$brush, `$x, `$y) `$y += `$lineHeight } `$g.Dispose() # Save BMP `$bmpPath = "$BmpPath" `$bmp.Save(`$bmpPath, [System.Drawing.Imaging.ImageFormat]::Bmp) `$bmp.Dispose() # Set as wallpaper # SPI_SETDESKTOPWALLPAPER=20, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE=3 [WallpaperApi]::SystemParametersInfo(20, 0, `$bmpPath, 3) | Out-Null "@ $renderContent | Set-Content -Path $RenderScript -Encoding UTF8 -Force Write-Log "Render script written" -Level OK # ----------------------------------------------------------------------- # Store deployment date in registry (used by render script) # ----------------------------------------------------------------------- Write-Log "Storing deployment date in registry" -Level INFO try { if (-not (Test-Path "HKLM:\SOFTWARE\X9\Deployment")) { New-Item -Path "HKLM:\SOFTWARE\X9\Deployment" -Force | Out-Null } $existingDate = (Get-ItemProperty -Path "HKLM:\SOFTWARE\X9\Deployment" ` -Name "DeployDate" -ErrorAction SilentlyContinue).DeployDate if (-not $existingDate) { Set-ItemProperty -Path "HKLM:\SOFTWARE\X9\Deployment" ` -Name "DeployDate" ` -Value (Get-Date -Format "yyyy-MM-dd") ` -Force Write-Log " DeployDate set: $(Get-Date -Format 'yyyy-MM-dd')" -Level OK } else { Write-Log " DeployDate already set: $existingDate" -Level INFO } } catch { Write-Log " Failed to set DeployDate: $_" -Level ERROR } # ----------------------------------------------------------------------- # Register scheduled task: DesktopInfo # Runs the render script on every user logon # ----------------------------------------------------------------------- Write-Log "Registering task: DesktopInfo" -Level STEP try { Unregister-ScheduledTask -TaskName "DesktopInfo" -Confirm:$false -ErrorAction SilentlyContinue $action = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$RenderScript`"" $trigger = New-ScheduledTaskTrigger -AtLogOn $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) ` -MultipleInstances IgnoreNew ` -StartWhenAvailable $principal = New-ScheduledTaskPrincipal -GroupId "Users" -RunLevel Limited $task = New-ScheduledTask -Action $action ` -Trigger $trigger ` -Settings $settings ` -Principal $principal ` -Description "Render system info onto desktop wallpaper on logon" Register-ScheduledTask -TaskName "DesktopInfo" -InputObject $task -Force | Out-Null Write-Log "Task DesktopInfo registered" -Level OK } catch { Write-Log "Failed to register DesktopInfo task: $_" -Level ERROR } # ----------------------------------------------------------------------- # Run once immediately for current user # ----------------------------------------------------------------------- Write-Log "Running DesktopInfo render now for current user" -Level INFO try { & powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File $RenderScript Write-Log "DesktopInfo rendered" -Level OK } catch { Write-Log "DesktopInfo render failed: $_" -Level WARN } Write-Log "Step 7 complete" -Level OK