From 08a00bf63e217dfd1a3ee3a8bd4cafbaf5a7fa5d Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Sat, 20 Jun 2026 20:06:47 +0200 Subject: [PATCH] Repository moved to Forgejo Usable scripts migrated to https://forgejo.oskamp.info/ivooskamp/Autopilot.git This Gitea copy is emptied and kept only as a redirect. --- Export-AutopilotHash-ToEmail.ps1 | 96 ----------- Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1 | 173 ------------------- Get-WindowsAutoPilotInfo.ps1 | 190 --------------------- GetAutoPilot.CMD | 7 - GetAutoPilotShutdown.CMD | 9 - README.md | 22 +++ start.bat | 4 - 7 files changed, 22 insertions(+), 479 deletions(-) delete mode 100644 Export-AutopilotHash-ToEmail.ps1 delete mode 100644 Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1 delete mode 100644 Get-WindowsAutoPilotInfo.ps1 delete mode 100644 GetAutoPilot.CMD delete mode 100644 GetAutoPilotShutdown.CMD create mode 100644 README.md delete mode 100644 start.bat diff --git a/Export-AutopilotHash-ToEmail.ps1 b/Export-AutopilotHash-ToEmail.ps1 deleted file mode 100644 index dc6c567..0000000 --- a/Export-AutopilotHash-ToEmail.ps1 +++ /dev/null @@ -1,96 +0,0 @@ -# Configuration -$csvPath = "$env:TEMP\AutopilotHash.csv" -$autopilotScript = "$env:TEMP\Get-WindowsAutopilotInfo.ps1" - -# Microsoft 365 OAuth Configuration -$tenantId = "YOUR_TENANT_ID" -$clientId = "YOUR_CLIENT_ID" -$clientSecret = "YOUR_CLIENT_SECRET" # Store securely! -$fromEmail = "sender@example.com" -$toEmail = "recipient@example.com" - -# Retrieve the device serial number -$serialNumber = (Get-WmiObject -Class Win32_BIOS).SerialNumber -if (-not $serialNumber) { - $serialNumber = "Unknown_SerialNumber" -} - -# Email subject including the serial number -$subject = "Autopilot Hash Export - $serialNumber" -$body = "See the attached CSV file containing the Autopilot Hash for device $serialNumber." - -# Download Get-WindowsAutopilotInfo.ps1 from a trusted source -Write-Host "Downloading Get-WindowsAutopilotInfo.ps1..." -$downloadUrl = "https://gitea.oskamp.info/ivooskamp/Autopilot/raw/branch/main/Get-WindowsAutoPilotInfo.ps1" - -Try { - Invoke-WebRequest -Uri $downloadUrl -OutFile $autopilotScript -UseBasicParsing -ErrorAction Stop -} Catch { - Write-Host "Error: Failed to download Get-WindowsAutopilotInfo.ps1." - Exit 1 -} - -# Verify if the script was downloaded correctly -if (-not (Test-Path $autopilotScript)) { - Write-Host "Error: Get-WindowsAutopilotInfo.ps1 does not exist after download." - Exit 1 -} - -# Execute the script to collect the Autopilot hash -Write-Host "Collecting the Autopilot hash..." -Try { - & PowerShell -ExecutionPolicy Bypass -File $autopilotScript -OutputFile $csvPath -ErrorAction Stop -} Catch { - Write-Host "Error retrieving the Autopilot hash: $_" - Exit 1 -} - -# Check if the CSV file was created -if (-not (Test-Path $csvPath)) { - Write-Host "Error: CSV file was not created." - Exit 1 -} - -# Obtain Microsoft 365 OAuth Token -Write-Host "Retrieving Microsoft 365 OAuth token..." -$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -$tokenBody = @{ - client_id = $clientId - scope = "https://graph.microsoft.com/.default" - grant_type = "client_credentials" - client_secret = $clientSecret -} - -$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -$accessToken = $tokenResponse.access_token - -# Send email via Microsoft Graph API -$graphUrl = "https://graph.microsoft.com/v1.0/users/$fromEmail/sendMail" - -$emailJson = @{ - message = @{ - subject = $subject - body = @{ - contentType = "Text" - content = $body - } - toRecipients = @(@{ emailAddress = @{ address = $toEmail } }) - attachments = @(@{ - "@odata.type" = "#microsoft.graph.fileAttachment" - name = "AutopilotHash_$serialNumber.csv" - contentType = "text/csv" - contentBytes = [Convert]::ToBase64String([System.IO.File]::ReadAllBytes($csvPath)) - }) - } -} - -$emailJson = $emailJson | ConvertTo-Json -Depth 10 - -Write-Host "Sending email..." -Invoke-RestMethod -Uri $graphUrl -Headers @{Authorization = "Bearer $accessToken"; "Content-Type" = "application/json"} -Method Post -Body $emailJson - -Write-Host "Email sent to $toEmail" - -# Cleanup -Remove-Item -Path $csvPath -Force -Remove-Item -Path $autopilotScript -Force diff --git a/Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1 b/Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1 deleted file mode 100644 index d3b19a1..0000000 --- a/Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1 +++ /dev/null @@ -1,173 +0,0 @@ -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 - } -} diff --git a/Get-WindowsAutoPilotInfo.ps1 b/Get-WindowsAutoPilotInfo.ps1 deleted file mode 100644 index 133a057..0000000 --- a/Get-WindowsAutoPilotInfo.ps1 +++ /dev/null @@ -1,190 +0,0 @@ -<#PSScriptInfo - -.VERSION 1.3 - -.GUID ebf446a3-3362-4774-83c0-b7299410b63f - -.AUTHOR Michael Niehaus - -.COMPANYNAME Microsoft - -.COPYRIGHT - -.TAGS Windows AutoPilot - -.LICENSEURI - -.PROJECTURI - -.ICONURI - -.EXTERNALMODULEDEPENDENCIES - -.REQUIREDSCRIPTS - -.EXTERNALSCRIPTDEPENDENCIES - -.RELEASENOTES -Version 1.0: Original published version. -Version 1.1: Added -Append switch. -Version 1.2: Added -Credential switch. -Version 1.3: Added -Partner switch. - -#> - -<# -.SYNOPSIS -Retrieves the Windows AutoPilot deployment details from one or more computers -.DESCRIPTION -This script uses WMI to retrieve properties needed by the Microsoft Store for Business to support Windows AutoPilot deployment. -.PARAMETER Name -The names of the computers. These can be provided via the pipeline (property name Name or one of the available aliases, DNSHostName, ComputerName, and Computer). -.PARAMETER OutputFile -The name of the CSV file to be created with the details for the computers. If not specified, the details will be returned to the PowerShell -pipeline. -.PARAMETER Append -Switch to specify that new computer details should be appended to the specified output file, instead of overwriting the existing file. -.PARAMETER Credential -Credentials that should be used when connecting to a remote computer (not supported when gathering details from the local computer). -.PARAMETER Partner -Switch to specify that the created CSV file should use the schema for Partner Center (using serial number, make, and model). -.EXAMPLE -.\Get-WindowsAutoPilotInfo.ps1 -ComputerName MYCOMPUTER -OutputFile .\MyComputer.csv -.EXAMPLE -.\Get-WindowsAutoPilotInfo.ps1 -ComputerName MYCOMPUTER -OutputFile .\MyComputer.csv -Append -.EXAMPLE -.\Get-WindowsAutoPilotInfo.ps1 -ComputerName MYCOMPUTER1,MYCOMPUTER2 -OutputFile .\MyComputers.csv -.EXAMPLE -Get-ADComputer -Filter * | .\GetWindowsAutoPilotInfo.ps1 -OutputFile .\MyComputers.csv -.EXAMPLE -Get-CMCollectionMember -CollectionName "All Systems" | .\GetWindowsAutoPilotInfo.ps1 -OutputFile .\MyComputers.csv -.EXAMPLE -.\Get-WindowsAutoPilotInfo.ps1 -ComputerName MYCOMPUTER1,MYCOMPUTER2 -OutputFile .\MyComputers.csv -Partner - -#> - -[CmdletBinding()] -param( - [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Position=0)][alias("DNSHostName","ComputerName","Computer")] [String[]] $Name = @($env:ComputerName), - [Parameter(Mandatory=$False)] [String] $OutputFile = "", - [Parameter(Mandatory=$False)] [Switch] $Append = $false, - [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $Credential = $null, - [Parameter(Mandatory=$False)] [Switch] $Partner = $false, - [Parameter(Mandatory=$False)] [Switch] $Force = $false -) - -Begin -{ - # Initialize empty list - $computers = @() -} - -Process -{ - foreach ($comp in $Name) - { - $bad = $false - - # Get the common properties. - Write-Verbose "Checking $comp" - $serial = (Get-WmiObject -ComputerName $comp -Credential $Credential -Class Win32_BIOS).SerialNumber - - # Get the hash (if available) - $devDetail = (Get-WMIObject -ComputerName $comp -Credential $Credential -Namespace root/cimv2/mdm/dmmap -Class MDM_DevDetail_Ext01 -Filter "InstanceID='Ext' AND ParentID='./DevDetail'") - if ($devDetail -and (-not $Force)) - { - $hash = $devDetail.DeviceHardwareData - } - else - { - $bad = $true - $hash = "" - } - - # If the hash isn't available, get the make and model - if ($bad -or $Force) - { - $cs = Get-WmiObject -ComputerName $comp -Credential $Credential -Class Win32_ComputerSystem - $make = $cs.Manufacturer.Trim() - $model = $cs.Model.Trim() - if ($Partner) - { - $bad = $false - } - } - else - { - $make = "" - $model = "" - } - - # Getting the PKID is generally problematic for anyone other than OEMs, so let's skip it here - $product = "" - - # Depending on the format requested, create the necessary object - if ($Partner) - { - # Create a pipeline object - $c = New-Object psobject -Property @{ - "Device Serial Number" = $serial - "Windows Product ID" = $product - "Hardware Hash" = $hash - "Manufacturer name" = $make - "Device model" = $model - } - # From spec: - # "Manufacturer Name" = $make - # "Device Name" = $model - - } - else - { - # Create a pipeline object - $c = New-Object psobject -Property @{ - "Device Serial Number" = $serial - "Windows Product ID" = $product - "Hardware Hash" = $hash - } - } - - # Write the object to the pipeline or array - if ($bad) - { - # Report an error when the hash isn't available - Write-Error -Message "Unable to retrieve device hardware data (hash) from computer $comp" -Category DeviceError - } - elseif ($OutputFile -eq "") - { - $c - } - else - { - $computers += $c - } - - } -} - -End -{ - if ($OutputFile -ne "") - { - if ($Append) - { - if (Test-Path $OutputFile) - { - $computers += Import-CSV -Path $OutputFile - } - } - if ($Partner) - { - $computers | Select "Device Serial Number", "Windows Product ID", "Hardware Hash", "Manufacturer name", "Device model" | ConvertTo-CSV -NoTypeInformation | % {$_ -replace '"',''} | Out-File $OutputFile - # From spec: - # $computers | Select "Device Serial Number", "Windows Product ID", "Hardware Hash", "Manufacturer Name", "Device Name" | ConvertTo-CSV -NoTypeInformation | % {$_ -replace '"',''} | Out-File $OutputFile - } - else - { - $computers | Select "Device Serial Number", "Windows Product ID", "Hardware Hash" | ConvertTo-CSV -NoTypeInformation | % {$_ -replace '"',''} | Out-File $OutputFile - } - } -} \ No newline at end of file diff --git a/GetAutoPilot.CMD b/GetAutoPilot.CMD deleted file mode 100644 index 1c776ff..0000000 --- a/GetAutoPilot.CMD +++ /dev/null @@ -1,7 +0,0 @@ -@ECHO OFF -echo Enabling WinRM -PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command Enable-PSRemoting -SkipNetworkProfileCheck -Force -echo Gathering AutoPilot Hash -PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command %~dp0Get-WindowsAutoPilotInfo.ps1 -ComputerName $env:computername -OutputFile %~dp0compHash.csv -append -echo Done! -pause \ No newline at end of file diff --git a/GetAutoPilotShutdown.CMD b/GetAutoPilotShutdown.CMD deleted file mode 100644 index eea6ba8..0000000 --- a/GetAutoPilotShutdown.CMD +++ /dev/null @@ -1,9 +0,0 @@ -@ECHO OFF -echo Enabling WinRM -PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command Enable-PSRemoting -SkipNetworkProfileCheck -Force -echo Gathering AutoPilot Hash -PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command %~dp0Get-WindowsAutoPilotInfo.ps1 -ComputerName $env:computername -OutputFile %~dp0compHash.csv -append -echo Done! -dir -pause -shutdown.exe -s -t 0 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..da6ea66 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Autopilot — moved + +This repository has **moved to Forgejo** and is no longer maintained here. + +➡️ **New location:** https://forgejo.oskamp.info/ivooskamp/Autopilot.git + +Only the current, usable scripts were migrated: + +- `Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1` — modern, self-contained hash + collection (Get-CimInstance, handles execution policy, optional Intune upload). +- `start.bat` — launcher for the v4 script. + +The obsolete Microsoft v1.3 script, the `GetAutoPilot*.CMD` launchers and the +email-export script were intentionally left behind and not migrated. + +Please update your remotes: + +```bash +git remote set-url origin https://forgejo.oskamp.info/ivooskamp/Autopilot.git +``` + +This Gitea copy has been emptied intentionally and is kept only as a redirect. diff --git a/start.bat b/start.bat deleted file mode 100644 index 90b89f5..0000000 --- a/start.bat +++ /dev/null @@ -1,4 +0,0 @@ -@echo off -powershell.exe -ExecutionPolicy Bypass -File "%~dp0Get-WindowsAutoPilotInfo-IdiotProof-v4.ps1" -pause -shutdown -s -t 0