Public/Import-IntuneDeviceFilter.ps1
|
function Import-IntuneDeviceFilter { <# .SYNOPSIS Creates device filters for Intune .DESCRIPTION Creates device filters by manufacturer for each device OS platform (Windows, macOS, iOS/iPadOS, Android). Creates 3 manufacturer filters per OS: Dell/HP/Lenovo for Windows, Apple for macOS/iOS. .EXAMPLE Import-IntuneDeviceFilter #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter()] [switch]$RemoveExisting ) $results = @() # Get all existing filters first with pagination (OData filter on displayName not supported for this endpoint) # Store full filter objects so we can check descriptions later $existingFilters = @{} try { $listUri = "beta/deviceManagement/assignmentFilters?`$select=id,displayName,description" do { $existingFiltersResponse = Invoke-MgGraphRequest -Method GET -Uri $listUri -ErrorAction Stop foreach ($existingFilter in $existingFiltersResponse.value) { if (-not $existingFilters.ContainsKey($existingFilter.displayName)) { $existingFilters[$existingFilter.displayName] = @{ Id = $existingFilter.id Description = $existingFilter.description } } } $listUri = $existingFiltersResponse.'@odata.nextLink' } while ($listUri) } catch { Write-Warning "Could not retrieve existing filters: $_" $existingFilters = @{} } # Build a simple name->id lookup for backwards compatibility in the import section $existingFilterNames = @{} foreach ($key in $existingFilters.Keys) { $existingFilterNames[$key] = $existingFilters[$key].Id } # Define filters first so we know what to delete $filterDefinitions = @( # Windows filters by manufacturer @{ DisplayName = "Windows - Dell Devices" Description = "Filter for Dell Windows devices" Platform = "windows10AndLater" Rule = '(device.manufacturer -eq "Dell Inc.")' }, @{ DisplayName = "Windows - HP Devices" Description = "Filter for HP Windows devices" Platform = "windows10AndLater" Rule = '(device.manufacturer -eq "HP") or (device.manufacturer -eq "Hewlett-Packard")' }, @{ DisplayName = "Windows - Lenovo Devices" Description = "Filter for Lenovo Windows devices" Platform = "windows10AndLater" Rule = '(device.manufacturer -eq "LENOVO")' }, # macOS filters @{ DisplayName = "macOS - Apple Devices" Description = "Filter for Apple macOS devices" Platform = "macOS" Rule = '(device.manufacturer -eq "Apple")' }, @{ DisplayName = "macOS - MacBook Devices" Description = "Filter for MacBook devices" Platform = "macOS" Rule = '(device.model -startsWith "MacBook")' }, @{ DisplayName = "macOS - iMac Devices" Description = "Filter for iMac devices" Platform = "macOS" Rule = '(device.model -startsWith "iMac")' }, # iOS/iPadOS filters @{ DisplayName = "iOS - iPhone Devices" Description = "Filter for iPhone devices" Platform = "iOS" Rule = '(device.model -startsWith "iPhone")' }, @{ DisplayName = "iOS - iPad Devices" Description = "Filter for iPad devices" Platform = "iOS" Rule = '(device.model -startsWith "iPad")' }, @{ DisplayName = "iOS - Corporate Owned" Description = "Filter for corporate-owned iOS/iPadOS devices" Platform = "iOS" Rule = '(device.deviceOwnership -eq "Corporate")' }, # Android filters @{ DisplayName = "Android - Samsung Devices" Description = "Filter for Samsung Android devices" Platform = "androidForWork" Rule = '(device.manufacturer -eq "samsung")' }, @{ DisplayName = "Android - Google Pixel Devices" Description = "Filter for Google Pixel devices" Platform = "androidForWork" Rule = '(device.manufacturer -eq "Google")' }, @{ DisplayName = "Android - Corporate Owned" Description = "Filter for corporate-owned Android devices" Platform = "androidForWork" Rule = '(device.deviceOwnership -eq "Corporate")' } ) # Remove existing filters if requested # SAFETY: Only delete filters that have "Imported by Intune-Hydration-Kit" in description if ($RemoveExisting) { foreach ($filterName in $existingFilters.Keys) { $filterInfo = $existingFilters[$filterName] # Safety check: Only delete if created by this kit (has hydration marker in description) if (-not (Test-HydrationKitObject -Description $filterInfo.Description -ObjectName $filterName)) { Write-Verbose "Skipping '$filterName' - not created by Intune-Hydration-Kit" continue } if ($PSCmdlet.ShouldProcess($filterName, "Delete device filter")) { try { Invoke-MgGraphRequest -Method DELETE -Uri "beta/deviceManagement/assignmentFilters/$($filterInfo.Id)" -ErrorAction Stop Write-HydrationLog -Message " Deleted: $filterName" -Level Info $results += New-HydrationResult -Name $filterName -Type 'DeviceFilter' -Action 'Deleted' -Status 'Success' } catch { $errMessage = Get-GraphErrorMessage -ErrorRecord $_ Write-HydrationLog -Message " Failed: $filterName - $errMessage" -Level Warning $results += New-HydrationResult -Name $filterName -Type 'DeviceFilter' -Action 'Failed' -Status "Delete failed: $errMessage" } } else { Write-HydrationLog -Message " WouldDelete: $filterName" -Level Info $results += New-HydrationResult -Name $filterName -Type 'DeviceFilter' -Action 'WouldDelete' -Status 'DryRun' } } return $results } foreach ($filter in $filterDefinitions) { try { # Check if filter already exists using pre-fetched list if ($existingFilterNames.ContainsKey($filter.DisplayName)) { Write-HydrationLog -Message " Skipped: $($filter.DisplayName)" -Level Info $results += New-HydrationResult -Name $filter.DisplayName -Id $existingFilterNames[$filter.DisplayName] -Platform $filter.Platform -Action 'Skipped' -Status 'Already exists' continue } if ($PSCmdlet.ShouldProcess($filter.DisplayName, "Create device filter")) { $filterBody = @{ displayName = $filter.DisplayName description = "$($filter.Description) - Imported by Intune-Hydration-Kit" platform = $filter.Platform rule = $filter.Rule roleScopeTags = @("0") } $newFilter = Invoke-MgGraphRequest -Method POST -Uri "beta/deviceManagement/assignmentFilters" -Body $filterBody -ErrorAction Stop Write-HydrationLog -Message " Created: $($filter.DisplayName)" -Level Info $results += New-HydrationResult -Name $filter.DisplayName -Id $newFilter.id -Platform $filter.Platform -Action 'Created' -Status 'Success' } else { Write-HydrationLog -Message " WouldCreate: $($filter.DisplayName)" -Level Info $results += New-HydrationResult -Name $filter.DisplayName -Platform $filter.Platform -Action 'WouldCreate' -Status 'DryRun' } } catch { Write-HydrationLog -Message " Failed: $($filter.DisplayName) - $_" -Level Warning $results += New-HydrationResult -Name $filter.DisplayName -Platform $filter.Platform -Action 'Failed' -Status $_.Exception.Message } } return $results } |