param( [string]$AssignedUser = "", [switch]$Online ) # ── Execution Policy ──────────────────────────────────────────────────────── $OriginalPolicy = Get-ExecutionPolicy -Scope Process $RestrictedPolicies = @("Restricted", "AllSigned") if ($OriginalPolicy -in $RestrictedPolicies) { Write-Host "" Write-Host "De huidige execution policy is: $OriginalPolicy" -ForegroundColor Yellow Write-Host "Dit script heeft minimaal 'RemoteSigned' nodig om te kunnen draaien." Write-Host "" $Confirm = Read-Host "Wil je de execution policy tijdelijk aanpassen? (j/n)" if ($Confirm -notmatch '^[jJyY]') { Write-Host "Geannuleerd. Execution policy is niet gewijzigd." -ForegroundColor Yellow exit 1 } Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force Write-Host "Execution policy tijdelijk ingesteld op Unrestricted." -ForegroundColor Cyan $PolicyChanged = $true } else { $PolicyChanged = $false } # ──────────────────────────────────────────────────────────────────────────── $ErrorActionPreference = "Stop" # Fixed settings to make the script idiot-proof $GroupTag = "Medewerker" $DateStamp = Get-Date -Format "yyyy-MM-dd" # Prefer the script/USB location for output if ($PSScriptRoot) { $BasePath = $PSScriptRoot } else { $BasePath = (Get-Location).Path } $OutputFile = Join-Path $BasePath ("AutoPilotHashes-{0}.csv" -f $DateStamp) function Write-Info { param([string]$Message) Write-Host $Message } function Test-InternetConnection { try { $null = Test-NetConnection -ComputerName "graph.microsoft.com" -Port 443 -InformationLevel Quiet -WarningAction SilentlyContinue return [bool]$? } catch { return $false } } function Get-AutopilotHardwareHash { try { $hash = (Get-CimInstance -Namespace "root/cimv2/mdm/dmmap" -ClassName "MDM_DevDetail_Ext01" -Filter "InstanceID='Ext' AND ParentID='./DevDetail'").DeviceHardwareData if ([string]::IsNullOrWhiteSpace($hash)) { throw "DeviceHardwareData is empty." } return $hash } catch { throw "Unable to read the Autopilot hardware hash from WMI. Run this script in full Windows OOBE or Windows with the MDM Bridge WMI provider available. Details: $($_.Exception.Message)" } } function Get-DeviceSerialNumber { try { $serial = (Get-CimInstance -ClassName Win32_BIOS).SerialNumber if ([string]::IsNullOrWhiteSpace($serial)) { throw "Serial number is empty." } return $serial.Trim() } catch { throw "Unable to read the device serial number. Details: $($_.Exception.Message)" } } function Ensure-CsvHeader { param([string]$Path) if (-not (Test-Path -LiteralPath $Path)) { '"Device Serial Number","Windows Product ID","Hardware Hash","Group Tag","Assigned User"' | Out-File -LiteralPath $Path -Encoding utf8 } } function Add-AutopilotCsvRow { param( [string]$Path, [string]$SerialNumber, [string]$HardwareHash, [string]$GroupTagValue, [string]$AssignedUserValue ) Ensure-CsvHeader -Path $Path $row = [pscustomobject]@{ 'Device Serial Number' = $SerialNumber 'Windows Product ID' = '' 'Hardware Hash' = $HardwareHash 'Group Tag' = $GroupTagValue 'Assigned User' = $AssignedUserValue } $row | Export-Csv -LiteralPath $Path -NoTypeInformation -Append -Encoding utf8 } function Upload-ToIntune { param([string]$CsvPath) if (-not $Online) { return } if (-not (Test-InternetConnection)) { Write-Info "No internet connection detected. Skipping online upload. The CSV fallback has been saved to: $CsvPath" return } $moduleName = "WindowsAutoPilotIntune" try { if (-not (Get-Module -ListAvailable -Name $moduleName)) { Write-Info "WindowsAutoPilotIntune module not found. Installing module..." Install-Module -Name $moduleName -Force -Scope CurrentUser -AllowClobber } Import-Module $moduleName -Force if (-not (Get-Command -Name Get-AutopilotDevice -ErrorAction SilentlyContinue)) { throw "The WindowsAutoPilotIntune module was loaded, but the expected commands are not available." } Write-Info "Connecting to Microsoft Graph..." Connect-MSGraph | Out-Null Write-Info "Uploading CSV to Intune..." Import-AutoPilotCSV -csvFile $CsvPath Write-Info "Upload finished." } catch { Write-Info "Online upload failed. The CSV fallback is still available at: $CsvPath" Write-Info ("Upload error: " + $_.Exception.Message) } } try { Write-Info "Collecting Autopilot device information..." Write-Info ("Group Tag is fixed to: " + $GroupTag) Write-Info ("Output file: " + $OutputFile) $serialNumber = Get-DeviceSerialNumber $hardwareHash = Get-AutopilotHardwareHash Add-AutopilotCsvRow -Path $OutputFile -SerialNumber $serialNumber -HardwareHash $hardwareHash -GroupTagValue $GroupTag -AssignedUserValue $AssignedUser Write-Info "Hardware hash saved successfully." Upload-ToIntune -CsvPath $OutputFile Write-Info "Done." } catch { Write-Error $_.Exception.Message exit 1 } finally { if ($PolicyChanged) { Set-ExecutionPolicy -ExecutionPolicy $OriginalPolicy -Scope Process -Force Write-Host "Execution policy teruggezet naar: $OriginalPolicy" -ForegroundColor Cyan } }