Automação Visual com Recursos Nativos do Windows!
🧠 Automação Visual com PowerShell: Encontre e Clique em Imagens na Tela Usando Recursos Nativos do Windows
Você já imaginou automatizar o seu Windows apenas reconhecendo imagens na tela — sem instalar nada, apenas com PowerShell e APIs nativas?
Pois é, isso é totalmente possível.
Com algumas linhas de código, o PowerShell pode analisar o que aparece no monitor, identificar uma imagem específica, mover o mouse até ela e interagir como se fosse você.
Parece mágica, mas é pura integração com as bibliotecas do próprio Windows.
💡 Cenário de Exemplo
Vamos usar um exemplo simples, mas poderoso:
>> Encontrar o menu Iniciar do Windows 11, clicar sobre ele, digitar Explorador de Arquivos e abrir o aplicativo.
Tudo isso com um script único em PowerShell.
⚙️ Script Completo
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type @'
using System;
using System.Runtime.InteropServices;
public class MouseHelper {
  [DllImport("user32.dll")]
  public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
  
  public const int MOUSEEVENTF_LEFTDOWN = 0x02;
  public const int MOUSEEVENTF_LEFTUP = 0x04;
}
public class ScreenHelper {    
  [DllImport("user32.dll")]
  public static extern int GetSystemMetrics(int nIndex);
  
  public const int SM_CXSCREEN = 0;
  public const int SM_CYSCREEN = 1;
}
'@
$keyboard = New-Object -ComObject WScript.Shell
function Send-LeftClick {
  [MouseHelper]::mouse_event([MouseHelper]::MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
  Start-Sleep -Milliseconds 30
  [MouseHelper]::mouse_event([MouseHelper]::MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
}
function Find-ImageOnScreen([string]$ImagePath, [int]$ColorTolerance){
  $needle = [System.Drawing.Bitmap]::FromFile($ImagePath)
  $screenWidth = [ScreenHelper]::GetSystemMetrics([ScreenHelper]::SM_CXSCREEN)
  $screenHeight = [ScreenHelper]::GetSystemMetrics([ScreenHelper]::SM_CYSCREEN)
  $screenshot = New-Object System.Drawing.Bitmap($screenWidth, $screenHeight)
  $graphics = [System.Drawing.Graphics]::FromImage($screenshot)
  $graphics.CopyFromScreen(0, 0, 0, 0, $screenshot.Size)
  $graphics.Dispose()
  
  for ($y = 0; $y -le ($screenHeight - $needle.Height); $y++) {
      if ($y % 100 -eq 0) { Write-Host "Progresso: linha $y de $screenHeight `r" -NoNewline}
      for ($x = 0; $x -le ($screenWidth - $needle.Width); $x++) {
          $match = $true
          for ($cy = 0; $cy -lt $needle.Height -and $match; $cy++) {
              for ($cx = 0; $cx -lt $needle.Width -and $match; $cx++) {
                  $sp = $screenshot.GetPixel($x + $cx, $y + $cy)
                  $np = $needle.GetPixel($cx, $cy)
                  if ([Math]::Abs($sp.R - $np.R) -gt $ColorTolerance -or 
                      [Math]::Abs($sp.G - $np.G) -gt $ColorTolerance -or 
                      [Math]::Abs($sp.B - $np.B) -gt $ColorTolerance) {
                      $match = $false
                  }
              }
          }
          if ($match) {
              $centerX = $x + [int]($needle.Width / 2)
              $centerY = $y + [int]($needle.Height / 2)
              $needle.Dispose()
              $screenshot.Dispose()
              return @($centerX, $centerY)
          }
      }
  }
  $needle.Dispose()
  $screenshot.Dispose()
  return $false
}
# !!! ATENÇÃO !!!
# Se a tela do Windows estiver com escala diferente de 100% pode ser que a procura falhe
# Aqui passamos o caminho da imagem que desejamos procurar
$found = Find-ImageOnScreen -ImagePath 'C:\Temp\Iniciar.png' -ColorTolerance 10
if ($found) {
  Write-Host "Movendo mouse para: X=$($found[0]), Y=$($found[1])" -ForegroundColor Green
  [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($found[0], $found[1])
  Start-Sleep -Milliseconds 100
  Send-LeftClick
  Start-Sleep -Milliseconds 500
  $keyboard.SendKeys("Explorador de Arquivos")
  Start-Sleep -Seconds 1
  $keyboard.SendKeys("{ENTER}")
}
🧩 Explicando o Script por Blocos
1️⃣ Importando Bibliotecas e Classes Nativas
O script carrega assemblies do .NET (System.Windows.Forms e System.Drawing) e define classes C# para acessar funções da DLL user32.dll, responsáveis por eventos de mouse e dimensões de tela.
Isso torna o PowerShell capaz de interagir diretamente com o Windows.
2️⃣ Função Send-LeftClick
Simula um clique esquerdo do mouse, usando a função mouse_event.
Esse método é crucial para automação visual e substitui o clique físico.
3️⃣ Função Find-ImageOnScreen
Aqui está o núcleo da automação.
Ela:
- Captura uma screenshot completa do monitor;
 - Percorre pixel a pixel comparando com a imagem-alvo (
$ImagePath); - Usa a tolerância de cor (
ColorTolerance) para compensar variações de brilho ou tema; - Retorna as coordenadas X e Y do centro da imagem encontrada.
 
💡 Dica: quanto menor a tolerância, mais precisa (porém mais sensível à cor); quanto maior, mais flexível.
4️⃣ Execução da Ação
Se a imagem for encontrada:
- O mouse é movido até o ponto;
 - Um clique é executado;
 - O script digita “Explorador de Arquivos” e pressiona Enter, abrindo o app automaticamente.
 
🚀 Expansão de Uso
Esse modelo pode ser adaptado para inúmeros cenários:
- Testes automatizados de interface;
 - Interação com aplicativos legados sem API;
 - Automação de tarefas repetitivas visuais;
 - Execução condicional com base em ícones ou botões visíveis.
 
Tudo isso sem instalar frameworks externos — apenas PowerShell e criatividade.
🧭 Conclusão
Espero que este artigo agregue conhecimento e gere insights de utilização para o seu dia a dia e para as atividades em sua empresa.
Automação não precisa ser complexa — às vezes, a melhor solução está nas ferramentas que você já tem instaladas.
Conteúdo desenvolvido por:
📘 Ivan Barbosa Kovalinkinas



