Remember to maintain security and privacy. Do not share sensitive information. Procedimento.com.br may make mistakes. Verify important information. Termo de Responsabilidade

Como Coletar o Hash de Hardware Automatizado Sem Precisar de Conta Administrador

O script abaixo é utilizado para coletar o hash de hardware para registrar o equipamento no Windows Autopilot. O script faz a coleta por meio da exportação na opção "Acessar trabalho ou escola" nas configurações do Windows. Ele criará um arquivo CSV contendo o hash de hardware e o salvará no diretório especificado. O arquivo CSV gerado será utilizado para fazer a importação no Intune e registrar o dispositivo no perfil do Autopilot.

Instruções de execução

Para executar o script corretamente, siga as instruções abaixo:

  1. Abra o PowerShell.

    
    <# 
    ======================================================================================         
    Nome: Get-HashdeHardware.ps1
    Autor: Ricardo da Silva Oliveira
    Data  : 04/06/2024
    Descrição: Este script é utilizado para coletar o hash de hardware por meio da
    exportação na opção que fica em Configurações, Contas, Acessar trabalho ou escola.
    No final, será gerado um arquivo com o nome 'DeviceHash_$computerName.csv' que será
    utilizado para registrar o equipamento no Windows Autopilot.
    
    Nota: Existe uma outra alternativa para coletar o Hash de Hardware, veja a documentação
    no link: https://learn.microsoft.com/pt-br/autopilot/add-devices#powershell
    ======================================================================================         
    #>

$data=Get-Date -Format "dd/MM/yy-HH:mm" $filedata=Get-Date -Format "dd-MM-yy"

Define os valores iniciais das variáveis globais utilizadas para criar os logs

$global:DataLog = (Get-Date).tostring("dd-MM-yyyy") $global:HoraLog = (Get-Date).tostring("HHmmss") $global:LogFileLocal = ("C:\Users\Public\Documents\Get-HashdeHardware.log")

$fspvice = New-Object -ComObject SAPI.SPVoice

function DetectarMovimentoMouse { param ( [int]$tempoMonitoramento = 1 # Tempo em segundos )

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class User32 {
    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out POINT lpPoint);
    public struct POINT {
        public int X;
        public int Y;
    }
}

"@

# Inicializa a posição inicial do cursor do mouse
$posicaoInicial = New-Object User32+POINT > $null
[User32]::GetCursorPos([ref]$posicaoInicial) > $null

# Registra o tempo de início do monitoramento
$tempoInicio = Get-Date
$movimentoDetectado = $false

# Loop para monitorar o movimento do mouse
while ((Get-Date) -lt $tempoInicio.AddSeconds($tempoMonitoramento)) {
    Start-Sleep -Seconds 1
    $posicaoAtual = New-Object User32+POINT
    [User32]::GetCursorPos([ref]$posicaoAtual) > $null

    # Verifica se o cursor se moveu
    if ($posicaoAtual.X -ne $posicaoInicial.X -or $posicaoAtual.Y -ne $posicaoInicial.Y) {
        $movimentoDetectado = $true
        $fspvice.Speak(" Por favor, não toque no mouse ou teclado. A coleta será reinicializada.") >> $null
        # break
        Stop-Process -Name SystemSettings -Force -ErrorAction SilentlyContinue >> $null
        $fspvice.Speak(" Aguarde...")  >> $null           
        main
        exit

    } 
}

}

function main {

function Gravar-Log ([String]$LOG_txt) {

$global:HoraLog = (Get-Date).ToString("HH:mm:ss")

try {
    Add-Content -Path $global:LogFileLocal -Value "$global:DataLog - $global:HoraLog : $LOG_txt" -Force -Encoding Unicode
}
catch {
    Write-Error "Falha ao gravar no arquivo de log: $_"
    return
}    
}

Gravar-Log -LOG_txt "================== INICIO =================="

Write-Host ""
Write-Host "================== Coletar Hardware ID para Cadastro no Autopilot =================="
Write-Host ""

$texto = "Será realizada automaticamente a Coleta do Hardware ID.
Durante esse processo, as Configurações do sistema serão abertas para realizarmos a exportação dos dados.
Por favor, mantenha-se afastado do teclado e do mouse durante esse processo. 
Assim que a coleta for finalizada, você será informado. 
Realizando a coleta."
#$velocidade = 50

function ShowInfor {
    param (
        [Parameter(Position = 0, Mandatory = $true)]
        [string]$Texto,

        [Parameter(Position = 1)]
        [int]$Velocidade = 10
    )

    for ($i = 0; $i -lt $Texto.Length; $i++) {
        Write-Host -NoNewline $Texto[$i]        
        Start-Sleep -Milliseconds $Velocidade

        if ($Texto[$i] -eq '.') {
            Write-Host -NoNewline "`n"
            DetectarMovimentoMouse -tempoMonitoramento 1
        }            
    }
    # $fspvice.Speak($Texto)
}
# Exemplo de uso da função
ShowInfor -Texto "$texto"

Start-Sleep -Seconds 2
Write-Output ""
Write-Output "Aguarde."
Write-Output ""

Stop-Process -Name SystemSettings -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1

# Abrir a tela de Configurações para Acessar trabalho ou escola
Start-Process ms-settings:workplace

# Aguardar alguns segundos para permitir que a interface de usuário seja carregada
Start-Sleep -Seconds 3
function seWindows {        
    $osCaption = (Get-WmiObject -Class Win32_OperatingSystem).Caption
    if ($osCaption -like "*Windows 10*") {
        # Simular o pressionamento da tecla TAB para selecionar o botão Exportar
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        Start-Sleep -Seconds 1
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

    } elseif ($osCaption -like "*Windows 11*") {

        # Simular o pressionamento da tecla TAB para selecionar o botão Exportar
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        Start-Sleep -Seconds 1
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

    } else {

        return "Outra versão do Windows $osCaption"
    }

}

function seWindowsDomain {

    DetectarMovimentoMouse -tempoMonitoramento 1

    $osCaption = (Get-WmiObject -Class Win32_OperatingSystem).Caption

    if ($osCaption -like "*Windows 10*") {

        # Simular o pressionamento da tecla TAB para selecionar o botão Exportar
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        Start-Sleep -Seconds 1
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        Start-Sleep -Seconds 1

    } elseif ($osCaption -like "*Windows 11*") {

        # Simular o pressionamento da tecla TAB para selecionar o botão Exportar
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        Start-Sleep -Seconds 1
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")            
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")            
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")            
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        Start-Sleep -Seconds 1
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

    } else {

        return "Outra versão do Windows $osCaption"
    }

}

# Verifica se é do AD ou Autopilot e chama a função correta
if ($env:USERDNSDOMAIN) {
    seWindowsDomain
} else {
    seWindows
}

# Fecha a janela de configurações
Start-Sleep -Seconds 2
Stop-Process -Name SystemSettings -Force -ErrorAction SilentlyContinue

Write-Output ""
Write-Output "Coletado o hash de hardware..."
Write-Output ""
#ShowInfor -Texto "Coletando o hash de hardware."

Write-Output ""
Write-Output "Aguarde..."
Write-Output ""

#ShowInfor -Texto "Aguarde."

############ Parte que vai procurar por arquivos MDM* e realizar o processo de descompactarção e copiar dos CSV ############
# Definir o caminho dos arquivos .cab e .zip desejados
$cabFilePaths = @("C:\Users\Public\Documents\MDMDiagnostics\MDM*.cab", "C:\Users\Public\Documents\MDMDiagnostics\MDM*.zip")
$outputDir = "C:\Users\Public\Documents\ColetaID"
$computerName = $env:COMPUTERNAME
$csvFileName = "DeviceHash_$computerName.csv"

# Remove arquivos antigos antes de coletar
$temps = @("C:\Users\Public\Documents\MDMDiagnostics", "C:\Users\Public\Documents\ColetaID")
foreach ($temp in $temps) {
    if (Test-Path -Path $temp) {
        Remove-Item -Path $temp -Recurse -Force
    }
}

$contaSedemora = 0

while ($true) {
    $contaSedemora++
    $found = $false
    foreach ($path in $cabFilePaths) {
        if (Test-Path -Path $path) {
            $found = $true
            $cabFilePath = $path
            break
        }
    }
    if ($found) {
        break
    }
    Write-Output ""
    Write-Output "Aguarde..."
    Write-Output ""
    Start-Sleep -Seconds 15
    if ($contaSedemora -ge 20) {
        Write-Host "================== Error para Coletar o Hardware ID =================="
        Write-Host ""
        Write-Host "Entrar em contato com o 881 e informar:"
        Write-Host "Erro MDMDiagnostics" -ForegroundColor Yellow
        Write-Host "Nome do procedimento: 'Coletar Hardware ID para Cadastro no Autopilot'"
        Write-Host ""
        Write-Host "======================================================================"
        Start-Sleep 3
        exit
    }
    #Gravar-Log -LOG_txt "Aguarde."
}

# Verificar se não existe a pasta e criar
if (-not (Test-Path -Path $outputDir)) {
    mkdir $outputDir
}

# Verificar se o arquivo .cab ou .zip existe
if (Test-Path -Path $cabFilePath) {
    Gravar-Log -LOG_txt "Extraindo CSV..."
    Write-Output ""
    Write-Output "Aguarde."
    Write-Output ""

    # Criar uma pasta temporária para extrair o conteúdo do arquivo
    $tempDir = New-Item -ItemType Directory -Path "$env:TEMP\MDMDiagReport"

    # Usar expand.exe para extrair o arquivo .cab ou Expand-Archive para extrair o .zip
    $logExpadfiles = ""
    if ($cabFilePath -like "*.cab") {
        & expand.exe $cabFilePath -F:* $tempDir.FullName >> $logExpadfiles
    } elseif ($cabFilePath -like "*.zip") {
        Expand-Archive -Path $cabFilePath -DestinationPath $tempDir.FullName
    }
    Gravar-Log -LOG_txt $logExpadfiles

    # Verificar se o arquivo CSV existe no diretório extraído
    $extractedCsvPath = Join-Path -Path $tempDir.FullName -ChildPath $csvFileName

    if (Test-Path -Path $extractedCsvPath) {
        Gravar-Log -LOG_txt "Arquivo CSV encontrado. Copiando para $outputDir..."

        # Copiar o arquivo CSV para o diretório de saída
        $logCp = ""
        Copy-Item -Path $extractedCsvPath -Destination $outputDir >> $logCp
        Gravar-Log -LOG_txt $logCp
    } else {
        Gravar-Log -LOG_txt "Arquivo CSV não encontrado no diretório extraído."
    }

    # Remover a pasta temporária
    Remove-Item -Path $tempDir.FullName -Recurse

    # Exibe a pasta e abre o local do CSV        
    Write-Host ""
    Write-Host "Arquivo Coletado com sucesso." -ForegroundColor Green
    Write-Host ""
    $fspvice.Speak(" Arquivo Coletado com sucesso.") >> $null
    Gravar-Log -LOG_txt "Arquivo Coletado com sucesso."
    Write-Host ""
    Write-Host "Local: $outputDir." -ForegroundColor Cyan
    Start-Sleep 1
    Gravar-Log -LOG_txt "Local: $outputDir"
    Write-Host ""
    Write-Host "Abrindo a pasta do arquivo." -ForegroundColor DarkCyan
    $fspvice.Speak(" Abrindo a pasta do arquivo.") >> $null
    Write-Host ""
    $csvPathNameCompleto = Join-Path -Path $outputDir -ChildPath $csvFileName
    $csvPegaSerial = Import-Csv -Path $csvPathNameCompleto
    $csvSerial = $csvPegaSerial.'Device Serial Number'
    Rename-Item -Path $csvPathNameCompleto -NewName "$csvSerial.csv"
    Start-Sleep 2        
    start $outputDir
} else {
    Write-Error "Erro para coletar o Hash de Hardware."
    Gravar-Log -LOG_txt "Erro para coletar o Hash de Hardware."
}

Gravar-Log -LOG_txt "================== FIM =================="

}

Definir as versões e edições suportadas de Windows 10 e Windows 11

$supportedWindowsVersions = @( "Microsoft Windows 11 Pro", "Microsoft Windows 11 Pro Education", "Microsoft Windows 11 Pro for Workstations", "Microsoft Windows 11 Enterprise", "Microsoft Windows 11 Education", "Microsoft Windows 10 Pro", "Microsoft Windows 10 Pro Education", "Microsoft Windows 10 Pro for Workstations", "Microsoft Windows 10 Enterprise", "Microsoft Windows 10 Education", "Microsoft Windows 10 Enterprise LTSC" )

Obter as informações do sistema operacional

$osInfo = Get-WmiObject -Query "SELECT Caption FROM Win32_OperatingSystem" | Select-Object -Property Caption -ExpandProperty Caption

Verificar se a edição do Windows é suportada

if ($supportedWindowsVersions -contains $osInfo) {

"A versão $($osInfo) dá suporte ao Autopilot. Pode prosseguir."

main

} else { Clear-Host Write-Host "" # Linha em branco Write-Host "############# Sistema Operacional Não Compatível #############" -ForegroundColor Yellow Write-Host "" # Linha em branco Write-Host "A versão do seu Sistema Operacional é: $($osInfo)" -ForegroundColor Cyan Write-Host "Essa versão ($($osInfo)) não é compatível com o Autopilot." -ForegroundColor Red Write-Host "" # Linha em branco Write-Host "############# Sistema Operacional Não Compatível #############" -ForegroundColor Yellow Write-Host "" # Linha em branco Write-Host "Veja abaixo as versões suportadas pelo Autopilot:" -ForegroundColor DarkGray

# Exibe as versões suportadas
foreach ($suportSO in $supportedWindowsVersions) {
    Write-Host $suportSO.Replace("Microsoft", "") -ForegroundColor Green
}

Write-Host ""  # Linha em branco
Write-Host "Pressione qualquer tecla para sair..." -ForegroundColor DarkGray
Write-Host ""  # Linha em branco
Read-Host -Prompt "->"
exit 1

}


Ao executar este script, aguarde até que ele seja concluído. Ele abrirá a tela de "Acessar trabalho ou escola" nas configurações do Windows, pressionará os botões necessários para exportar o hash de hardware e salvará o arquivo CSV no diretório especificado. No final, o diretório especificado para o arquivo CSV gerado será exibido. O arquivo será criado com o nome do número de série do computador.

## Observações
- **Não é necessário ter permissões de Administrador para executar esse script**, pois ele é executado no contexto de usuário.

To share Download PDF

Gostou do artigo? Deixe sua avaliação!
Sua opinião é muito importante para nós. Clique em um dos botões abaixo para nos dizer o que achou deste conteúdo.