Last active
February 5, 2024 13:32
-
-
Save nicolonsky/29568077bcad7135ea7a6182742f4a55 to your computer and use it in GitHub Desktop.
Bulk Update Windows Autopilot entities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Connect-MSGraph | |
Update-MSGraphEnvironment -SchemaVersion "Beta" -Quiet | |
Connect-MSGraph -Quiet | |
# Get all autopilot devices (even if more than 1000) | |
$autopilotDevices = Invoke-MSGraphRequest -HttpMethod GET -Url "deviceManagement/windowsAutopilotDeviceIdentities" | Get-MSGraphAllPages | |
# Display gridview to show devices | |
$selectedAutopilotDevices = $autopilotDevices | Out-GridView -OutputMode Multiple -Title "Select Windows Autopilot entities to update" | |
$selectedAutopilotDevices | ForEach-Object { | |
$autopilotDevice = $PSItem | |
# Change names according to your environment | |
$autopilotDevice.groupTag = "MOSD" | |
#$autopilotDevice.orderIdentifier = "ORDER1234" | updating orderidentifier is currently not supported | |
$requestBody= | |
@" | |
{ | |
groupTag: `"$($autopilotDevice.groupTag)`", | |
} | |
"@ | |
Write-Output "Updating entity: $($autopilotDevice.id) | groupTag: $($autopilotDevice.groupTag) | orderIdentifier: $($autopilotDevice.orderIdentifier)" | |
Invoke-MSGraphRequest -HttpMethod POST -Content $requestBody -Url "deviceManagement/windowsAutopilotDeviceIdentities/$($autopilotDevice.id)/UpdateDeviceProperties" | |
} | |
# Invoke an autopilot service sync | |
Invoke-MSGraphRequest -HttpMethod POST -Url "deviceManagement/windowsAutopilotSettings/sync" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I was using this to bulk update my customers devices after they had been hybrid joined to Intune and sucked into Autopilot by assigning them to an Autopilot profile which is set to convert all assigned devices to Autopilot. I needed to set a tag on each device depending on which on-prem OU the device was originating from so that when it is built from Autopilot it can be Domain Joined into the same OU (use a group with a dynamic device rule for each tag). This worked fine up until sometime around september last year. I have since then had 2 other projects for other customers who are on the same journey and needed the same thing. Unfortunately I was forced to tag each device manually in Intune :(
This is the script which worked before and has stopped working now - it is based on your wonderful code above. Can anyone help explain why it no longer works or how to get it working again?
`# GroupTagBulkListWinAutopilotDevices-v4.ps1
Run this script with local admin rights, preferably on a Windows server.
$ErrorActionPreference = "SilentlyContinue"
Trust scripts downloaded from the PSGallery
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
Update Nuget Package and PowerShellGet Module
Install-PackageProvider NuGet -Scope CurrentUser -Force
Install the required PowerShellGet module if not already installed
if (-not (Get-Module -ListAvailable -Name PowerShellGet)) {
Install-Module PowerShellGet -Scope CurrentUser -Force -AllowClobber
}
Remove old modules from existing session
Remove-Module PowerShellGet,PackageManagement -Force -ErrorAction Ignore
Import updated module
Import-Module PowerShellGet -MinimumVersion 2.0 -Force
Import-PackageProvider PowerShellGet -MinimumVersion 2.0 -Force
MSAL is used with a registered MsalClientApplication in Azure for MSGraph Authentication and requires a -ClientId and -ClientSecret or Certificate
See https://github.com/AzureAD/MSAL.PS
Install the required MSAL.PS module if not already installed (Not supported by Microsoft)
if (-not (Get-Module -ListAvailable -Name "MSAL.PS")) {
Install-Module -Name "MSAL.PS" -SkipPublisherCheck -Force -AllowClobber
}
Install the required AzureAD module if not already installed
if (-not (Get-Module -ListAvailable -Name AzureAD)) {
Install-Module -Name AzureAD -Force -AllowClobber
}
Install the required Graph.Intune module if not already installed
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Intune)) {
Install-Module -Name Microsoft.Graph.Intune -Force -AllowClobber
}
Check if the OS is a client version
$isClientOS = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
If it is a client OS
if ($isClientOS) {
# Check if RSAT is installed for Windows 10 or 11 client OS
$feature = Get-WindowsCapability -Online | Where-Object { $_.Name -like 'Rsat*' }
if ($feature.Count -gt 0 -and $feature[0].State -ne 'Installed') {
# Install RSAT tools
Add-WindowsCapability -Online -Name $feature[0].Name
}
}
If it is not a client OS
if (-not $isClientOS) {
# Check if RSAT-AD-PowerShell feature is installed (ONLY WORKS ON SERVER OS)
$featureInstalled = Get-WindowsFeature RSAT-AD-PowerShell -ErrorAction SilentlyContinue
# If not installed, install the feature (ONLY WORKS ON SERVER OS)
if ($featureInstalled -eq $null) {
Install-WindowsFeature RSAT-AD-PowerShell -IncludeAllSubFeature -IncludeManagementTools
}
}
Install the required ActiveDirectory module if not already installed
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
Install-Module -Name ActiveDirectory -Force -AllowClobber
}
Import Modules that are not loaded for the current session
Check if AzureAD module is already imported
if (-not (Get-Module -Name AzureAD -ListAvailable)) {
Import-Module -Name AzureAD -Force
}
Check if ActiveDirectory module is already imported
if (-not (Get-Module -Name ActiveDirectory -ListAvailable)) {
Import-Module -Name ActiveDirectory -Force
}
Check if Microsoft.Graph.Intune module is already imported
if (-not (Get-Module -Name Microsoft.Graph.Intune -ListAvailable)) {
Import-Module -Name Microsoft.Graph.Intune -Force
}
Connect-MSGraph
Update-MSGraphEnvironment -SchemaVersion "Beta" -Quiet
Set-MgEnvironment -GraphEndpoint "https://graph.microsoft.com/v1.0" -SchemaVersion "beta"
Connect-MSGraph -Quiet
CLS
Define parameters for AD retrieval of computer objects from an OU so that they can be tagged the same.
$OUpath = 'OU=HybridJoin,OU=Laptop,OU=Workstations,OU=Contoso,DC=com'
$GrpTag = "Book"
$OUpath = 'OU=HybridJoin,OU=Conference,OU=Workstations,OU=Contoso,DC=com'
$GrpTag = "Conf"
$OUpath = 'OU=HybridJoin,OU=Desktop,OU=Workstations,OU=Contoso,DC=com'
$GrpTag = "Dtop"
$ExportPath = 'c:\temp\computers_in_ou.csv'
Get-ADComputer -Filter * -SearchBase $OUpath | Select-object Name | Export-Csv -NoType $ExportPath -Force
Define the input file path
$InputFilePath = 'c:\temp\computers_in_ou.csv'
Fetch all devices from Intune
$intuneDevices = Invoke-MSGraphRequest -HttpMethod GET -Url "deviceManagement/managedDevices" | Get-MSGraphAllPages
Load computer names from the input file
$computerNames = Get-Content -Path $InputFilePath
Define an array to store results
$results = @()
foreach ($computer in $computerNames) {
Write-Output "A Computer was found named: " $computer
$PC = $computer.Trim('"')
# Find a matching device in Intune based on computer name
Write-Output "Trying to match " $.deviceName " and " $PC
$matchedDevice = $intuneDevices | Where-Object { $.deviceName -eq $PC }
"@
}
Invoke an autopilot service sync
Invoke-MSGraphRequest -HttpMethod POST -Url "deviceManagement/windowsAutopilotSettings/sync"
Remove all values from used variables
$OUpath = $null
$ExportPath = $null
$InputFilePath = $null
$intuneDevices = $null
$computerNames = $null
$results = $null
$computer = $null
$PC = $null
$matchedDevice = $null
$computerSerial = $null
$autopilotDevices = $null
$matchedDevice2 = $null
$requestBody = $null
Delete the input file
Remove-Item -Path $InputFilePath -Force
`