Olá, pessoal!

Vocês sabem que aplicar um papel de parede nos computadores da companhia, é uma tarefa muito normal em praticamente todas as empresas, não é verdade?! E executar esta "modesta" atividade via Microsoft Intune parece simples à primeira vista, no entanto, quem já tentou fazer isso em máquinas com Windows 10/11 Pro sabe que a abordagem padrão, usando perfis de restrição de dispositivo, esbarra em algumas limitações.

Este post, inspirado no excelente artigo do MVP 'Gannon Novak' do site SMBtotheCloud vai lhe mostrar através de uma ótimo solução alternativa, como usar scripts PowerShell e a implantação de aplicativos Win32 no Microsoft Intune para aplicar este tipo de configuração. Vamos não apenas configurar o Wallpaper, mas também implementar um método inteligente para atualizá-lo dinamicamente, sem a necessidade de reempacotar e redistribuir o aplicativo ou ajustar o script a cada mudança.

🎰 O Desafio: Por que o método padrão falha no Windows 10 Pro?

A forma mais direta de configurar o papel de parede no Intune é através de um Perfil de Configuração de Dispositivo > Restrições de Dispositivo. Lá, você encontra opções para especificar URLs para as imagens desejadas. Simples, certo? O problema é que essas configurações específicas são aplicáveis apenas às edições Enterprise e Education do Windows 10/11.

Se você tentar aplicar esse perfil a um dispositivo com Windows 10/11 Pro, o status da política no Intune mostrará "Não aplicável". Precisamos então, de um caminho alternativo. Bora!

🎯 A Solução: Scripts PowerShell e o Registro do Windows

Quando as políticas padrão não funcionam, muitas vezes a solução está em manipular diretamente o Registro do Windows. É exatamente isso que faremos. Vamos usar scripts PowerShell para:

  • Criar as chaves e valores necessários no registro para definir a imagem;
  • Baixar a imagem desejada de um local acessível (como o Azure Blob Storage);
  • Configurar o sistema para usar a imagem baixada;

Para distribuir e executar esses scripts de forma gerenciada através do Intune, utilizaremos o recurso de implantação de Aplicativos Win32.

O Script de Instalação (Configuração Inicial)

O primeiro passo é criar um script PowerShell que fará a configuração inicial. Este script será empacotado como um aplicativo Win32, como já informado. Abaixo o código, com as explicações:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Garante que o caminho base no registro exista, senão será criado
New-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP -Force

# Caminho base no registro onde as configurações serão aplicadas
$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP"

# URL da imagem (substitua pelo seu link - Ex: Azure Blob Storage)
$BackgroundImageURL = 'https://seu_storage.blob.core.windows.net/wallpaper/background.jpg'

# Pasta local onde a imagem será salva no cliente
$ImageDestinationFolder = "C:\MDM\images"

# Caminho completo para o arquivo da imagem local
$Backgroundimage = "$ImageDestinationFolder\background.jpg"

# Cria a pasta C:\MDM\images se ela não existir. O -ErrorAction SilentlyContinue evita erros caso a pasta já exista.
md $ImageDestinationFolder -ErrorAction SilentlyContinue

# Usa o BITS (Background Intelligent Transfer Service) para baixar a imagem da URL especificada
Start-BitsTransfer -Source $BackgroundImageURL -Destination "$Backgroundimage"

# Configuração das Chaves do Registro para o Papel de Parede
New-ItemProperty -Path $RegPath -Name DesktopImagePath -Value $backgroundimage -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name DesktopImageUrl -Value $backgroundimage -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name DesktopImageStatus -Value 1 -PropertyType DWORD -Force | Out-Null

exit 0

Pontos importantes sobre este script:

  • URL da Imagem: Você precisa substituir a URL de exemplo ($BackgroundImageURL) pela URL real onde sua imagem está hospedada. O Azure Blob Storage é uma ótima opção, garantindo que a imagem esteja acessível publicamente (ou via SAS token, se necessário, mas o script assume acesso anônimo aqui).

  • Nome do Arquivo: O script assume que a imagem se chamará 'background.jpg'. Manter esse nome é crucial para o funcionamento do script de detecção que veremos a seguir. Se mudar o nome do arquivo, não esqueça de mudar no script.

  • Pasta de Destino: A imagem é salva em ‘C:\MDM\Images’. Certifique-se de que não haja políticas bloqueando a criação ou escrita nesta pasta, ou ajuste o caminho ($ImageDestinationFolder) conforme necessário.


Abaixo, o script de Uninstall, que nada mais é que, a remoção das chaves de registro:

1
2
3
4
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImagePath"
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImageUrl"
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImageStatus"
exit 0

🎰 O Desafio da Atualização e o Script de Detecção Inteligente

Ok, a configuração inicial está resolvida. Mas e se a empresa quiser trocar as imagens de vez em quando, ou para campanhas específicas? Com a abordagem Win32 App padrão, teríamos que:

  • Atualizar a imagem no Blob Storage;
  • (Potencialmente) Alterar o script de instalação se algo mudasse;
  • Reempacotar o script usando a Ferramenta de Preparação de Conteúdo Win32 da Microsoft (IntuneWinAppUtil.exe);
  • Fazer upload da nova versão do arquivo .intunewin para o Intune;
  • Aguardar a distribuição e instalação nos clientes;

Isso é trabalhoso e propenso a erros. A beleza da solução proposta pelo 'Gannon Novak' está no script de detecção personalizado.

O Intune, ao implantar um aplicativo Win32, usa regras de detecção para verificar se o aplicativo já está instalado corretamente. Normalmente, isso envolve verificar a existência de um arquivo, pasta ou chave de registro específica. No nosso caso, usaremos um script PowerShell personalizado como regra de detecção.

Este script de detecção fará o seguinte:

  1. Baixará a versão atual da imagem (background.jpg) do Blob Storage para uma pasta temporária;
  2. Comparará a data/hora da última modificação (timestamp) dessa imagem recém-baixada com a imagem que já está na pasta C:\MDM\images do cliente;
  3. Verificará também se as chaves de registro relevantes estão configuradas corretamente;
  4. Se o timestamp da imagem local e remota coincidirem e as chaves de registro estiverem corretas, o script retornará “Detected” (indicando que a versão correta já está instalada).
  5. Se os timestamp diferirem (significando que a imagem no Blob Storage foi atualizada) ou se as chaves de registro estiverem incorretas, o script sairá com um código de erro (exit 1), sinalizando ao Intune que a "aplicação" (nossa imagem e configurações) não está no estado desejado. Isso fará com que o Intune execute novamente o script de instalação (Parte 1), que baixará a nova imagem e reconfigurará o registro.
    Isso permite que você simplesmente substitua o arquivo background.jpg no seu Blob Storage. Na próxima vez que o Intune avaliar a política de detecção nos clientes (o que ocorre periodicamente), ele perceberá a mudança nos timestamps e automaticamente executará o script de instalação para atualizar a imagem nos endpoints, sem nenhuma intervenção manual no Intune!


    Script de detecção:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# URL da imagem (DEVE ser a mesma do script de instalação)
$BackgroundImageURL = 'https://seu_storage.blob.core.windows.net/wallpaper/background.jpg'

# Pasta temporária para baixar a imagem para verificação
$TempImageDestinationFolder = "C:\MDM\images\temp"

# Caminho completo para o arquivo temporário
$TempBackgroundimage = "$TempImageDestinationFolder\background.jpg"

# Caminho da imagem atualmente em uso no cliente
$CurrentBackgroundImage = "C:\MDM\images\background.jpg"

# --- Criação do Diretório Temporário ---
md $TempImageDestinationFolder -ErrorAction SilentlyContinue

# Baixa a imagem mais recentes do Blob para a pasta temporária
Start-BitsTransfer -Source $BackgroundImageURL -Destination "$TempBackgroundimage"

# Pega o timestamp da imagem de fundo baixada do Blob
$BlobBackgroundTimestamp = Get-ItemProperty "$TempBackgroundimage" | Select-Object -ExpandProperty LastWriteTime

# Pega o timestamp da imagem de fundo atualmente no cliente (se existir)
$CurrentBackgroundTimestamp = Get-ItemProperty "$CurrentBackgroundImage" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty LastWriteTime

# Verifica se os valores de registro esperados existem e estão corretos
$RegDesktopPath = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImagePath" -ErrorAction SilentlyContinue
$RegDesktopStatus = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImageStatus" -ErrorAction SilentlyContinue
$RegDesktopUrl = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "DesktopImageUrl" -ErrorAction SilentlyContinue

# Remove a pasta temporária e seu conteúdo após a verificação
Remove-Item -Path $TempImageDestinationFolder -Recurse -Force -ErrorAction SilentlyContinue

# Compara os timestamps e os valores do registro
If (($CurrentBackgroundTimestamp -eq $BlobBackgroundTimestamp) -and 
    ($RegDesktopStatus -eq 1) -and 
    ($RegDesktopPath -eq $CurrentBackgroundImage) -and ($RegDesktopUrl -eq $CurrentBackgroundImage))
{
    # Se tudo estiver correto e atualizado, escreve "Detected" para o Intune
    Write-Host "Detected"
    exit 0
}
Else 
{
    # Se algo estiver desatualizado ou incorreto, informa e sai com erro (força a reinstalação)
    Write-Host "Imagem desatualizada ou valores de registro ausentes/incorretos."
    exit 1
}

📦 Empacotando e Implantando via Intune

Agora que temos os dois scripts (instalação e detecção), precisamos empacotar o script de instalação como um aplicativo Win32 e configurá-lo no Intune.

  • Salve os Scripts: Salve o script de instalação como install.ps1 e o script de detecção como detect.ps1;
  • Baixe a Ferramenta de Preparação: Obtenha a Ferramenta de Preparação de Conteúdo do Microsoft Win32 (IntuneWinAppUtil.exe) no GitHub oficial da Microsoft: Microsoft Win32 Content Prep Tool
  • Empacote o Script de Instalação:
  • Crie uma pasta de origem (ex: C:\Fonte_wallpaper) e coloque o install.ps1 dentro dela;
  • Crie uma pasta de saída (ex: C:\Build_wallpaper);
  • Abra o Prompt de Comando ou PowerShell, navegue até onde você salvou o IntuneWinAppUtil.exe e execute:
    1
    
    IntuneWinAppUtil.exe -c C:\Fonte_wallpaper -s install.ps1 -o C:\Build_wallpaper
    

    Será criado o arquivo install.intunewin no diretório de saída. É ele que você fará *upload para o Intune.*

Intunewin Obs: Criei a origem e a saída no mesmo diretório, mas recomendo que façam em diretórios separados, para mitigar possíveis erros.

Agora, vamos criar o Aplicativo no Intune:

  1. Vá para o portal do Microsoft Intune;
  2. Navegue até Apps > Windows > + Create;
  3. App Type: Windows App (Win32);
  4. App information: Selecione o arquivo install.intunewin que você criou;
  5. Preencha os detalhes (Name, Description, Publisher, Category, etc);
  • Install command: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File .\install.ps1
  • Uninstall command (Opcional): %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File .\uninstall.ps1
    • Você precisaria criar este uninstall.ps1 e empacotá-lo junto se quiser essa funcionalidade;
    • É recomendado ter um script que remova as chaves de registro, se necessário;
  • Install behavior: System (para garantir permissões adequadas para escrever em HKLM e C:\MDM);
  • Requirements: Especifique a arquitetura do SO (32/64 bits) e a versão mínima do Windows;
  • Detection rules:
    • Rules format: Use a custom detection script;
    • Script file: Faça upload do seu arquivo detect.ps1;
    • Run script as 32-bit process on 64-bit clients: Não (geralmente);
    • Enforce script signature check and run script silently: Não (a menos que seus scripts estejam assinados);
  • Dependencies: (Geralmente não necessário para este caso);
  • Supersedence: (Geralmente não necessário para este caso);
  • Assignments: Atribua o aplicativo aos grupos de dispositivos desejados (ex: Todos os dispositivos Windows);
  • Review + create: Revise todas as configurações e crie o aplicativo;

ConfigApp Detect

✅ Conclusão

Embora a configuração inicial de papel de parede no Windows 10/11 Pro via Intune exija uma solução alternativa usando scripts e aplicativos Win32, a abordagem detalhada aqui oferece uma flexibilidade significativa.

Ao combinar um script de instalação com um script de detecção inteligente baseado em *timestamp* de arquivo, você pode não apenas definir as imagens corporativas, mas também atualizá-las dinamicamente simplesmente alterando os arquivos de origem em seu repositório (como o Blob Storage), sem precisar tocar na configuração do Intune novamente.

Esta técnica demonstra o poder da automação com PowerShell e a flexibilidade da implantação de aplicativos Win32 no Intune para superar limitações e gerenciar configurações complexas de forma eficiente.

Espero que este tutorial ajude você a manter um ambiente de trabalho padronizado e atualizado para seus usuários do Windows 10/11 Pro!

Bom, é isso hoje. Até a próxima! 🤘