The Wallpaper Automation Script That Makes Assigned Access Work Smoothly

🚀 Secure Windows Kiosk Deployment with Assigned Access & Intune

This configuration demonstrates how to build a secure and controlled Windows kiosk environment using Assigned Access (Kiosk Mode) together with modern deployment tools like Windows Autopilot and Microsoft Intune.

📌 What This Script Does

Before applying the Assigned Access XML, you must run the following PowerShell script. The script is a fully local, Intune remediation‑optimized wallpaper and lockscreen manager. It guarantees that the kiosk device always uses the correct background and lockscreen images — stored locally on the system.

It is designed to work reliably even in offline, restricted, or library/public kiosk environments where cloud‑based personalization policies may fail.

🛡️ Key Capabilities (Summary)

  • Creates/maintains the folder C:\Kiosk
  • Uses two image files:
    • background.jpg → Desktop wallpaper
    • kiosk_lockscreen.jpg → Lock screen
  • Applies both images using HKLM PersonalizationCSP
  • Applies wallpaper for logged‑in kiosk users via HKCU
  • Creates an autorun script to ensure wallpaper loads on every new login
  • Creates a fallback lockscreen image in C:\Windows\Web\Screen
  • Fixes ACL permissions so any restricted kiosk user can read the image files
  • Runs as SYSTEM inside Intune Remediation (recommended)

🔄 Automatic Image Updates

If you replace the files in C:\Kiosk with new images:

  • The next Intune remediation cycle applies the new wallpaper/lockscreen
  • No restart required for lockscreen
  • Desktop wallpaper updates at next login (autorun script ensures this)

⚠️ Why This Script Is Required Before Assigned Access

Assigned Access can fail if images, paths or icons referenced in your XML do not exist yet. Running this script before applying the kiosk XML ensures that:

  • All required files exist and have correct access permissions
  • Wallpaper paths used by kiosk mode are already set
  • Regkeys such as PersonalizationCSP are present before lockdown
  • Your kiosk device boots into a fully configured visual environment

Below is the script exactly as used in the deployment.

PowerShell – Local Kiosk Wallpaper Manager

# OnePRScript_LOCAL.ps1 – HELT LOKAL version (Device Script-optimerad)
# Sätter desktop- och låsskärmsbild från C:\IFObilder, låser via HKLM\PersonalizationCSP,
# fixar HKCU via autostartscript, skapar fallback i %SystemRoot%\Web\Screen.
# Körs som SYSTEM i Intune Device Script (Remediate-läge som standard).

[CmdletBinding()]
param(
    [string]$Action = 'Remediate',     # <-- VIKTIGT: Kör ALLTID Remediate
    [switch]$VerboseLogging
)

# ---- KONFIG (100% LOKAL) ----
$WorkingDir   = "C:\Kiosk"
$desktopFile  = "background.jpg"          
$lockFile     = "kiosk_lockscreen.jpg"    

$desktopPath  = Join-Path $WorkingDir $desktopFile
$lockPath     = Join-Path $WorkingDir $lockFile
$RegKey       = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP"
$WebScreenOut = Join-Path $env:SystemRoot "Web\Screen\kiosk_lockscreen_LOCAL.jpg"
$LogFile      = Join-Path $WorkingDir "SetKioskWallpaper_LOCAL.log"

# ---- LOGG ----
function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    try {
        $logDir = Split-Path $LogFile -Parent
        if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory -Force | Out-Null }
        $line = "{0} [{1}] {2}" -f (Get-Date).ToString('yyyy-MM-dd HH:mm:ss'), $Level, $Message
        $line | Out-File -FilePath $LogFile -Append -Encoding UTF8
        if ($VerboseLogging) { Write-Host $line }
    } catch { }
}

# ---- KONTROLLERA ATT BILDERNA FINNS ----
function Test-LocalImages {
    if (-not (Test-Path $desktopPath -PathType Leaf)) {
        Write-Log "SAKNAS: $desktopPath" "ERROR"
        return $false
    }
    if (-not (Test-Path $lockPath -PathType Leaf)) {
        Write-Log "SAKNAS: $lockPath" "ERROR"
        return $false
    }
    Write-Log "Båda lokala bilderna finns: $desktopPath | $lockPath"
    return $true
}

# ---- REMEDIATE ----
function Do-Remediate {

    # 1. Skapa mapp om den saknas
    if (-not (Test-Path $WorkingDir)) {
        New-Item -Path $WorkingDir -ItemType Directory -Force | Out-Null
        Write-Log "Skapade $WorkingDir"
    }

    # 2. Kontrollera att bilderna finns
    if (-not (Test-LocalImages)) {
        throw "En eller båda bilderna saknas i $WorkingDir"
    }

    # 3. Sätt ACL så alla kan läsa bilderna
    try {
        $sid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-545") 
        $inherit = [System.Security.AccessControl.InheritanceFlags]::None
        $prop    = [System.Security.AccessControl.PropagationFlags]::None
        foreach ($f in @($desktopPath, $lockPath)) {
            $acl = Get-Acl $f
            $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($sid, "ReadAndExecute", $inherit, $prop, "Allow")
            $acl.SetAccessRule($rule)
            Set-Acl -Path $f -AclObject $acl
        }
        Write-Log "ACL uppdaterad på bilderna"
    } catch { Write-Log "ACL FEL: $($_.Exception.Message)" "WARN" }

    # 4. HKLM PersonalizationCSP
    try {
        if (-not (Test-Path $RegKey)) { New-Item -Path $RegKey -Force | Out-Null }

        Set-ItemProperty -Path $RegKey -Name "DesktopImagePath"    -Value $desktopPath -Force
        Set-ItemProperty -Path $RegKey -Name "LockScreenImagePath" -Value $lockPath    -Force

        Set-ItemProperty -Path $RegKey -Name "DesktopImageStatus" -Value 1 -Force
        Set-ItemProperty -Path $RegKey -Name "LockScreenImageStatus" -Value 1 -Force

        Write-Log "PersonalizationCSP uppdaterad"
    } catch { Write-Log "CSP FEL: $($_.Exception.Message)" "WARN" }

    # 5. Fallback-bild
    try {
        Copy-Item -Path $lockPath -Destination $WebScreenOut -Force
        $acl  = Get-Acl $WebScreenOut
        $sid  = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-545")
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($sid,"ReadAndExecute","None","None","Allow")
        $acl.SetAccessRule($rule)
        Set-Acl -Path $WebScreenOut -AclObject $acl
        Write-Log "Fallback kopierad"
    } catch { Write-Log "Fallback FEL: $($_.Exception.Message)" "WARN" }

    # 6. HKCU (om inte SYSTEM)
    try {
        if ($env:USERNAME -and $env:USERNAME -notin @('defaultuser100000','SYSTEM')) {
            Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "Wallpaper" -Value $desktopPath -Force
            Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "WallpaperStyle" -Value "2" -Force
            Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "TileWallpaper" -Value "0" -Force
            rundll32.exe user32.dll,UpdatePerUserSystemParameters 1, True, 20
            Write-Log "HKCU uppdaterad"
        }
    } catch { Write-Log "HKCU FEL: $($_.Exception.Message)" "WARN" }

    # 7. Autostart-script för framtida inloggningar
    try {
        $scriptPath = "C:\Users\Public\SetKioskWallpaper_LOCAL.ps1"
        $content = @"
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name 'Wallpaper' -Value '$desktopPath'
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name 'WallpaperStyle' -Value '2'
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name 'TileWallpaper' -Value '0'
rundll32.exe user32.dll,UpdatePerUserSystemParameters 1, True, 20
"@
        $content | Out-File -FilePath $scriptPath -Encoding UTF8 -Force

        $startup = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
        if (-not (Test-Path $startup)) { New-Item -Path $startup -ItemType Directory -Force | Out-Null }

        $lnk = Join-Path $startup "KioskWallpaper.lnk"
        $shell = New-Object -ComObject WScript.Shell
        $shortcut = $shell.CreateShortcut($lnk)
        $shortcut.TargetPath = "powershell.exe"
        $shortcut.Arguments = "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$scriptPath`""
        $shortcut.Save()

        Write-Log "Autostart-skript skapat"
    } catch { Write-Log "Autostart FEL: $($_.Exception.Message)" "WARN" }
}

# ---- HUVUD ----
Write-Log "START OnePRScript_LOCAL Action=$Action"

try {
    Do-Remediate
    Write-Log "Remediate: ALLT FIXAT"
    exit 0
} catch {
    Write-Output "FEL: $($_.Exception.Message)"
    Write-Log "KRITISKT FEL: $($_.Exception.Message)" "ERROR"
    exit 1
}
  

Kommentarer

Populära inlägg i den här bloggen

🚀 Force Reinstallation of an Intune App

🔵Troubleshooting Intune Device Enrollments: Understanding GUIDs, Registry Paths, and EnterpriseMgmt Tasks

🚀 Windows Autopilot Self-Deploying Mode — Zero-Touch Setup That Feels Like Magic