Forum Discussion
timjeens
May 12, 2025Copper Contributor
Automated import of Hardware Hashes into Intune
Hi everyone,
So, here is the script I used to pre-seed the hardware hashes into my Intune environment.
Please check it over before just running it..
You'll need to create a csv called: computernamelist.csv
In this file, you'll need a list of all your computer names like this:
"ComputerName"
"SID-1234"
"SID-4345"
You can use a the Get-ADComputer command to gather all your computers and output to a CSV.
Features:
- It will run through 10 computers at a time.
- It will remove computers that it has confirmed as being updated in Intune.
- Pings a computer first to speed it up.
- Only for devices on your network or on the VPN.
You can schedule it to run, or I just re-ran it a bunch of times over a few weeks.
# Path to the CSV file
$csvPath = "C:\scripts\computernamelist.csv"
# Import the CSV file
$computers = Import-Csv -Path $csvPath
# Number of concurrent jobs (adjust as needed)
$maxConcurrentJobs = 10
# Array to store the job references
$jobs = @()
# Ensure the required settings and script are set up
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force
Install-Script -Name Get-WindowsAutopilotInfo -Force
# Authenticate with Microsoft Graph (Office 365 / Azure AD)
Connect-MGGraph
# Function to remove a computer from the CSV after successful import
function Remove-ComputerFromCSV {
param (
[string]$computerName,
[string]$csvPath
)
$computers = Import-Csv -Path $csvPath
$computers = $computers | Where-Object { $_.ComputerName -ne $computerName }
$computers | Export-Csv -Path $csvPath -NoTypeInformation
Write-Host "Removed $computerName from CSV."
}
# Loop through each computer in the CSV
foreach ($computer in $computers) {
$computerName = $computer.ComputerName
# Start a new background job for each computer
$job = Start-Job -ScriptBlock {
param($computerName, $csvPath)
# Check if the computer is reachable (ping check)
if (Test-Connection -ComputerName $computerName -Count 1 -Quiet) {
Write-Host "$computerName is online. Retrieving Autopilot info..."
# Ensure TLS 1.2 is used and execution policy is set for the job
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force
# Run the Autopilot info command and capture the output
$output = Get-WindowsAutopilotInfo -Online -Name $computerName
# Check if the output contains the success or error messages
if ($output -like "*devices imported successfully*") {
Write-Host "Success: $computerName - Autopilot info imported successfully."
# Remove the computer from the CSV after successful import
Remove-ComputerFromCSV -computerName $computerName -csvPath $csvPath
} elseif ($output -like "*error 806 ZtdDeviceAlreadyAssigned*") {
Write-Host "Error: $computerName - Device already assigned."
} else {
Write-Host "Error: $computerName - Unknown issue during import."
}
} else {
Write-Host "$computerName is offline. Skipping."
}
} -ArgumentList $computerName, $csvPath
# Add the job to the list
$jobs += $job
# Monitor job status
Write-Host "Started job for $computerName with Job ID $($job.Id)."
# If the number of jobs reaches the limit, wait for them to complete
if ($jobs.Count -ge $maxConcurrentJobs) {
# Wait for all current jobs to complete before starting new ones
$jobs | ForEach-Object {
Write-Host "Waiting for Job ID $($_.Id) ($($_.State)) to complete..."
$_ | Wait-Job
Write-Host "Job ID $($_.Id) has completed."
}
# Check job output and clean up completed jobs
$jobs | ForEach-Object {
if ($_.State -eq 'Completed') {
$output = Receive-Job -Job $_
Write-Host "Output for Job ID $($_.Id): $output"
Remove-Job $_
} elseif ($_.State -eq 'Failed') {
Write-Host "Job ID $($_.Id) failed."
}
}
# Reset the jobs array
$jobs = @()
}
}
# Wait for any remaining jobs to complete
$jobs | ForEach-Object {
Write-Host "Waiting for Job ID $($_.Id) ($($_.State)) to complete..."
$_ | Wait-Job
Write-Host "Job ID $($_.Id) has completed."
}
# Check job output for remaining jobs
$jobs | ForEach-Object {
if ($_.State -eq 'Completed') {
$output = Receive-Job -Job $_
Write-Host "Output for Job ID $($_.Id): $output"
Remove-Job $_
} elseif ($_.State -eq 'Failed') {
Write-Host "Job ID $($_.Id) failed."
}
}
This is all derived from: https://learn.microsoft.com/en-us/autopilot/add-devices
"Get-WindowsAutopilotInfo" is from this link.
Hope this helps someone.
Thanks,
Tim Jeens
1 Reply
- NabilNahdiBrass Contributor
Nice! Thanks for sharing