Compartilhe que você está se especializando

Aqui faremos um POST rápido sobre um assunto que acreditamos que possa acrescentar a vários profissionais, seremos breves e abordaremos de uma maneira também bem simples com o objetivo de agregar o máximo da forma mais rápida.

Nosso fluxo será criar uma tarefa agendada semanal no Windows para:

Script PowerShell -> Ler template HTML -> Alterar senha da Wifi -> (se sucesso) -> Gerar QrCode -> Salvar tudo como imagem (pois terá uma GPO para usar como wallpaper).

Para tentarmos reaproveitar o máximo os códigos, definimos aqui (quando possível) as mesmas variáveis (como nome da pasta), ficando mais simples o entendimento e utilização. Deixamos, também, algumas partes em cinza, para que você altere conforme a realidade de seu ambiente.

Sugerimos que você obtenha os arquivos (template e código) do nosso GitHub, para conseguir a versão mais nova e/ou completa. Mas para entender como fazer, leia as informações abaixo.

Gerar um template HTML

O HTML a ser usado como papel de parede pode ser gerado por IA, onde é possível definir os padrões visuais da empresa, recursividade, entre outros requisitos.

Um exemplo de HTML precisamos:

  • O arquivo HTML será C:\Temp\template.html
  • O QrCode será C:\Temp\WiFiQR.png
  • A logo da empresa, como C:\Temp\logo.png

O conteúdo do template será :

<!DOCTYPE html>
<html lang="pt-BR">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Wallpaper</title>

<style>
*{margin:0}
body{overflow:hidden;font:16px Arial;color:#032f5d;background:#fff;}
.wallpaper{height:100vh;position:relative;background:#edf3f7;}
.blue{position:absolute;width:50%;height:130%;right:-10%;top:-15%;background:#063f78;transform:rotate(7deg);}
.content{position:absolute;top:50%;left:7%;transform:translateY(-50%);}
p{font-size:24px;}
h1{margin:15px 0;font-size:5vw;line-height:1;}
span{color:#063f78}
.qr{position:absolute;top:50%;right:10%;width:25%;transform:translateY(-50%);text-align:center;color:#fff;}
.qr img{width:100%;}
</style>

</head>

<body>
<div class="wallpaper">
  <div class="blue"></div>
  <main class="content">
    <p>Tecnologia • Conexão • Inovação</p>
    <h1>O futuro,<br><span>em constante<br>evolução.</span></h1>
    <p>Inovação e tecnologia para conectar pessoas.</p>
  </main>
  <section class="qr">
    <h1>Wi-Fi</h1>
    <img src="WiFiQR.png" alt="QR Code">
    <p><br>Rede Wifi: NomeDaRede<br><br>Senha: SenhaDaRede</p>
  </section>
</div>
</body>
</html>

PowerShell – Criar uma senha randômica

O código para gerar uma senha aleatória é:

$TamanhoSenha = 8
$Caracteres = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%"
$NetworkPass = -join (1..$TamanhoSenha | ForEach-Object {
    $Caracteres[(Get-Random -Minimum 0 -Maximum $Caracteres.Length)]
})

PowerShell – Alterar a senha da Wifi

Esse é o maior e mais complexo código, foi feito baseado na versão 9.3.x do UniFi, caso sua versão seja diferente consulte o site oficial de API em nossas referências:

# Script criado para usar a API do UniFi 9.3.x Self Hosted
# ==========================================

# CONFIGURAÇÃO (ALTERE COMO DESEJAR)
# ==========================================
$Controller = "https://seuubiquitiserver.seudominio.com:8443"
$NetworkSSID = "NomeDaRede"
$NetworkPass = "SenhaDaRede"
$UnifiUser = "admin"
$UnifiPass = "Senha_do_admin"

# INICIO DO SCRIPT
# ==========================================

# Ignorar certificado SSL interno
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

# Sessão HTTP
$Session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

# Login
# ==========================================
Write-Host "Autenticando..."
$LoginBody = @{
    username = $UnifiUser
    password = $UnifiPass
} | ConvertTo-Json

$Login = Invoke-RestMethod -Uri "$Controller/api/login" -Method POST -Body $LoginBody -ContentType "application/json" -WebSession $Session

if ($Login.meta.rc -ne "ok") {
    Write-Host "Falha no login" -ForegroundColor Yellow
    break
}

Write-Host "Login OK"
Write-Host ""

# Buscar sites
# ==========================================
Write-Host "Buscando sites..."
$Sites = Invoke-RestMethod -Uri "$Controller/api/self/sites" -Method GET -WebSession $Session

if ($Sites.data.Count -eq 0) {
    Write-Host "Nenhum site encontrado" -ForegroundColor Yellow
    break
}

# Array para guardar resultados
$Encontrados = @()

# Loop nos sites
# ==========================================
foreach ($Site in $Sites.data) {
    Write-Host "Consultando site: $($Site.name)..."
    try {
        $Wlans = Invoke-RestMethod -Uri "$Controller/api/s/$($Site.name)/rest/wlanconf" -Method GET -WebSession $Session
        foreach ($Wifi in $Wlans.data) {
            if ($Wifi.name -eq $NetworkSSID) {
                Write-Host "SSID encontrado no site $($Site.name)" -ForegroundColor Green
                $Encontrados += [PSCustomObject]@{
                    SiteNome   = $Site.name
                    SiteID     = $Site._id
                    WifiNome   = $Wifi.name
                    WifiID     = $Wifi._id
                    Security   = $Wifi.security
                    Enabled    = $Wifi.enabled
                }
            }
        }

    }
    catch {
        Write-Host "Erro consultando site $($Site.name): $($_.Exception.Message)" -ForegroundColor Yellow
        break
    }
}

$WifiEncontrado = $Encontrados[0]
if ($WifiEncontrado.Security -ne "wpapsk") {
    Write-Host "ABORTADO - Apenas redes wpapsk podem ter senha compartilhada alterada." -ForegroundColor Yellow
    break
}

# Alterar senha
# ==========================================
$BodyAlteracao = @{
    x_passphrase = $NetworkPass
} | ConvertTo-Json

$Alteracao = Invoke-RestMethod -Uri "$Controller/api/s/$($WifiEncontrado.SiteNome)/rest/wlanconf/$($WifiEncontrado.WifiID)" -Method PUT -Body $BodyAlteracao -ContentType "application/json" -WebSession $Session

if ($Alteracao.meta.rc -eq "ok") {
    Write-Host ""
    Write-Host "Senha alterada com sucesso!"
    Write-Host "================================="
    Write-Host "Nova senha: $NetworkPass" -ForegroundColor Green
}
else {
    Write-Host ""
    Write-Host "Erro ao alterar senha:"
    $Alteracao | ConvertTo-Json -Depth 5
}

PowerShell – Gerar um QrCode

Existem diversas formas de gerar o QrCode, inclusive escrevemos um post Criando QR Codes e códigos de barras nativamente no Microsoft Word (mas precisaria do Word.Interop). O meio mais simples usando o PowerShell foi:

# Necessário módulo QRCodeGenerator (instale com o comando Install-Module -Name QRCodeGenerator -Force -Scope CurrentUser )

$Folder = "C:\Temp"
$QRFileName = "WiFiQR.png"
$NetworkSSID = "NomeDaRede"
$NetworkPass = "SenhaDaRede"

# Verifica se existe o diretório (ou aboarta)
if (-not (Test-Path -Path $Folder -PathType Container)) { break }

# Gera os QR Codes
$pngPath = Join-Path $Folder $QRFileName
New-QRCodeText -Text "WIFI:T:WPA;S:$NetworkSSID;P:$NetworkPass;;" -OutPath $pngPath -Width 10

PowerShell – Alterar parte do HTML

Para alterar o conteúdo de um arquivo texto, execute os seguintes comandos:

$templateFile = "C:\Temp\template.html"
$NetworkSSID = "NomeDaRede"
$NetworkPass = "SenhaDaRede"
# ==========================================
if (-not (Test-Path $templateFile -PathType Leaf)) { break }
(Get-Content $templateFile -Raw) -replace "NomeDaRede", "$NetworkSSID" | Set-Content $templateFile
(Get-Content $templateFile -Raw) -replace "SenhaDaRede", "$NetworkPass" | Set-Content $templateFile

PowerShell – Converter HTML em imagem

Parar converter um html em imagem, a forma mais simples que encontramos foi:

$Folder = "C:\Temp"
$HtmlFile = "template.html"
$ImageFile = "wallpaper.png"

$Html = Join-Path $Folder $HtmlFile
$Image = Join-Path $Folder $ImageFile 
$Edge = "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe"
if (-not (Test-Path $Edge)) { $Edge = "${env:ProgramFiles}\Microsoft\Edge\Application\msedge.exe" }
& $Edge --headless --disable-gpu --hide-scrollbars --screenshot="$Image" --window-size=1920,1080 "file:///$($Html -replace '\\','/')"

Definindo com Papel de parede

Usar GPO para definir o papel de parede é uma maneira prática de manter a identidade visual dos computadores da empresa padronizada. Sem nos aprofundar muito nessa parte, em nosso Post vamos considerar que a imagem ficará em um compartilhamento de rede (é importante que os usuários tenham permissão de leitura nessa pasta.), por exemplo:

\\Nome_servidor\PastaCompartilhada\wallpaper.png

Para criar a GPO, vá na OU onde estão esses usuários, edite ou crie a GPO nessa OU, dentro vá em

User Configuration
└── Policies
└── Administrative Templates
└── Desktop
└── Active Desktop

Habilite a configuração Desktop Wallpaper e no campo Wallpaper Name, informe o caminho completo da imagem (o caminho de rede, definido acima), em Wallpaper Style escolha Fill. Clique em Apply e depois em OK.

O Script completo

Considerando então que você já possuí os seguintes requisitos:

  • Tem um ambiente para executar uma tarefa agendada (se o servidor UniFI for Windows, é recomendado executar nele);
  • Tem mapeado um local para colocar a imagem (que uma GPO irá aplicar como papel de parede para os computadores);
  • Tem uma conta de rede (com permissão de escrita na pasta compartilhada) para criar uma tarefa agendada que execute o PowerShell;
  • Testar cada (como executar o PowerShell com o usuário que deverá executar a tarefa agendada) antes.

Abaixo o código unificado do PowerShell:

# Necessário o QRCodeGenerator, execute COMO ADMINISTRADOR o comando "Install-Module -Name QRCodeGenerator -Scope AllUsers -Force" e depois abra um novo PowerShell

# CONFIGURAÇÃO (ALTERE COMO DESEJAR)
# ==========================================
$Caracteres = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
$Controller = "https://seuubiquitiserver.seudominio.com:8443"
$DestinationFolder = "C:\Temp"
$HTMLFile = "wallpaper.html"
$ImageFile = "wallpaper.png"
$NetworkSSID = "NomeDaRede"
$QRFileName = "WiFiQR.png"
$SharedFolder = "\\Nome_servidor\PastaCompartilhada"
$SourceFolder = "C:\Temp"
$TamanhoSenha = 8
$TemplateFile = "template.html"
$UnifiUser = "admin"
$UnifiPass = "Senha_do_admin"

# INICIO DO SCRIPT
# ==========================================
$templatePath = Join-Path $SourceFolder $TemplateFile
if (-not (Test-Path -Path $SourceFolder -PathType Container)) { break }
if (-not (Test-Path $templatePath -PathType Leaf)) { break }
if (-not (Test-Path -Path $SharedFolder -PathType Container)) { break }
$QrPath = Join-Path $DestinationFolder $QRFileName
$HTMLPath = Join-Path $DestinationFolder $HTMLFile
$ImageFullPath = Join-Path $SharedFolder $ImageFile

$NetworkPass = -join (1..$TamanhoSenha | ForEach-Object {
    $Caracteres[(Get-Random -Minimum 0 -Maximum $Caracteres.Length)]
})

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

$Session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

$LoginBody = @{
    username = $UnifiUser
    password = $UnifiPass
} | ConvertTo-Json

$Login = Invoke-RestMethod -Uri "$Controller/api/login" -Method POST -Body $LoginBody -ContentType "application/json" -WebSession $Session

if ($Login.meta.rc -ne "ok") {
    Write-Host "Falha no login" -ForegroundColor Yellow
    break
}

$Sites = Invoke-RestMethod -Uri "$Controller/api/self/sites" -Method GET -WebSession $Session

if ($Sites.data.Count -eq 0) {
    Write-Host "Nenhum site encontrado" -ForegroundColor Yellow
    break
}

$Encontrados = @()

foreach ($Site in $Sites.data) {
    try {
        $Wlans = Invoke-RestMethod -Uri "$Controller/api/s/$($Site.name)/rest/wlanconf" -Method GET -WebSession $Session
        foreach ($Wifi in $Wlans.data) {
            if ($Wifi.name -eq $NetworkSSID) {
                $Encontrados += [PSCustomObject]@{
                    SiteNome   = $Site.name
                    SiteID     = $Site._id
                    WifiNome   = $Wifi.name
                    WifiID     = $Wifi._id
                    Security   = $Wifi.security
                    Enabled    = $Wifi.enabled
                }
            }
        }
    }
    catch {
        Write-Host "Erro consultando site $($Site.name): $($_.Exception.Message)" -ForegroundColor Yellow
        break
    }
}

$WifiEncontrado = $Encontrados[0]
if ($WifiEncontrado.Security -ne "wpapsk") {
    Write-Host "ABORTADO - Apenas redes wpapsk podem ter senha compartilhada alterada." -ForegroundColor Yellow
    break
}

$BodyAlteracao = @{
    x_passphrase = $NetworkPass
} | ConvertTo-Json

#$Alteracao = Invoke-RestMethod -Uri "$Controller/api/s/$($WifiEncontrado.SiteNome)/rest/wlanconf/$($WifiEncontrado.WifiID)" -Method PUT -Body $BodyAlteracao -ContentType "application/json" -WebSession $Session

if ($Alteracao.meta.rc -eq "ok") {
    New-QRCodeText -Text "WIFI:T:WPA;S:$NetworkSSID;P:$NetworkPass;;" -OutPath $QrPath -Width 10

    (Get-Content $templatePath -Raw) -replace "NomeDaRede", "$NetworkSSID" -replace "SenhaDaRede", "$NetworkPass" -replace "logo.png", "$SourceFolder\logo.png" | Set-Content $HTMLPath

    Remove-Item "$ImageFullPath" -Force -ErrorAction SilentlyContinue

    $Edge = "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe"
    if (-not (Test-Path $Edge)) { $Edge = "${env:ProgramFiles}\Microsoft\Edge\Application\msedge.exe" }

    $EdgeProfile = "$DestinationFolder\Edge"
    New-Item -ItemType Directory -Path $EdgeProfile -Force | Out-Null
    & $Edge --headless --disable-gpu --hide-scrollbars --no-sandbox --user-data-dir="$EdgeProfile" --screenshot="$ImageFullPath" --window-size=1920,1080 "file:///$($HTMLPath -replace '\\','/')"

    $count = 0
    do { 
        Start-Sleep -Seconds 1
        $count++
    } while (-not (Test-Path -LiteralPath $ImageFullPath) -and $count -lt 30)

    Remove-Item "$EdgeProfile" -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue
    Remove-Item "$HTMLPath" -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue
    Remove-Item "$QrPath" -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue
}

Fontes/Referências

NVLAN – Criando QR Codes e códigos de barras nativamente no Microsoft Word
NVLAN – GitHub

https://developer.ui.com/network/v9.3.45/gettingstarted
https://github.com/beezly/unifi-apis
https://github.com/gakamor/public-scripts/blob/main/Invoke-LapsQR.ps1
https://github.com/opastorello/unifi-api-docs
https://github.com/ubiquiti-community/unifi-api

Mais Informações

Esperamos ter te ajudado e estaremos sempre a disposição para mais informações.

Se você tem interesse em algum assunto específico, tem alguma dúvida, precisa de ajuda, ou quer sugerir um post, entre em contato conosco pelo e-mail equipe@nvlan.com.br.

NVLAN - Consultoria
Categorias: Redes

0 comentário

Deixe um comentário

Espaço reservado para avatar

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *