-
-
Save nicolonsky/29568077bcad7135ea7a6182742f4a55 to your computer and use it in GitHub Desktop.
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" |
Hi Nicola,
I am trying to run above script but I am getting below error. Could you please assist with this issue?
I am able to use GET function but the POST Content and Sync functions.
Updating entity: M00ABBD | groupTag: TESTAutoPilot | orderIdentifier:
Invoke-MSGraphRequest : 404 Not Found
{"error":{"code":"ResourceNotFound","message":"{\r\n "_version": 3,\r\n "Message": "An error has occurred - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: df4dbdd1-2000-4145-84a5-2e501c6437b0 -
Url: https://fef.msua07.manage.microsoft.com/DeviceEnrollmentFE_2306/StatelessDeviceEnrollmentFEService/deviceManagement/windowsAutopilotDeviceIdentities('M00ABBD')/microsoft.management.services.api.updateDeviceProperties?api-version=5023-05-11
",\r\n "CustomApiErrorPhrase": "",\r\n "RetryAfter": null,\r\n "ErrorSourceService": "",\r\n "HttpHeaders":
"{}"\r\n}","innerError":{"date":"2023-07-17T05:26:56","request-id":"df4dbdd1-20bb-4145-84a5-2e501c6437b0","client-request-id":"df4dbdd1-20bb-4145-84a5-2e501c6437b0"}}}
At C:\Temp\Add-Update-GroupTagstoAutoPilotDevices\2-Add-Update-GroupTagstoAutoPilotDevices.ps1:31 char:5
-
Invoke-MSGraphRequest -HttpMethod POST -Content $requestBody -Url ...
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- CategoryInfo : ConnectionError: (@{Request=; Response=}:PSObject) [Invoke-MSGraphRequest], HttpRequestException
- FullyQualifiedErrorId : PowerShellGraphSDK_HttpRequestError,Microsoft.Intune.PowerShellGraphSDK.PowerShellCmdlets.InvokeRequest
Regards,
Ravikant
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 }
if ($matchedDevice) {
Write-Output "Matching Success"
$results += [PSCustomObject]@{
ComputerName = $PC
SerialNumber = $matchedDevice.serialNumber
}
$computerSerial = $matchedDevice.serialNumber
Write-Output "SN " $computerSerial
# Get all autopilot devices
$autopilotDevices = Invoke-MSGraphRequest -HttpMethod GET -Url "deviceManagement/windowsAutopilotDeviceIdentities" | Get-MSGraphAllPages
$matchedDevice2 = $autopilotDevices | Where-Object { $_.serialNumber -eq $computerSerial }
if ($matchedDevice2) {
$matchedDevice2.groupTag = $GrpTag
$requestBody = @"
{
groupTag: "`"$($matchedDevice2.groupTag)`"",
}
"@
Write-Output "Updating entity: $($matchedDevice2.id) | groupTag: $($matchedDevice2.groupTag)"
Invoke-MSGraphRequest -HttpMethod POST -Content $requestBody -Url "deviceManagement/windowsAutopilotDeviceIdentities/$($matchedDevice2.id)/UpdateDeviceProperties"
}
}
}
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
`
Great script! I have 3500 devices that were converted to Autopilot and will ultimately need GroupTags added so they can be reset. Is the existing device name available in the grid view so we can multi-select and apply GroupTags? That would really sweeten this up since the devices are already prepended with the correct site code (that match the GroupTags.)