Group Policy can install the module, register the refresh task, set the PowerShell execution policy and, on Enterprise and Education editions, force a lock screen image that PowerBGInfo renders.
When to use this route
- Active Directory domain-joined PCs and session hosts.
- When the same GPO should also carry the execution policy and the lock screen policy.
Prerequisites
- Group Policy Management Console and rights to edit and link a GPO.
- A share that computer accounts can read (for example under
SYSVOLorNETLOGON) holding a saved copy of the module (Save-Module, see Run in production) andSet-BGInfoWallpaper.ps1. - For the lock screen policy: Windows Enterprise, Education or Server.
Step 1: install the module and the script
Use your software distribution tool, or a computer startup script (Computer Configuration > Policies > Windows Settings > Scripts (Startup/Shutdown) > Startup, PowerShell Scripts tab). Startup scripts run as the computer account, before anyone signs in.
# Startup script: installs the staged PowerBGInfo and the wallpaper script.
$share = '\\contoso.com\NETLOGON\PowerBGInfo'
# The share holds one tested version, saved with Save-Module.
$version = (Get-ChildItem "$share\Module\PowerBGInfo" -Directory |
Select-Object -First 1).Name
$programFiles = if ($env:ProgramW6432) { $env:ProgramW6432 } else {
$env:ProgramFiles
}
$moduleTarget = Join-Path $programFiles `
"WindowsPowerShell\Modules\PowerBGInfo\$version"
$moduleSource = Join-Path $share "Module\PowerBGInfo\$version"
$moduleFiles = @(Get-ChildItem -LiteralPath $moduleSource -File -Recurse -ErrorAction Stop)
if (-not $moduleFiles.Count) { throw "The module source is empty: $moduleSource" }
$copyModule = -not (Test-Path -LiteralPath (Join-Path $moduleTarget 'PowerBGInfo.psd1') -PathType Leaf)
foreach ($moduleFile in $moduleFiles) {
$relativePath = $moduleFile.FullName.Substring($moduleSource.Length).TrimStart('\', '/')
$targetFile = Join-Path $moduleTarget $relativePath
if (-not (Test-Path -LiteralPath $targetFile -PathType Leaf)) {
$copyModule = $true
break
}
$sourceHash = (Get-FileHash -LiteralPath $moduleFile.FullName -Algorithm SHA256).Hash
$targetHash = (Get-FileHash -LiteralPath $targetFile -Algorithm SHA256).Hash
if ($sourceHash -ne $targetHash) {
$copyModule = $true
break
}
}
if ($copyModule) {
New-Item -ItemType Directory -Path $moduleTarget -Force | Out-Null
Copy-Item -Path (Join-Path $moduleSource '*') -Destination $moduleTarget `
-Recurse -Force -ErrorAction Stop
foreach ($moduleFile in $moduleFiles) {
$relativePath = $moduleFile.FullName.Substring($moduleSource.Length).TrimStart('\', '/')
$targetFile = Join-Path $moduleTarget $relativePath
if (-not (Test-Path -LiteralPath $targetFile -PathType Leaf)) {
throw "The module copy is incomplete: $targetFile"
}
$sourceHash = (Get-FileHash -LiteralPath $moduleFile.FullName -Algorithm SHA256).Hash
$targetHash = (Get-FileHash -LiteralPath $targetFile -Algorithm SHA256).Hash
if ($sourceHash -ne $targetHash) {
throw "The module copy does not match its source: $targetFile"
}
}
}
$scriptTarget = Join-Path $programFiles 'PowerBGInfo'
New-Item -ItemType Directory -Path $scriptTarget -Force | Out-Null
Copy-Item -Path "$share\Scripts\*" -Destination $scriptTarget -Force
$env:ProgramW6432 always points at the 64-bit Program Files, so the script writes to the right place whichever PowerShell runs it.
Step 2, option A (recommended): a Preferences scheduled task
A Group Policy Preferences scheduled task gives you the logon and unlock triggers from Task Scheduler without a registration script.
- Edit the GPO linked to the computers. Go to Computer Configuration > Preferences > Control Panel Settings > Scheduled Tasks.
- New > Scheduled Task (At least Windows 7).
- General tab:
Action: Replace (see Common tab below).
Name:
PowerBGInfo wallpaper.When running the task, use: BUILTIN\Users (Change User or Group).
Run only when user is logged on. Do not tick Run with highest privileges. 4. Triggers tab:
New: At log on, Any user, Delay task for: 30 seconds.
New: On workstation unlock, Any user.
Optional: Daily, Repeat task every: 30 minutes, for a duration of: Indefinitely. 5. Actions tab: Start a program.
Program:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exeArguments, entered on one line with spaces between the parts:
-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Program Files\PowerBGInfo\Set-BGInfoWallpaper.ps1"
- Conditions tab: clear Start the task only if the computer is on AC power.
- Settings tab: If the task is already running: Do not start a new instance; Stop the task if it runs longer than: 1 hour.
- Common tab: tick Remove this item when it is no longer applied. Microsoft documents that this switches the item's action to Replace and deletes the task when the GPO no longer applies.
The task editor in the Group Policy Management Editor is the Task Scheduler editor, so the options match Task Scheduler.
An Immediate Task (At least Windows 7) runs once when Group Policy refreshes and is then removed. That suits a one-off machine render as SYSTEM, not a recurring per-user wallpaper.
Step 2, option B: a user logon script
Simpler, but it runs only at sign-in and never on unlock.
- User Configuration > Policies > Windows Settings > Scripts (Logon/Logoff) > Logon > PowerShell Scripts tab.
- Add
Set-BGInfoWallpaper.ps1(copy it into the GPO folder, or use a UNC path users can read).
Things to know:
- The PowerShell Scripts tab runs Windows PowerShell. For PowerShell 7, add
pwsh.exeon the Scripts tab with-File <path>as parameters. - Windows waits five minutes after sign-in before it runs logon scripts, unless Computer Configuration > Administrative Templates > System > Group Policy > Configure Logon Script Delay is set (
0disables the delay). - Logon scripts run alongside Explorer unless Run logon scripts synchronously is enabled. Leave it off.
- Microsoft notes that a PowerShell logon script can start before the desktop shell is ready and fail its execution policy zone check with "AuthorizationManager check failed". The
BypassandAllSignedpolicies do not do that check.
Execution policy
Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell > Turn on Script Execution sets the execution policy for Windows PowerShell. PowerShell 7 has its own setting under Administrative Templates > PowerShell Core once you install its templates (InstallPSCorePolicyDefinitions.ps1 in $PSHOME); each PowerShell 7 setting can defer to the Windows PowerShell one.
| Policy option | Execution policy |
|---|---|
| Allow only signed scripts | AllSigned |
| Allow local scripts and remote signed scripts | RemoteSigned |
| Allow all scripts | Unrestricted |
| Disabled | Restricted |
A policy set here overrides every other scope, including -ExecutionPolicy Bypass on the task's command line. With Allow only signed scripts, sign Set-BGInfoWallpaper.ps1 and your other scripts. PowerBGInfo itself is signed by Evotec; add its publisher certificate to Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Trusted Publishers in the same GPO, so tasks never stop at the untrusted-publisher prompt (see Security and operations).
The Desktop Wallpaper policy
User Configuration > Administrative Templates > Desktop > Desktop > Desktop Wallpaper sets one wallpaper file for the user and stops them changing it. Microsoft documents that:
- The file can be a local path or a UNC path, and a
.bmpor.jpg. - If the file is not available when the user signs in, no wallpaper is shown.
- The setting does not apply to Remote Desktop server sessions.
PowerBGInfo does not check for this policy. Do not combine it with the per-user task: the two fight over the same setting, and the policy is applied again at the latest at the next sign-in. If you need an enforced wallpaper, let PowerBGInfo produce the file and let the policy show it:
- Run
Set-BGInfoMachineImage.ps1from Task Scheduler as SYSTEM with-OutputFileName Wallpaper.jpg. - Point the policy at
C:\ProgramData\PowerBGInfo\Wallpaper.jpg.
The image then carries machine facts only (no user name), and Windows shows changes the next time it applies the wallpaper, normally at sign-in.
The lock screen policy
Computer Configuration > Administrative Templates > Control Panel > Personalization > Force a specific default lock screen and logon image takes the path of an image, local or UNC, and uses it for the lock screen and the sign-in screen. Microsoft documents that it only applies to Enterprise, Education and Server editions. Pair it with Prevent changing lock screen and logon image so users keep that image.
- Register the SYSTEM task from Task Scheduler (startup and daily) to render
C:\ProgramData\PowerBGInfo\LockScreen.jpgwith-Target File. - Set the policy to
C:\ProgramData\PowerBGInfo\LockScreen.jpg.
PowerBGInfo's own -Target LogonScreen writes the same registry value (HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization\LockScreenImage) only when the per-user lock screen API fails, in both PowerShell 7 and Windows PowerShell 5.1 (see Run in production). Do not use both: the GPO owns that value and overwrites it.
An archived Microsoft support blog (2018) describes how the sign-in screen caches this image: it reloads the file only when its last-modified time is newer than the cached copy. PowerBGInfo rewrites the file on every run, so a newer timestamp is expected; restoring an older copy of the file would not show.
Verify
gpresult /r /scope computer
Get-ScheduledTask -TaskName 'PowerBGInfo wallpaper' |
Select-Object TaskPath, State
Get-ExecutionPolicy -List
Then sign in as a test user and check %LOCALAPPDATA%\PowerBGInfo\last-run.log.
Pitfalls
- The share is not readable by computer accounts. Startup scripts run as the computer; grant
Domain Computersread access. - The logon script appears to do nothing. It is waiting out the five-minute logon script delay.
- Two wallpaper owners. The Desktop Wallpaper policy, a Personalization CSP from Intune or a theme from another tool all override PowerBGInfo.
- The lock screen policy on Pro. It is ignored; see Troubleshooting.
Further reading
- Group Policy Preferences
- Group Policy Preferences common options (archived)
- Scheduled Tasks extension (archived)
- ADMX_Scripts policies
- ADMX_GroupPolicy: Configure Logon Script Delay
- about_Execution_Policies
- about_Group_Policy_Settings
- ADMX_Desktop: Desktop Wallpaper
- ADMX_ControlPanelDisplay: lock screen policies
- Changing the image used in the lock screen policy (archived blog)