Translate-AadGroupUserDevice.ps1
<#PSScriptInfo .VERSION 1.0 .GUID e58f9c57-2652-4e17-9676-d6aa4e78cd8b .AUTHOR Jannik Reinhard .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI https://github.com/JayRHa/Intune-Scripts/blob/main/Translate-DeivceAndUserGroups/Translate-AadGroupUserDevice.ps1 .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION Change a user group to a device group based on the device primary contact .INPUTS None required .OUTPUTS None .NOTES Author: Jannik Reinhard (jannikreinhard.com) Twitter: @jannik_reinhard Release notes: Version 1.0: Init #> Param() function Get-GraphAuthentication{ $GraphPowershellModulePath = "$global:Path/Microsoft.Graph.psd1" if (-not (Get-Module -ListAvailable -Name 'Microsoft.Graph')) { if (-Not (Test-Path $GraphPowershellModulePath)) { Write-Error "Microsoft.Graph.Intune.psd1 is not installed on the system check: https://docs.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0" Return } else { Import-Module "$GraphPowershellModulePath" $Success = $? if (-not ($Success)) { Write-Error "Microsoft.Graph.Intune.psd1 is not installed on the system check: https://docs.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0" Return } } } try { Connect-MgGraph -Scopes "Device.Read.All" } catch { Write-Error "Failed to connect to MgGraph" return $false } Select-MgProfile -Name "beta" return $true } function Get-AllGroupMember { param( [Parameter(Mandatory = $true)] $groupName ) $groupId = (Get-MgGroup -Filter "displayname eq '$groupName'").id $groupMembers = Get-MgGroupMember -GroupId $groupId $groupMembers = $groupMembers | Sort-Object -Property AdditionalProperties.displayName $items = @() $groupMembers | ForEach-Object { if($_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.user'){ $param = [PSCustomObject]@{ ItemName = $_.AdditionalProperties.displayName ItemType = "User" Id = $_.Id Uri = "https://graph.microsoft.com/v1.0/directoryObjects/" + $_.Id } $items += $param } elseif ($_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.device') { $param = [PSCustomObject]@{ ItemName = $_.AdditionalProperties.displayName ItemType = "Device" Id = $_.Id Uri = "https://graph.microsoft.com/v1.0/directoryObjects/" + $_.Id } $items += $param } elseif ($_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.group') { $colornumber= Get-Random -Maximum 9 $param = [PSCustomObject]@{ ItemName = $_.AdditionalProperties.displayName ItemType = "Group" Id = $_.Id Uri = "https://graph.microsoft.com/v1.0/directoryObjects/" + $_.Id } $items += $param } } return @($items) } function Get-MigrateGroupMember{ param ( [String]$migrationType, [array]$groupMember = $null, $windows = $true, $ios = $true, $macos = $true, $android = $true ) $os = @() if($windows){$os += 'Windows'} if($macos){$os += 'MacMDM'} if($android){$os += 'Android'} if($ios){$os += 'IOS'} $newGroupMember = @() if($migrationType -eq 'User'){ $groupMember | Where-Object {$_.ItemType -eq 'Device'} | Foreach-Object { $userId = (Get-MgDeviceRegisteredOwner -DeviceId $_.Id).Id if($userId){ $newGroupMember += [PSCustomObject]@{ Uri = "https://graph.microsoft.com/v1.0/directoryObjects/" + $userId } } } $groupMember | Where-Object {$_.ItemType -eq 'User'} | Foreach-Object { $newGroupMember += [PSCustomObject]@{ Uri = $_.Uri } } }elseif($migrationType -eq 'Device'){ $groupMember | Where-Object {$_.ItemType -eq 'User'} | Foreach-Object { (Get-MgUserOwnedDevice -UserId $_.Id) | ForEach-Object { $newGroupMember += [PSCustomObject]@{ Uri = "https://graph.microsoft.com/v1.0/directoryObjects/" + $_.Id OperatinSystem = $_.AdditionalProperties.operatingSystem } } } $groupMember | Where-Object {$_.ItemType -eq 'Device'} | Foreach-Object { $newGroupMember += [PSCustomObject]@{ Uri = $_.Uri OperatinSystem = $_.OperatinSystem } } $newGroupMember = $newGroupMember | Where-Object {$_.OperatinSystem -in $os} } $newGroupMember = $newGroupMember | Sort-Object -Property uri -Uniqu return $newGroupMember } function Get-AllAadGroup{ return Get-MgGroup -All } function Check-GroupName{ param( [Parameter(Mandatory)] $groupName, [Parameter(Mandatory)] $allGroups ) foreach ($group in $allGroups) { if($group.displayName -eq $groupName) { return $true } } return $false } function Add-MgtGroup{ param ( [Parameter(Mandatory = $true)] [String]$groupName, [String]$groupDescription = $null, [array]$groupMember = $null ) $bodyJson = @' { "displayName": "", "groupTypes": [], "mailEnabled": false, "mailNickname": "NotSet", "securityEnabled": true } '@ | ConvertFrom-Json $bodyJson.displayName = $groupName if($groupDescription){ $bodyJson | Add-Member -NotePropertyName description -NotePropertyValue $groupDescription } if($groupMember.Length -gt 0){ $bodyJson | Add-Member -NotePropertyName 'members@odata.bind' -NotePropertyValue @($groupMember.uri) } $bodyJson = $bodyJson | ConvertTo-Json New-MgGroup -BodyParameter $bodyJson } ################################################################################################# ########################################### Start ############################################### ################################################################################################# $countListGroups = 20 Get-GraphAuthentication | Out-Null # Get an check aad group $aadGroupName = Read-Host "Enter the name of the AAD Group" $groups = Get-AllAadGroup $checkGroupName = Check-GroupName -groupName $aadGroupName -allGroups $groups if(-not $checkGroupName){ Write-Warning "Group $aadGroupName not found" Write-Host "------------------------------" Write-Host "Available Groups:" -ForegroundColor Yellow $i = 0 foreach ($group in $groups) { Write-Host " - " $group.displayName $i++ if($i -gt $countListGroups -or $i -gt 100){ Write-Warning "Open the Azure Ad Portal to see all group: https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupsManagementMenuBlade/~/AllGroups" break } } Write-Host "------------------------------" while(-not $checkGroupName) { $aadGroupName = Read-Host "Enter the name of the AAD Group" $checkGroupName = Check-GroupName -groupName $aadGroupName -allGroups $groups } } $migrationType = Read-Host -Prompt "Enter the migration type. Do you want to move the group to a user group or device group? [Device, User]" while("device", "Device", "user", "User" -notcontains $migrationType ) { $migrationType = Read-Host -Prompt "Enter the migration type. Do you want to move the group to a user group or device group? [Device, User]" } $groupName = Read-Host -Prompt "Enter the name of the new group" $windows = $false $android = $false $iOS = $false $macOs = $false if($migrationType -eq "Device"){ $answer = Read-Host -Prompt "Do you want to migrate Windows Devices? [Y/N]" while("Y", "N", "Yes", "No", "y", "n" -notcontains $answer ) { $answer = Read-Host -Prompt "Do you want to migrate Windows Devices? [Y/N]" } if("Y", "Yes", "y" -contains $answer){$windows = $true} $answer = Read-Host -Prompt "Do you want to migrate Android Devices? [Y/N]" while("Y", "N", "Yes", "No", "y", "n" -notcontains $answer ) { $answer = Read-Host -Prompt "Do you want to migrate Android Devices? [Y/N]" } if("Y", "Yes", "y" -contains $answer){$android = $true} $answer = Read-Host -Prompt "Do you want to migrate iOS Devices? [Y/N]" while("Y", "N", "Yes", "No", "y", "n" -notcontains $answer ) { $answer = Read-Host -Prompt "Do you want to migrate iOS Devices? [Y/N]" } if("Y", "Yes", "y" -contains $answer){$iOS = $true} $answer = Read-Host -Prompt "Do you want to migrate MacOs Devices? [Y/N]" while("Y", "N", "Yes", "No", "y", "n" -notcontains $answer ) { $answer = Read-Host -Prompt "Do you want to migrate MacOs Devices? [Y/N]" } if("Y", "Yes", "y" -contains $answer){$macOs = $true} } $allGroupMember = Get-AllGroupMember -groupName $aadGroupName $groupMember = Get-MigrateGroupMember -migrationType $migrationType -groupMember $allGroupMember -windows $windows -ios $iOS -macos $macOs -android $android Add-MgtGroup -groupName $groupName -groupDescription " " -groupMember $groupMember |