Set-PsIntuneDeviceCategory.ps1
function Set-PSIntuneDeviceCategory { <# .SYNOPSIS Batch update Intune device category assignment .DESCRIPTION Batch update Intune device category assignment using an input file (csv or txt) to filter the computer names .PARAMETER IntputFile Path and name of .CSV or .TXT input file CSV file must have a column named "Computer" TXT file must be computer names only, one per line .PARAMETER CategoryName A valid category name. If the name does not exist in the Intune subscription, it will return an error .PARAMETER Credential User with permissions to access and modify Intune managed devices .EXAMPLE Set-PSIntuneDeviceCategory -InputFile ".\computers.txt" -CategoryName "Personal" -Credential $mycredential .EXAMPLE Set-PSIntuneDeviceCategory -InputFile ".\computers.csv" -CategoryName "Corporate" -Credential $mycredential .NOTES Requires an Azure AD app registration with Application permissions assigned: Device.Read / Read.All / ReadWrite.All DeviceManagementManagedDevice.Read.All / ReadWrite.All 0.1 - 2021-02-03 - David Stein, Catapult Systems #> [CmdletBinding(SupportsShouldProcess=$True)] param ( [parameter(Mandatory)][string][ValidateNotNullOrEmpty()] $InputFile, [parameter(Mandatory)][string] $CategoryName, [parameter(Mandatory)][pscredential] $Credential ) if (-not(Test-Path $InputFile)) { throw "file not found: $InputFile" } if ($InputFile.EndsWith(".csv")) { [array]$computers = Import-Csv -Path $InputFile | Select-Object Computer } elseif ($InputFile.EndsWith(".txt")) { [array]$computers = Get-Content -Path $InputFile | Where-Object {-not($($_).ToString().StartsWith(';'))} } else { throw "invalid file type (.csv or .txt only)" } if ($computers.Count -gt 0) { Write-Host "processing $($computers.Count) computer names" } else { throw "no computers were imported from file" } Write-Verbose "connecting to: azure ad" $azconn = Connect-AzureAD -Credential $Credential -ErrorAction Stop if (!$WhatIfPreference) { Write-Verbose "connected to $($azconn.TenantDomain)" } Write-Verbose "connecting to: msgraph" $conn = Connect-MSGraph -Credential $credential -PassThru Update-MSGraphEnvironment -SchemaVersion 'beta' | Out-Null [string]$baseUrl = "https://graph.microsoft.com/beta" Write-Verbose "getting devices" [array]$devices = Get-DeviceManagement_ManagedDevices Write-Verbose "returned $($devices.Count) devices" Write-Verbose "getting device categories" [array]$cats = Get-DeviceManagement_DeviceCategories Write-Verbose "returned $($cats.Count) categories" Write-Verbose "validating requested category: $CategoryName" $cat = $cats | Where-Object {$_.displayName -eq $CategoryName} if ($null -eq $cat) { throw "category not found: $CategoryName" } $DeviceCategory = $cat.id Write-Verbose "categoryId........ $DeviceCategory" function Set-DeviceCategory { [CmdletBinding(SupportsShouldProcess=$True)] param ( [parameter(Mandatory)][string] $DeviceID, [parameter(Mandatory)][string] $CategoryID ) Write-Verbose "updating device... $DeviceID" $requestBody = @{ "@odata.id" = "$baseUrl/deviceManagement/deviceCategories/$CategoryID" } $url = "$baseUrl/deviceManagement/managedDevices/$DeviceID/deviceCategory/`$ref" Write-Verbose "request-url: $url" if (!$WhatIfPreference) { $result = Invoke-MSGraphRequest -HttpMethod PUT -Url $url -Content $requestBody } else { Write-Host "[WHAT-IF] would submit request to graph API" -ForegroundColor Cyan } #$result } foreach ($computer in $computers) { $device = $devices | Where-Object {$_.deviceName -eq $computer} if ($null -eq $device) { Write-Warning "device not found: $computer" } else { $deviceid = $device.id Write-Verbose "deviceName........ $computer" Write-Verbose "deviceId.......... $deviceId" Write-Verbose "current-category.. $($device.deviceCategoryDisplayName)" Set-DeviceCategory -DeviceID $device.id -category $DeviceCategory } } } |