Agente para Windows que baixa um manifesto JSON público, valida os arquivos por SHA-256 e aplica o wallpaper da área de trabalho e a tela de bloqueio no contexto do usuário interativo.
Toda a identidade da organização fica centralizada em uma única chave no arquivo WallpaperAgent.Config.psd1:
OrganizationName = 'orgname' # altere para o nome da organizaçãoA partir desse valor, o projeto deriva automaticamente:
- instalação:
C:\ProgramData\{OrganizationName}\WallpaperAgent; - dados por usuário:
%LOCALAPPDATA%\{OrganizationName}\WallpaperAgent; - registro:
HKLM:\SOFTWARE\{OrganizationName}\WallpaperAgent; - pasta de tarefas:
\{OrganizationName}\; - tarefa de atualização:
{OrganizationName} - Wallpaper Update; - tarefa de aplicação:
{OrganizationName} - Wallpaper Apply; - nomes dos mutexes usados para impedir execuções simultâneas.
Todos esses valores podem ser sobrescritos individualmente no arquivo de configuração.
Cada organização que utilizar o projeto deve criar um repositório separado exclusivamente para armazenar o manifesto e as imagens publicadas. O correto é manter dois repositórios independentes:
WallpaperAgent: código do agente, instalação, detecção e documentação;- repositório de conteúdo, por exemplo
WallpaperContent:manifest.json, wallpapers e lock screens.
Não publique imagens e releases dentro do repositório do agente. Essa separação permite atualizar o conteúdo sem alterar, recompilar ou redistribuir o pacote instalado pelo Intune.
O repositório de conteúdo deve ser configurado em WallpaperAgent.Config.psd1:
RepositoryOwner = 'github-owner'
RepositoryName = 'WallpaperContent'
RepositoryBranch = 'main'
RepositoryManifestPath = 'windows/manifest.json'
PublisherTokenEnvironmentVariable = 'WALLPAPER_REPOSITORY_TOKEN'
ManifestUrl = ''Com ManifestUrl vazio, o agente deriva automaticamente:
https://raw.githubusercontent.com/{RepositoryOwner}/{RepositoryName}/{RepositoryBranch}/{RepositoryManifestPath}
Crie um fine-grained personal access token limitado somente ao repositório de conteúdo e conceda a permissão de repositório Contents: Read and write. Esse token é usado pelo servidor, portal ou processo que publica as imagens e atualiza o manifesto.
O valor do token deve ficar em um cofre de segredos ou variável de ambiente no servidor de publicação, usando por padrão o nome configurado em PublisherTokenEnvironmentVariable:
[Environment]::SetEnvironmentVariable(
'WALLPAPER_REPOSITORY_TOKEN',
'github_pat_REPLACE_WITH_REAL_TOKEN',
'Machine'
)Nunca coloque o token no PSD1, no manifesto, no Git, no pacote .intunewin ou nos computadores clientes. O WallpaperAgent somente lê URLs HTTPS e não utiliza o token de escrita. Para esse modelo, o repositório de conteúdo deve ser público. Caso o conteúdo precise ser privado, publique-o por um endpoint intermediário somente leitura; não distribua um token read/write aos dispositivos.
O agente usa duas tarefas agendadas:
-
Wallpaper Update
- executada como
SYSTEM; - inicia com o Windows;
- repete no intervalo definido em
CheckIntervalMinutes; - baixa o manifesto e os assets;
- valida URL, extensão, tamanho, integridade SHA-256 e leitura da imagem;
- mantém o release anterior quando a atualização falha.
- executada como
-
Wallpaper Apply
- executada no grupo interno
INTERACTIVE; - inicia no logon do usuário;
- repete no mesmo intervalo;
- aplica desktop e lock screen no contexto correto do usuário;
- reaplica o padrão caso o usuário altere manualmente a imagem.
- executada no grupo interno
Quando o updater detecta conteúdo novo, ele tenta iniciar imediatamente a tarefa de aplicação. Sem usuário conectado, o conteúdo fica preparado para o próximo logon.
WallpaperAgent/
|-- Agent/
| |-- Apply-Wallpaper.ps1
| `-- Update-Wallpaper.ps1
|-- Intune/
| |-- Detect-WallpaperAgent.ps1
| `-- Detect-WallpaperAgent.template.ps1
|-- docs/
| |-- ARCHITECTURE.md
| |-- CONFIGURATION.md
| |-- INTUNE.md
| `-- MANIFEST.md
|-- WallpaperAgent.Config.psd1
|-- WallpaperAgent.Helpers.psm1
|-- Install-WallpaperAgent.ps1
|-- Uninstall-WallpaperAgent.ps1
|-- Test-WallpaperAgent.ps1
|-- Get-WallpaperAgentDiagnostics.ps1
|-- Build-WallpaperAgentPackage.ps1
|-- Install.cmd
|-- Uninstall.cmd
|-- Install.ps1
|-- Uninstall.ps1
|-- Diagnostics.ps1
|-- CHANGELOG.md
`-- README.md
Os arquivos Install.ps1, Uninstall.ps1 e Diagnostics.ps1 são wrappers de compatibilidade com os nomes do projeto anterior.
Antes de instalar, crie o repositório separado de conteúdo e edite WallpaperAgent.Config.psd1:
OrganizationName = 'orgname'
AgentVersion = '1.0.0'
RepositoryOwner = 'github-owner'
RepositoryName = 'WallpaperContent'
RepositoryBranch = 'main'
RepositoryManifestPath = 'windows/manifest.json'
PublisherTokenEnvironmentVariable = 'WALLPAPER_REPOSITORY_TOKEN'
ManifestUrl = ''
CheckIntervalMinutes = 15Deixe ManifestUrl vazio para gerar a URL pública a partir da configuração do repositório. Use um valor explícito somente para um proxy, CDN ou endpoint HTTPS diferente do GitHub Raw.
Abra o Windows PowerShell 5.1 e execute:
Set-ExecutionPolicy -Scope Process Bypass -Force
.\Test-WallpaperAgent.ps1Para validar também o manifesto remoto:
.\Test-WallpaperAgent.ps1 -TestManifestA validação verifica a configuração, os arquivos do pacote, a plataforma Windows, arquitetura de 64 bits, Scheduled Tasks, System.Drawing e Windows Runtime.
Abra o Windows PowerShell como administrador:
Set-ExecutionPolicy -Scope Process Bypass -Force
.\Install-WallpaperAgent.ps1 -ForceConfigTambém é possível usar:
.\Install.ps1 -ForceConfigou:
Install.cmd-ForceConfig substitui a configuração instalada pela configuração do pacote. Sem esse parâmetro, uma configuração já instalada é preservada durante a atualização.
Para instalar sem tentar baixar o primeiro release imediatamente:
.\Install-WallpaperAgent.ps1 -ForceConfig -SkipInitialUpdate.\Test-WallpaperAgent.ps1 -TestInstalledStateConfirme também as tarefas:
Get-ScheduledTask -TaskPath '\orgname\' |
Select-Object TaskName, StateO caminho real depende de OrganizationName ou de uma sobrescrita em TaskPath.
.\Get-WallpaperAgentDiagnostics.ps1Ou pelo comando compatível:
.\Diagnostics.ps1O diagnóstico mostra:
- configuração resolvida;
- chave de registro de detecção;
- estado e último resultado das tarefas;
status.json;- release atual;
- log de instalação;
- log do updater;
- log de aplicação do usuário atual.
Com OrganizationName = 'orgname':
C:\ProgramData\orgname\WallpaperAgent\
|-- Agent\
| |-- Apply-Wallpaper.ps1
| |-- Update-Wallpaper.ps1
| |-- WallpaperAgent.Config.psd1
| `-- WallpaperAgent.Helpers.psm1
|-- Assets\
| |-- Desktop\
| `-- LockScreen\
|-- State\
| |-- current.json
| |-- manifest.json
| `-- status.json
`-- Logs\
|-- install.log
`-- update.log
Dados por usuário:
%LOCALAPPDATA%\orgname\WallpaperAgent\
|-- current.json
`-- Logs\apply.log
- uma nova release é detectada no intervalo configurado;
- os arquivos só substituem o conteúdo anterior após validação completa;
- falha de rede, JSON inválido, hash incorreto ou imagem corrompida não remove o release funcional;
- sem usuário conectado, o download ocorre normalmente e a aplicação é feita no próximo logon;
- alterações manuais de wallpaper ou lock screen são corrigidas na próxima execução da tarefa de aplicação;
- logs são rotacionados para um arquivo
.1quando atingem o limite configurado.
Gere uma área limpa de empacotamento:
.\Build-WallpaperAgentPackage.ps1A saída será criada em:
Build\WallpaperAgent-{AgentVersion}\
|-- Source\
|-- Detection\Detect-WallpaperAgent.ps1
|-- IntuneWin\
`-- WallpaperAgent-{AgentVersion}-Source.zip
Para também gerar o .intunewin:
.\Build-WallpaperAgentPackage.ps1 `
-IntuneWinAppUtilPath 'C:\Tools\IntuneWinAppUtil.exe'Configuração recomendada do aplicativo Win32:
| Campo | Valor |
|---|---|
| Install command | Install.cmd |
| Uninstall command | Uninstall.cmd |
| Install behavior | System |
| Device restart behavior | No specific action |
| Architecture | 64-bit |
| Detection rules | Use a custom detection script |
| Detection script | arquivo gerado em Detection\Detect-WallpaperAgent.ps1 |
| Run as 32-bit on 64-bit clients | No |
| Enforce script signature check | No, até os scripts serem assinados |
O script de detecção gerado contém a versão esperada do pacote, mas não contém o nome da organização. Ele localiza a instalação pela chave ProductCode = WallpaperAgent e valida os arquivos e tarefas registrados.
Por padrão, a desinstalação mantém Assets para evitar que o Windows continue apontando para uma imagem removida:
.\Uninstall-WallpaperAgent.ps1 -Confirm:$falsePara visualizar antes:
.\Uninstall-WallpaperAgent.ps1 -WhatIfPara remover também os assets:
.\Uninstall-WallpaperAgent.ps1 -RemoveAssets -Confirm:$falseO Uninstall.cmd usa o modo não interativo e preserva os assets.
- somente URLs HTTPS são aceitas;
- o nome do arquivo do asset não pode conter caminho relativo ou absoluto;
- somente
.jpg,.jpege.pngsão aceitos; - cada arquivo é validado por SHA-256 antes da ativação;
- o arquivo baixado é validado como imagem;
- há limites de tamanho para manifesto e assets;
- downloads usam arquivo temporário e promoção atômica;
- o updater executa como
SYSTEM, enquanto a aplicação ocorre no contexto interativo; - a pasta de instalação concede controle total apenas a
SYSTEMe Administradores; usuários recebem leitura e execução.
Ao publicar uma nova versão:
- altere
AgentVersionemWallpaperAgent.Config.psd1; - atualize
CHANGELOG.md; - execute
Build-WallpaperAgentPackage.ps1; - use o novo
.intunewine o script correspondente emDetection; - atribua primeiro ao grupo piloto.
Consulte os arquivos da pasta docs para detalhes de configuração, arquitetura, manifesto e Intune.