MS-IN-002 - Papel De Parede E Tela De Bloqueio Por Política

ID: KB-MS-IN-002

Responsável: Thiago Amaral, TI

Status: Publicado

Última Atualização: 04/07/2025


Propósito

Instruir a definir um papel de parede e tela de bloqueio utilizando o Intune.

Aplica-se a

  • TI.

Pré-requisitos

  • Conhecimento básico com o centro de administração do Intune.

  • Conhecimento básico de powershell.

  • Intunewin instalado em uma máquina com Windows.

  • Papeis de parede da FCT Consig.

  • Conta de administrador do Intune ou Global.


Instruções

1. Preparando O Script Do Papel De Parede Com .intunewin

  1. Crie um scriptpowershellde instalação.

    • install.ps1

      # Instalacao do Pacote de Papel de Parede FCT
      # Versao 2.3 - Sobrescrita Automatica com Deteccao por Hash
      
      $PackageName = "WallpaperFCT"
      $ValidationFile = "C:\\ProgramData\\scloud\\Validation\\$PackageName"
      $DestinationFolder = Join-Path $env:ProgramData $PackageName
      
      Start-Transcript -Path "$env:ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\\$PackageName-install.log" -Force
      $ErrorActionPreference = "Continue"
      
      Write-Output "Iniciando instalacao do $PackageName versao 2.3."
      Write-Output "Modo: Sobrescrita automatica com deteccao por hash."
      
      # --- Etapa 1: Limpeza Previa Automatica ---
      Write-Output "=== ETAPA 1: LIMPEZA PREVIA ==="
      
      # Verificar instalacao anterior
      $PreviousInstallation = $false
      $PreviousHash = $null
      
      if (Test-Path $ValidationFile) {
          try {
              $DetectionContent = Get-Content -Path $ValidationFile -Raw
              if ($DetectionContent) {
                  try {
                      $DetectionInfo = $DetectionContent | ConvertFrom-Json
                      Write-Output "Instalacao anterior encontrada:"
                      Write-Output "  - Versao: $($DetectionInfo.Version)"
                      Write-Output "  - Instalada em: $($DetectionInfo.InstallDate)"
                      if ($DetectionInfo.ContentHash) {
                          Write-Output "  - Hash anterior: $($DetectionInfo.ContentHash)"
                          $PreviousHash = $DetectionInfo.ContentHash
                      }
                      $PreviousInstallation = $true
                  } catch {
                      Write-Output "Instalacao anterior encontrada (formato legado): $DetectionContent"
                      $PreviousInstallation = $true
                  }
              }
          } catch {
              Write-Output "Arquivo de deteccao encontrado, mas com erro de leitura."
              $PreviousInstallation = $true
          }
      }
      
      # SEMPRE executar limpeza previa
      Write-Output "Executando limpeza previa automatica..."
      
      # Remover pasta de destino se existir
      if (Test-Path $DestinationFolder) {
          try {
              Write-Output "Removendo instalacao anterior: $DestinationFolder"
              Remove-Item -Path $DestinationFolder -Recurse -Force
      
              if (-not (Test-Path $DestinationFolder)) {
                  Write-Output "OK Instalacao anterior removida com sucesso."
              } else {
                  Write-Output "AVISO: Pasta ainda existe apos remocao."
              }
          } catch {
              Write-Output "ERRO ao remover instalacao anterior: $($_.Exception.Message)"
              Write-Output "Continuando com a instalacao..."
          }
      } else {
          Write-Output "Nenhuma instalacao anterior encontrada."
      }
      
      # Limpar configuracoes de registro anteriores
      Write-Output "Limpando configuracoes anteriores do registro..."
      
      # Limpar tela de bloqueio anterior
      $LockScreenRegPath = "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Personalization"
      if (Test-Path $LockScreenRegPath) {
          try {
              $removedItems = @()
      
              if (Get-ItemProperty -Path $LockScreenRegPath -Name "LockScreenImage" -ErrorAction SilentlyContinue) {
                  Remove-ItemProperty -Path $LockScreenRegPath -Name "LockScreenImage" -ErrorAction SilentlyContinue
                  $removedItems += "LockScreenImage"
              }
      
              if (Get-ItemProperty -Path $LockScreenRegPath -Name "NoChangingLockScreen" -ErrorAction SilentlyContinue) {
                  Remove-ItemProperty -Path $LockScreenRegPath -Name "NoChangingLockScreen" -ErrorAction SilentlyContinue
                  $removedItems += "NoChangingLockScreen"
              }
      
              if ($removedItems.Count -gt 0) {
                  Write-Output "OK Configuracoes de tela de bloqueio removidas: $($removedItems -join ', ')"
              } else {
                  Write-Output "Configuracoes de tela de bloqueio ja limpas."
              }
          } catch {
              Write-Output "Configuracoes de tela de bloqueio ja limpas ou nao existiam."
          }
      }
      
      # Limpar RunOnce anterior
      $RunOnceKey = "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
      if (Test-Path $RunOnceKey) {
          try {
              if (Get-ItemProperty -Path $RunOnceKey -Name "SetUserWallpaperFCT" -ErrorAction SilentlyContinue) {
                  Remove-ItemProperty -Path $RunOnceKey -Name "SetUserWallpaperFCT" -ErrorAction SilentlyContinue
                  Write-Output "OK Gatilho de logon anterior removido."
              } else {
                  Write-Output "Gatilho de logon anterior ja removido."
              }
          } catch {
              Write-Output "Gatilho de logon anterior ja removido ou nao existia."
          }
      }
      
      Write-Output "OK Limpeza previa concluida. Iniciando instalacao limpa..."
      
      # --- Etapa 2: Criar estrutura de diretorios ---
      Write-Output "=== ETAPA 2: CRIACAO DE DIRETORIOS ==="
      
      try {
          # Criar pasta de validacao
          $ValidationFolder = Split-Path $ValidationFile -Parent
          if (-not (Test-Path $ValidationFolder)) {
              New-Item -Path $ValidationFolder -ItemType Directory -Force | Out-Null
              Write-Output "OK Pasta de validacao criada: $ValidationFolder"
          }
      
          # Criar pasta de destino
          if (-not (Test-Path $DestinationFolder)) {
              New-Item -Path $DestinationFolder -ItemType Directory -Force | Out-Null
              Write-Output "OK Pasta de destino criada: $DestinationFolder"
          }
      } catch {
          Write-Output "ERRO ao criar diretorios: $($_.Exception.Message)"
          exit 1
      }
      
      # --- Etapa 3: Copiar arquivos de imagem ---
      Write-Output "=== ETAPA 3: COPIA DE ARQUIVOS ==="
      
      $CurrentPath = Split-Path -Parent $MyInvocation.MyCommand.Path
      $ImageFiles = @("wallpaper.jpg", "lockscreen.jpg", "wallpaper.png", "lockscreen.png", "Wallpaper.png", "Lockscreen.png")
      $CopiedFiles = @()
      
      foreach ($ImageFile in $ImageFiles) {
          $SourcePath = Join-Path $CurrentPath $ImageFile
          $DestPath = Join-Path $DestinationFolder $ImageFile
      
          if (Test-Path $SourcePath) {
              try {
                  Copy-Item -Path $SourcePath -Destination $DestPath -Force
      
                  if (Test-Path $DestPath) {
                      $FileSize = (Get-Item $DestPath).Length
                      Write-Output "OK $ImageFile copiado com sucesso ($([math]::Round($FileSize/1KB, 2)) KB)"
                      $CopiedFiles += $ImageFile
                  } else {
                      Write-Output "ERRO: $ImageFile nao foi copiado corretamente."
                  }
              } catch {
                  Write-Output "ERRO ao copiar $ImageFile : $($_.Exception.Message)"
              }
          } else {
              Write-Output "AVISO: $ImageFile nao encontrado no pacote."
          }
      }
      
      if ($CopiedFiles.Count -eq 0) {
          Write-Output "ERRO CRITICO: Nenhum arquivo de imagem foi copiado."
          exit 1
      }
      
      Write-Output "OK $($CopiedFiles.Count) arquivo(s) copiado(s) com sucesso."
      
      # --- Etapa 4: Calcular hash do conteudo ---
      Write-Output "=== ETAPA 4: CALCULO DE HASH ==="
      
      $ContentHashes = @()
      foreach ($CopiedFile in $CopiedFiles) {
          $FilePath = Join-Path $DestinationFolder $CopiedFile
          if (Test-Path $FilePath) {
              try {
                  $FileHash = (Get-FileHash -Path $FilePath -Algorithm SHA256).Hash
                  $ContentHashes += "$CopiedFile`:$FileHash"
                  Write-Output "Hash de $CopiedFile : $FileHash"
              } catch {
                  Write-Output "AVISO: Erro ao calcular hash de $CopiedFile"
              }
          }
      }
      
      # Criar hash combinado de todo o conteudo
      if ($ContentHashes.Count -gt 0) {
          $HashString = $ContentHashes -join "|"
          $CombinedHash = (Get-FileHash -Algorithm SHA256 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($HashString)))).Hash
      } else {
          $CombinedHash = "NO_FILES_FOUND"
      }
      Write-Output "Hash combinado do pacote: $CombinedHash"
      
      # Verificar se e uma atualizacao real
      if ($PreviousHash -and $PreviousHash -eq $CombinedHash) {
          Write-Output "AVISO: Hash identico a instalacao anterior. Conteudo nao mudou."
          Write-Output "Continuando com a instalacao para garantir configuracoes atualizadas..."
      } elseif ($PreviousHash) {
          Write-Output "OK Nova versao detectada (hash diferente). Prosseguindo com atualizacao..."
      } else {
          Write-Output "OK Primeira instalacao detectada. Prosseguindo..."
      }
      
      # --- Etapa 5: Configurar tela de bloqueio ---
      Write-Output "=== ETAPA 5: CONFIGURACAO DA TELA DE BLOQUEIO ==="
      
      # Procurar arquivo de tela de bloqueio (varios formatos possiveis)
      $LockScreenPath = $null
      $LockScreenFiles = @("lockscreen.jpg", "lockscreen.png", "Lockscreen.png", "Lockscreen.jpg")
      
      foreach ($LockFile in $LockScreenFiles) {
          $TestPath = Join-Path $DestinationFolder $LockFile
          if (Test-Path $TestPath) {
              $LockScreenPath = $TestPath
              break
          }
      }
      
      if ($LockScreenPath) {
          try {
              # Criar chave de registro se nao existir
              if (-not (Test-Path $LockScreenRegPath)) {
                  New-Item -Path $LockScreenRegPath -Force | Out-Null
                  Write-Output "OK Chave de registro criada: $LockScreenRegPath"
              }
      
              # Configurar imagem da tela de bloqueio
              Set-ItemProperty -Path $LockScreenRegPath -Name 'LockScreenImage' -Value $LockScreenPath -Force
      
              # Impedir alteracao da tela de bloqueio
              Set-ItemProperty -Path $LockScreenRegPath -Name 'NoChangingLockScreen' -Value 1 -Force
      
              Write-Output "OK Tela de bloqueio configurada: $LockScreenPath"
          } catch {
              Write-Output "ERRO ao configurar tela de bloqueio: $($_.Exception.Message)"
          }
      } else {
          Write-Output "AVISO: Arquivo de tela de bloqueio nao encontrado. Pulando configuracao."
      }
      
      # --- Etapa 6: Configurar papel de parede via RunOnce ---
      Write-Output "=== ETAPA 6: CONFIGURACAO DO PAPEL DE PAREDE ==="
      
      # Procurar arquivo de papel de parede (varios formatos possiveis)
      $WallpaperPath = $null
      $WallpaperFiles = @("wallpaper.jpg", "wallpaper.png", "Wallpaper.png", "Wallpaper.jpg")
      
      foreach ($WallFile in $WallpaperFiles) {
          $TestPath = Join-Path $DestinationFolder $WallFile
          if (Test-Path $TestPath) {
              $WallpaperPath = $TestPath
              break
          }
      }
      
      if ($WallpaperPath) {
          try {
              # Criar script inline para aplicar papel de parede no proximo logon
              $WallpaperScript = @"
      Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class Wallpaper { [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); public static void SetWallpaper(string path) { SystemParametersInfo(20, 0, path, 3); } }'
      [Wallpaper]::SetWallpaper('$WallpaperPath')
      "@
      
              # Codificar script em Base64 para evitar problemas com aspas
              $EncodedScript = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($WallpaperScript))
      
              # Configurar RunOnce para aplicar no proximo logon
              $RunOnceCommand = "powershell.exe -WindowStyle Hidden -EncodedCommand $EncodedScript"
              Set-ItemProperty -Path $RunOnceKey -Name 'SetUserWallpaperFCT' -Value $RunOnceCommand -Force
      
              Write-Output "OK Papel de parede configurado para aplicacao no proximo logon: $WallpaperPath"
          } catch {
              Write-Output "ERRO ao configurar papel de parede: $($_.Exception.Message)"
          }
      } else {
          Write-Output "AVISO: Arquivo de papel de parede nao encontrado. Pulando configuracao."
      }
      
      # --- Etapa 7: Criar arquivo de deteccao com hash ---
      Write-Output "=== ETAPA 7: CRIACAO DO ARQUIVO DE DETECCAO ==="
      
      try {
          $DetectionInfo = @{
              PackageName = $PackageName
              Version = "2.3"
              InstallDate = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
              ContentHash = $CombinedHash
              InstalledFiles = $CopiedFiles
              WallpaperPath = if (Test-Path $WallpaperPath) { $WallpaperPath } else { $null }
              LockScreenPath = if (Test-Path $LockScreenPath) { $LockScreenPath } else { $null }
              InstallationMethod = "AutoOverwrite"
          } | ConvertTo-Json -Depth 3
      
          $DetectionInfo | Out-File -FilePath $ValidationFile -Encoding UTF8 -Force
      
          if (Test-Path $ValidationFile) {
              Write-Output "OK Arquivo de deteccao criado com sucesso."
              Write-Output "Hash registrado: $CombinedHash"
          } else {
              Write-Output "ERRO: Arquivo de deteccao nao foi criado."
          }
      } catch {
          Write-Output "ERRO ao criar arquivo de deteccao: $($_.Exception.Message)"
      }
      
      # --- Etapa 8: Aplicar configuracoes imediatamente (se possivel) ---
      Write-Output "=== ETAPA 8: APLICACAO IMEDIATA ==="
      
      try {
          # Tentar aplicar papel de parede imediatamente se ha usuario logado
          $LoggedUsers = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName
      
          if ($LoggedUsers -and (Test-Path $WallpaperPath)) {
              Write-Output "Tentando aplicar papel de parede imediatamente..."
      
              # Aplicar papel de parede usando rundll32
              $ApplyCommand = "rundll32.exe user32.dll,UpdatePerUserSystemParameters"
              Start-Process -FilePath "rundll32.exe" -ArgumentList "user32.dll,UpdatePerUserSystemParameters" -Wait -WindowStyle Hidden
      
              Write-Output "OK Comando de atualizacao do sistema executado."
          } else {
              Write-Output "Papel de parede sera aplicado no proximo logon do usuario."
          }
      } catch {
          Write-Output "Aplicacao imediata nao foi possivel. Sera aplicado no proximo logon."
      }
      
      # --- Etapa 9: Relatorio final ---
      Write-Output ""
      Write-Output "=== RELATORIO DE INSTALACAO ==="
      Write-Output "Pacote: $PackageName"
      Write-Output "Versao: 2.3 (Sobrescrita Automatica)"
      Write-Output "Data/Hora: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
      Write-Output "Hash do Conteudo: $CombinedHash"
      Write-Output "Pasta de Instalacao: $DestinationFolder"
      Write-Output "Arquivos Instalados: $($CopiedFiles -join ', ')"
      
      # Verificar status final
      $InstallationSuccess = $true
      $Issues = @()
      
      if (-not (Test-Path $ValidationFile)) {
          $InstallationSuccess = $false
          $Issues += "Arquivo de deteccao nao criado"
      }
      
      if ($CopiedFiles.Count -eq 0) {
          $InstallationSuccess = $false
          $Issues += "Nenhum arquivo de imagem copiado"
      }
      
      if (-not (Test-Path $DestinationFolder)) {
          $InstallationSuccess = $false
          $Issues += "Pasta de destino nao criada"
      }
      
      if ($InstallationSuccess) {
          Write-Output "Status: INSTALACAO COMPLETA - OK"
          Write-Output ""
          Write-Output "PROXIMOS PASSOS:"
          Write-Output "1. A tela de bloqueio ja esta configurada e ativa"
          Write-Output "2. O papel de parede sera aplicado no proximo logon do usuario"
          Write-Output "3. Para aplicar imediatamente, o usuario pode fazer logoff/logon"
          Write-Output ""
          Write-Output "DETECCAO INTUNE:"
          Write-Output "Arquivo: $ValidationFile"
          Write-Output "Metodo: Arquivo existe + Hash de conteudo"
      } else {
          Write-Output "Status: INSTALACAO COM PROBLEMAS"
          Write-Output "Problemas encontrados:"
          $Issues | ForEach-Object { Write-Output "  - $_" }
      }
      
      Write-Output "================================="
      Write-Output ""
      Write-Output "Instalacao do $PackageName concluida"
      
      Stop-Transcript
      
      # Retornar codigo de saida apropriado
      if ($InstallationSuccess) {
          exit 0
      } else {
          exit 1
      }
      
  2. Crie um script powershell de desinstalação.

    • uninstall.ps1

      # Desinstalação do Pacote de Papel de Parede FCT
      # Versão 2.3 - Compatível com Install.ps1 v2.3 (Hash Detection)
      
      $PackageName = "WallpaperFCT"
      $ValidationFile = "C:\\ProgramData\\scloud\\Validation\\$PackageName"
      $DestinationFolder = Join-Path $env:ProgramData $PackageName
      
      Start-Transcript -Path "$env:ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\\$PackageName-uninstall.log" -Force
      $ErrorActionPreference = "Continue"
      
      Write-Output "Iniciando desinstalação do $PackageName versão 2.3."
      
      # --- Etapa 0: Validar se o pacote está instalado ---
      Write-Output "=== ETAPA 0: VERIFICAÇÃO DE INSTALAÇÃO ==="
      $PackageInstalled = $false
      $InstallationInfo = $null
      
      if (Test-Path $ValidationFile) {
          try {
              $DetectionContent = Get-Content -Path $ValidationFile -Raw
              if ($DetectionContent) {
                  # Tentar fazer parse como JSON primeiro (formato v2.3)
                  try {
                      $InstallationInfo = $DetectionContent | ConvertFrom-Json
                      Write-Output "✅ Pacote encontrado (formato v2.3):"
                      Write-Output "  - Versão: $($InstallationInfo.Version)"
                      Write-Output "  - Instalado em: $($InstallationInfo.InstallDate)"
                      Write-Output "  - Hash do conteúdo: $($InstallationInfo.ContentHash)"
                      Write-Output "  - Método de instalação: $($InstallationInfo.InstallationMethod)"
                      if ($InstallationInfo.InstalledFiles) {
                          Write-Output "  - Arquivos: $($InstallationInfo.InstalledFiles -join ', ')"
                      }
                      $PackageInstalled = $true
                  } catch {
                      # Se não for JSON, assumir que é arquivo de versão simples (formato legado)
                      Write-Output "✅ Pacote encontrado (formato legado): $DetectionContent"
                      $PackageInstalled = $true
                  }
              }
          } catch {
              Write-Output "⚠️ Arquivo de detecção encontrado, mas com erro de leitura. Continuando com desinstalação..."
              $PackageInstalled = $true
          }
      } else {
          Write-Output "Arquivo de detecção não encontrado."
      }
      
      if (Test-Path $DestinationFolder) {
          Write-Output "✅ Pasta de instalação encontrada: $DestinationFolder"
          $PackageInstalled = $true
      }
      
      if (-not $PackageInstalled) {
          Write-Output "⚠️ Pacote não parece estar instalado. Executando limpeza preventiva..."
      } else {
          Write-Output "✅ Instalação detectada. Prosseguindo com desinstalação completa..."
      }
      
      # --- Etapa 1: Remover chaves de registro da tela de bloqueio (HKLM) ---
      Write-Output "=== ETAPA 1: LIMPEZA DA TELA DE BLOQUEIO ==="
      $LockScreenRegPath = "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Personalization"
      
      try {
          if (Test-Path $LockScreenRegPath) {
              # Verificar e remover propriedades específicas
              $lockScreenProps = Get-ItemProperty -Path $LockScreenRegPath -ErrorAction SilentlyContinue
              $removedItems = @()
      
              if ($lockScreenProps -and $lockScreenProps.PSObject.Properties.Name -contains "LockScreenImage") {
                  Remove-ItemProperty -Path $LockScreenRegPath -Name "LockScreenImage" -ErrorAction SilentlyContinue
                  $removedItems += "LockScreenImage"
              }
      
              if ($lockScreenProps -and $lockScreenProps.PSObject.Properties.Name -contains "NoChangingLockScreen") {
                  Remove-ItemProperty -Path $LockScreenRegPath -Name "NoChangingLockScreen" -ErrorAction SilentlyContinue
                  $removedItems += "NoChangingLockScreen"
              }
      
              if ($removedItems.Count -gt 0) {
                  Write-Output "✅ Propriedades removidas: $($removedItems -join ', ')"
              } else {
                  Write-Output "Propriedades de tela de bloqueio já removidas."
              }
      
              # Verificar se a chave ficou vazia e remover se necessário
              $remainingProps = Get-ItemProperty -Path $LockScreenRegPath -ErrorAction SilentlyContinue
              if (-not $remainingProps -or ($remainingProps.PSObject.Properties.Name | Where-Object { $_ -notlike "PS*" }).Count -eq 0) {
                  Remove-Item -Path $LockScreenRegPath -Force -ErrorAction SilentlyContinue
                  Write-Output "✅ Chave de registro da tela de bloqueio removida completamente."
              }
          } else {
              Write-Output "Chave de registro da tela de bloqueio não encontrada."
          }
      } catch {
          Write-Output "❌ Erro ao processar configurações da tela de bloqueio: $($_.Exception.Message)"
      }
      
      # --- Etapa 2: Remover gatilho de logon do papel de parede (HKLM) ---
      Write-Output "=== ETAPA 2: LIMPEZA DO GATILHO DE LOGON ==="
      $RunOnceKey = "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
      
      try {
          if (Test-Path $RunOnceKey) {
              $runOnceProps = Get-ItemProperty -Path $RunOnceKey -Name "SetUserWallpaperFCT" -ErrorAction SilentlyContinue
              if ($runOnceProps) {
                  Remove-ItemProperty -Path $RunOnceKey -Name "SetUserWallpaperFCT" -Force
                  Write-Output "✅ Gatilho de logon (RunOnce) removido."
              } else {
                  Write-Output "Gatilho de logon não encontrado."
              }
          }
      } catch {
          Write-Output "❌ Erro ao remover gatilho de logon: $($_.Exception.Message)"
      }
      
      # --- Etapa 3: Limpeza das Configurações do Usuário (HKCU) ---
      Write-Output "=== ETAPA 3: LIMPEZA DAS CONFIGURAÇÕES DO USUÁRIO ==="
      
      try {
          # Limpar configurações do slideshow no perfil do usuário atual
          $wallpapersKey = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Wallpapers"
          if (Test-Path $wallpapersKey) {
              # Resetar tipo de fundo para papel de parede estático (0)
              Set-ItemProperty -Path $wallpapersKey -Name 'BackgroundType' -Value 0 -Force -ErrorAction SilentlyContinue
      
              # Remover diretório do slideshow se existir
              $slideshowProps = Get-ItemProperty -Path $wallpapersKey -ErrorAction SilentlyContinue
              if ($slideshowProps -and $slideshowProps.PSObject.Properties.Name -contains "SlideshowDirectoryPath1") {
                  Remove-ItemProperty -Path $wallpapersKey -Name 'SlideshowDirectoryPath1' -ErrorAction SilentlyContinue
                  Write-Output "✅ Configurações de slideshow do usuário removidas."
              }
          }
      
          # Limpar restrições de alteração de papel de parede
          $policyPath = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\ActiveDesktop"
          if (Test-Path $policyPath) {
              $policyProps = Get-ItemProperty -Path $policyPath -ErrorAction SilentlyContinue
              if ($policyProps -and $policyProps.PSObject.Properties.Name -contains "NoChangingWallPaper") {
                  Remove-ItemProperty -Path $policyPath -Name 'NoChangingWallPaper' -ErrorAction SilentlyContinue
                  Write-Output "✅ Restrições de alteração de papel de parede removidas."
              }
      
              # Se a chave ficou vazia, remover
              $remainingPolicyProps = Get-ItemProperty -Path $policyPath -ErrorAction SilentlyContinue
              if (-not $remainingPolicyProps -or ($remainingPolicyProps.PSObject.Properties.Name | Where-Object { $_ -notlike "PS*" }).Count -eq 0) {
                  Remove-Item -Path $policyPath -Force -ErrorAction SilentlyContinue
                  Write-Output "✅ Chave de política de desktop removida."
              }
          }
      
          # Restaurar papel de parede padrão do Windows
          $defaultWallpapers = @(
              "$env:SystemRoot\\Web\\Wallpaper\\Windows\\img0.jpg",
              "$env:SystemRoot\\Web\\Wallpaper\\Theme1\\img1.jpg",
              "$env:SystemRoot\\Web\\Wallpaper\\Theme2\\img1.jpg"
          )
      
          $wallpaperRestored = $false
          foreach ($wallpaper in $defaultWallpapers) {
              if (Test-Path $wallpaper) {
                  Set-ItemProperty -Path 'HKCU:\\Control Panel\\Desktop' -Name 'Wallpaper' -Value $wallpaper -Force
                  Write-Output "✅ Papel de parede padrão restaurado: $wallpaper"
                  $wallpaperRestored = $true
                  break
              }
          }
      
          if (-not $wallpaperRestored) {
              # Fallback: limpar o papel de parede
              Set-ItemProperty -Path 'HKCU:\\Control Panel\\Desktop' -Name 'Wallpaper' -Value '' -Force
              Write-Output "✅ Papel de parede limpo (sem imagem de fundo)."
          }
      
      } catch {
          Write-Output "❌ Erro ao limpar configurações do usuário: $($_.Exception.Message)"
      }
      
      # --- Etapa 4: Remover arquivos com validação ---
      Write-Output "=== ETAPA 4: REMOÇÃO DE ARQUIVOS ==="
      
      if (Test-Path $DestinationFolder) {
          try {
              # Listar arquivos antes de remover (para log)
              $FilesToRemove = Get-ChildItem -Path $DestinationFolder -Recurse -ErrorAction SilentlyContinue
              if ($FilesToRemove) {
                  Write-Output "Arquivos a serem removidos:"
                  $FilesToRemove | ForEach-Object {
                      $size = if ($_.PSIsContainer) { "<DIR>" } else { "$([math]::Round($_.Length/1KB, 2)) KB" }
                      Write-Output "  - $($_.Name) ($size)"
                  }
              }
      
              # Remover a pasta e todo o conteúdo
              Remove-Item -Path $DestinationFolder -Recurse -Force
      
              # Verificar se foi removida com sucesso
              if (-not (Test-Path $DestinationFolder)) {
                  Write-Output "✅ Pasta de conteúdo $DestinationFolder removida com sucesso."
              } else {
                  Write-Output "⚠️ AVISO: Pasta $DestinationFolder ainda existe após tentativa de remoção."
              }
          } catch {
              Write-Output "❌ Erro ao remover pasta $DestinationFolder : $($_.Exception.Message)"
          }
      } else {
          Write-Output "Pasta de conteúdo não encontrada."
      }
      
      # --- Etapa 5: Remover arquivo de validação ---
      Write-Output "=== ETAPA 5: REMOÇÃO DO ARQUIVO DE DETECÇÃO ==="
      
      if (Test-Path $ValidationFile) {
          try {
              Remove-Item -Path $ValidationFile -Force
      
              # Verificar se foi removido com sucesso
              if (-not (Test-Path $ValidationFile)) {
                  Write-Output "✅ Arquivo de validação removido com sucesso."
              } else {
                  Write-Output "⚠️ AVISO: Arquivo de validação ainda existe após tentativa de remoção."
              }
          } catch {
              Write-Output "❌ Erro ao remover arquivo de validação: $($_.Exception.Message)"
          }
      } else {
          Write-Output "Arquivo de validação não encontrado."
      }
      
      # --- Etapa 6: Verificar limpeza da pasta de validação ---
      Write-Output "=== ETAPA 6: LIMPEZA DA PASTA DE VALIDAÇÃO ==="
      $ValidationFolder = Split-Path $ValidationFile -Parent
      if (Test-Path $ValidationFolder) {
          try {
              $RemainingFiles = Get-ChildItem -Path $ValidationFolder -ErrorAction SilentlyContinue
              if (-not $RemainingFiles) {
                  Remove-Item -Path $ValidationFolder -Force -ErrorAction SilentlyContinue
                  Write-Output "✅ Pasta de validação vazia removida: $ValidationFolder"
              } else {
                  Write-Output "Pasta de validação mantida (contém outros arquivos)."
              }
          } catch {
              Write-Output "Pasta de validação mantida (pode conter outros arquivos)."
          }
      } else {
          Write-Output "Pasta de validação não encontrada."
      }
      
      # --- Etapa 7: Forçar atualização do desktop ---
      Write-Output "=== ETAPA 7: ATUALIZAÇÃO DO DESKTOP ==="
      try {
          # Atualizar configurações do sistema
          Rundll32.exe user32.dll,UpdatePerUserSystemParameters
          Start-Sleep -Seconds 2
      
          # Forçar refresh do desktop
          $signature = @'
      [DllImport("user32.dll", SetLastError = true)]
      public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, string pvParam, uint fWinIni);
      '@
      
          try {
              Add-Type -MemberDefinition $signature -Name SystemParams -Namespace Win32
              [Win32.SystemParams]::SystemParametersInfo(0x0014, 0, $null, 0x01 -bor 0x02)
              Write-Output "✅ Desktop atualizado com sucesso."
          } catch {
              Write-Output "✅ Configurações removidas. Desktop será atualizado automaticamente."
          }
      } catch {
          Write-Output "Configurações removidas. Atualização do desktop será feita automaticamente."
      }
      
      # --- Etapa 8: Relatório final ---
      Write-Output ""
      Write-Output "=== RELATÓRIO DE DESINSTALAÇÃO ==="
      Write-Output "Pacote: $PackageName"
      Write-Output "Versão: 2.3 (Compatível com Hash Detection)"
      Write-Output "Data/Hora: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
      
      if ($InstallationInfo -and $InstallationInfo.ContentHash) {
          Write-Output "Hash da instalação removida: $($InstallationInfo.ContentHash)"
      }
      
      # Verificar se ainda existem vestígios
      $RemainingItems = @()
      if (Test-Path $DestinationFolder) { $RemainingItems += "Pasta de instalação" }
      if (Test-Path $ValidationFile) { $RemainingItems += "Arquivo de validação" }
      
      # Verificar registro da tela de bloqueio
      if (Test-Path $LockScreenRegPath) {
          $lockProps = Get-ItemProperty -Path $LockScreenRegPath -ErrorAction SilentlyContinue
          if ($lockProps -and ($lockProps.PSObject.Properties.Name -contains "LockScreenImage")) {
              $RemainingItems += "Configuração de tela de bloqueio"
          }
      }
      
      # Verificar RunOnce
      if (Test-Path $RunOnceKey) {
          $runOnceProps = Get-ItemProperty -Path $RunOnceKey -Name "SetUserWallpaperFCT" -ErrorAction SilentlyContinue
          if ($runOnceProps) {
              $RemainingItems += "Gatilho de logon"
          }
      }
      
      if ($RemainingItems.Count -eq 0) {
          Write-Output "Status: DESINSTALAÇÃO COMPLETA ✅"
          Write-Output "Todos os componentes foram removidos com sucesso."
          Write-Output ""
          Write-Output "🎯 RESULTADO:"
          Write-Output "• Tela de bloqueio: Restaurada para padrão do sistema"
          Write-Output "• Papel de parede: Restaurado para padrão do Windows"
          Write-Output "• Arquivos: Removidos completamente"
          Write-Output "• Registro: Limpo de configurações FCT"
          Write-Output "• Detecção Intune: Arquivo removido (aplicação será detectada como 'Não Instalada')"
      } else {
          Write-Output "Status: DESINSTALAÇÃO PARCIAL ⚠️"
          Write-Output "Itens que podem ainda estar presentes:"
          $RemainingItems | ForEach-Object { Write-Output "  - $_" }
          Write-Output ""
          Write-Output "💡 RECOMENDAÇÃO:"
          Write-Output "Execute o script novamente ou remova manualmente os itens restantes."
      }
      
      Write-Output "================================="
      Write-Output ""
      Write-Output "Desinstalação do $PackageName concluída."
      Write-Output "NOTA: Para aplicar completamente as mudanças, recomenda-se fazer logoff/logon ou reiniciar o sistema."
      
      Stop-Transcript
      
      # Retornar código de saída apropriado
      if ($RemainingItems.Count -eq 0) {
          exit 0
      } else {
          exit 1
      }
      
  • Salve os arquivos com UTF-8 with BOM.

2.1. Empacotando O Script

  1. Coloque o Microsoft-Win32-Content-Prep-Tool-1.8.6 no disco C:/

  2. Crie uma pasta - ScriptWallpaperLockscreen - com o conteúdo:

    install.ps1
    uninstall.ps1
    wallpaper.png
    lockscreen.png
  3. Abra um terminal com permissões de administrador e navegue até a pasta:

    cd "C:\\Microsoft-Win32-Content-Prep-Tool-1.8.6"
  4. Execute o aplicativo e siga os seguintes passos:

    .\\IntuneWinAppUtil.exe
    
    Please specify the source folder: C:\\ScriptWallpaperLockscreen
    Please specify the setup file: install.ps1
    Please specify the output folder: C:\\ScriptWallpaperLockscreen
  5. O arquivo install.intunewin será gerado na pasta do aplicativo.

3. Configuração No Intune Para O Papel De Parede

  1. Acesse o Centro de Administração do Microsoft Intune.

  2. Vá para Aplicativos>Windows>Aplicativos do Windows.

  3. Clique em "+ Adicionar".

  4. Selecione "Aplicativo Windows (Win32)" no menu suspenso.

  • No assistente:

    • Informações do aplicativo: Selecione o arquivo.intunewinque você criou.

    • Informações do aplicativo: Preencha os detalhes (Nome, Descrição, Editor, etc.).

    • Programa:

      • Comando de instalação:

        • %SystemRoot%\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy Bypass -File .\\install.ps1

      • Comando de desinstalação:

        • %SystemRoot%\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy Bypass -File .\\uninstall.ps1

      • Comportamento de instalação do dispositivo: Sistema

      • Permitir desinstalação disponível: Não

    • Requisitos:Configure os requisitos de OS (ex: Windows 10 2004 e posterior) e arquitetura (x64/x86).

    • Regras de detecção:Essencial para que o Intune saiba se o aplicativo já está instalado.

      • Tipo de regra: Arquivo

      • Caminho: C:\\ProgramData\\scloud\\Validation

      • Nome do arquivo: WallpaperFCT

      • Método de detecção: Arquivo ou pasta existe(ou se quiser ser mais específico, "Tamanho do arquivo" ou "Data da modificação")

    • Dependências/Substituições (Opcional): Não é necessário para este cenário simples.

    • Atribuições: Atribua ao grupo de segurança do INTUNE de homologação ou produção.

4. Priorizar Políticas do Intune ao Invés das Locais

  1. Vá até o “Intune > Dispositivos > Gerenciar dispositivos > Configuração.

  2. Clique em “Criar” na aba “Políticas” e “Nova política”.

  3. Selecione a plataforma “Windows 10 e posterior” e “Tipo de perfil” “Modelos > Personalizado”.

4.1. Básico

  • Nome:

    • MDMWinsOverGP

  • Descrição:

    • Faz com que as políticas do Intune sejam priorizadas ao invés das políticas locais.

4.2. Parâmetro de Configuração

  1. Em “Adicionar”.

    1. Nome

      MDM Wins Over GP

    2. OMA-URI

      ./Device/Vendor/MSFT/Policy/Config/ControlPolicyConflict/MDMWinsOverGP

    3. Tipo de dados

      Integer

      • Value:1

4.3. Atribuições

  • Atribua o grupo de homologação ou produção do INTUNE.

4.4. Regras de Aplicabilidade

  • Pule.

4.5. Revisar + Criar

  1. Clique em “Criar”.

5. Removendo as Políticas Locais

  1. Prepare um script e o empacote-o como um.intunewin.

    # Nome do Script: Reverte-PoliticaLocal-Wallpaper.ps1
    # Objetivo: Remover as chaves de registro da política de papel de parede via GPO local
    # para permitir que a política do Intune seja aplicada.
    
    Write-Host "Iniciando script para reverter política de papel de parede local..."
    
    # Caminho do registro para a política de papel de parede do usuário
    $RegistryPath = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
    
    # Nomes das propriedades de registro a serem removidas
    $PropertyName1 = "Wallpaper"
    $PropertyName2 = "WallpaperStyle"
    
    # Verifica se o caminho do registro existe antes de tentar remover
    if (Test-Path $RegistryPath) {
        try {
            Write-Host "Chave de registro encontrada em $RegistryPath. Tentando remover as propriedades..."
    
            # Remove a propriedade 'Wallpaper' se ela existir
            if (Get-ItemProperty -Path $RegistryPath -Name $PropertyName1 -ErrorAction SilentlyContinue) {
                Remove-ItemProperty -Path $RegistryPath -Name $PropertyName1 -Force -ErrorAction SilentlyContinue
                Write-Host "Propriedade '$PropertyName1' removida com sucesso."
            }
    
            # Remove a propriedade 'WallpaperStyle' se ela existir
            if (Get-ItemProperty -Path $RegistryPath -Name $PropertyName2 -ErrorAction SilentlyContinue) {
                Remove-ItemProperty -Path $RegistryPath -Name $PropertyName2 -Force -ErrorAction SilentlyContinue
                Write-Host "Propriedade '$PropertyName2' removida com sucesso."
            }
    
        } catch {
            Write-Host "Ocorreu um erro ao remover as propriedades: $_"
        }
    } else {
        Write-Host "Nenhuma política local de papel de parede encontrada em $RegistryPath. Nenhuma ação necessária."
    }
    
    Write-Host "Script finalizado."
    
  2. Utilize o comando para criar o .intunewin.

    .\\IntuneWinAppUtil.exe -c "C:\\IntuneRevertLocalPolicy" -s "run.ps1" -o "C:\\IntuneRevertLocalPolicy"
    

5.1. Crie um Aplicativo no Intune

  1. Acesse o Centro de Administração do Microsoft Intune.

  2. Vá para Aplicativos > Windows > Aplicativos do Windows.

  3. Clique em "+ Adicionar".

  4. Selecione "Aplicativo Windows (Win32)" no menu suspenso.

  • No assistente:

    • Informações do aplicativo: Selecione o arquivo.intunewinque você criou.

    • Informações do aplicativo: Preencha os detalhes (Nome, Descrição, Editor, etc.).

    • Programa:

      • Comando de instalação:

        • powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File ".\\run.ps1"

      • Comando de desinstalação:

        • cmd.exe /c "exit 0”

      • Comportamento de instalação do dispositivo: Usuário

      • Permitir desinstalação disponível: Não

    • Requisitos: Configure os requisitos de OS (ex: Windows 10 2004 e posterior) e arquitetura (x64/x86).

    • Regras de detecção: Essencial para que o Intune saiba se o aplicativo já está instalado.

      • Tipo de regra: Usar um script de detecção personalizado.

      • Arquivo: detect.ps1

        # Objetivo: Verificar se as chaves de registro do GPO de papel de parede foram removidas.
        
        $RegistryPath = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
        $PropertyName1 = "Wallpaper"
        $PropertyName2 = "WallpaperStyle"
        
        # Tenta obter as propriedades. Se alguma delas existir, a "instalação" falhou.
        $Prop1 = Get-ItemProperty -Path $RegistryPath -Name $PropertyName1 -ErrorAction SilentlyContinue
        $Prop2 = Get-ItemProperty -Path $RegistryPath -Name $PropertyName2 -ErrorAction SilentlyContinue
        
        # Se ambas as propriedades forem nulas (não existem), o script funcionou.
        if (-not $Prop1 -and -not $Prop2) {
            # Escreve qualquer coisa na saída padrão para sinalizar sucesso ao Intune.
            Write-Host "Regras de detecção validadas: Políticas removidas."
            exit 0
        }
        
        # Se o script chegar aqui, significa que uma ou ambas as chaves ainda existem.
        # Não escreve nada na saída e sai com um código de erro para sinalizar falha ao Intune.
        exit 1
        
    • Dependências/Substituições (Opcional):Não é necessário para este cenário simples.

    • Atribuições:Atribua ao grupo de segurança do INTUNE dehomologaçãoouprodução.

Preparando A Tela De Bloqueio (Não Funciona No Windows Pro)

Para a tela de bloqueio, temos mais opções, e uma delas pode funcionar para o Windows Pro:

Opção 1: Usando um Perfil de Configuração "Configurações de catálogo" (Recomendado para Windows Pro)

Esta é a maneira mais moderna e flexível para muitas configurações no Windows Pro via Intune.

  1. Prepare a Imagem no SharePoint:

    • Tenha a imagem da tela de bloqueio na biblioteca de documentos do SharePoint com o link "Qualquer pessoa com o link". Obtenha essa URL.

  2. Crie um Perfil de Configuração:

    • No Centro de Administração do Intune, vá para “Dispositivos > Windows > Gerenciar dispositivos > configuração”.

    • Clique em"+ Criar perfil".

    • Plataforma: Windows 10 e posterior

    • Tipo de perfil: Catálogo de configurações

    • Clique em"Criar".

  3. Configurações do Perfil:

    • Básico:Dê umNome(ex: "Tela de Bloqueio da Empresa") eDescrição. Clique em "Avançar".

    • Configurações de configuração: Clique em"+ Adicionar configurações".

      1. Pesquisa por “Personalização” e clique na opção.

      2. Selecione:

        1. URL da Image da Tela de Bloqueio

        2. URL da Imagem de Área de Trabalho

    • Clique em "Avançar".

    • Marcas de Escopo: Padrão

    • Atribuições: Atribua aos seus grupos de usuários ou dispositivos. Clique em "Avançar".

    • Revisar + criar: Revise e crie o perfil.


Resultado Esperado

Depois da sincronização do Intune, as máquinas devem exibir o papel de parede escolhido.

Solução de Problemas

  • Verificando LogsVá até

    • C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs

      • Procure peloIntuneManagementExtension.log.

Artigos Relacionados

N/A

Anexos

N/A

Referências

  • https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-controlpolicyconflict

  • https://www.youtube.com/watch?v=UG9aTmdq3MA&t=306s

Histórico de Revisões

Data

Versão

Autor

Descrição das Mudanças

04/07/2025

1.0

Thiago Amaral

Confecção do documento.

Last updated