Public/Get-IntuneAppGroup.ps1
|
<# .SYNOPSIS Gets Intune app assignment groups from Microsoft Entra ID. .DESCRIPTION The Get-IntuneAppGroup function finds the groups created by New-IntuneAppGroup. With -Name it returns the app groups and app collection groups of those applications ('Intune-AG-<Name>-<Intent>' and 'Intune-ACG-<Name>-<Intent>'); the name is converted to PascalCase the same way as in New-IntuneAppGroup. With -All it returns every group whose name starts with 'Intune-AG-' or 'Intune-ACG-'. Groups are found with a startswith filter on the display name (all result pages). Each group is returned as a Tcs.Azure.IntuneAppGroup object with Name, Id, AppName, Intent, Status ('Existing') and MailNickname, so it can be piped to Remove-IntuneAppGroup. AppName and Intent are read from the group name and are empty for a group that does not follow the naming pattern. Requires the Microsoft Entra PowerShell module (Microsoft.Entra or Microsoft.Entra.Groups) and a session opened with Connect-Entra that can read groups, for example the Group.Read.All scope. .PARAMETER Name One or more application names. Accepts pipeline input. .PARAMETER All Return every group whose name starts with 'Intune-AG-' or 'Intune-ACG-'. .INPUTS System.String Application names. .OUTPUTS Tcs.Azure.IntuneAppGroup .EXAMPLE Get-IntuneAppGroup -Name 'Company Portal' Returns Intune-AG-CompanyPortal-Available, Intune-AG-CompanyPortal-Required and any other groups for Company Portal that exist. .EXAMPLE Get-IntuneAppGroup -All | Group-Object -Property AppName Lists every Intune app group, grouped by application. .NOTES Author: Nigel Tatschner Company: TheCodeSaiyan .LINK New-IntuneAppGroup .LINK Remove-IntuneAppGroup .LINK https://learn.microsoft.com/powershell/module/microsoft.entra.groups/get-entragroup #> function Get-IntuneAppGroup { [CmdletBinding(DefaultParameterSetName = 'ByName')] [OutputType('Tcs.Azure.IntuneAppGroup')] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'ByName')] [Alias('AppName')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory = $true, ParameterSetName = 'All')] [switch] $All ) begin { $TelemetryArgs = @{ ModuleName = $MyInvocation.MyCommand.Module.Name ModuleVersion = [string]$MyInvocation.MyCommand.Module.Version CommandName = $MyInvocation.MyCommand.Name ExecutionID = [guid]::NewGuid().ToString() } Invoke-TelemetryCollection @TelemetryArgs -Stage Start -ClearTimer $lastError = $null $telemetrySent = $false $prerequisiteError = Get-EntraPrerequisiteError -CommandName $MyInvocation.MyCommand.Name -RequiredCommand 'Get-EntraGroup' if ($prerequisiteError) { $telemetrySent = $true Invoke-TelemetryCollection @TelemetryArgs -Stage End -Failed $true -Exception $prerequisiteError $PSCmdlet.ThrowTerminatingError($prerequisiteError) } } process { $completed = $false try { if ($PSCmdlet.ParameterSetName -eq 'All') { try { Find-IntuneAppGroup | ForEach-Object { ConvertTo-IntuneAppGroupObject -Group $_ } } catch [System.Management.Automation.PipelineStoppedException] { throw } catch { $lastError = $_ Write-Error -ErrorRecord $_ } } else { foreach ($appName in $Name) { $pascalName = ConvertTo-TcsPascalCaseName -Text $appName if (-not $pascalName) { $exception = New-Object -TypeName System.ArgumentException -ArgumentList 'An application name cannot be blank or whitespace only.', 'Name' $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList $exception, 'BlankName', ([System.Management.Automation.ErrorCategory]::InvalidArgument), $appName $lastError = $errorRecord $PSCmdlet.WriteError($errorRecord) continue } try { Find-IntuneAppGroup -AppName $pascalName | ForEach-Object { ConvertTo-IntuneAppGroupObject -Group $_ } } catch [System.Management.Automation.PipelineStoppedException] { throw } catch { $lastError = $_ Write-Error -ErrorRecord $_ } } } $completed = $true } catch { $lastError = $_ throw } finally { # The end block does not run after a terminating error or when a downstream command # (for example Select-Object -First) stops the pipeline, so End telemetry is sent here. if (-not $completed -and -not $telemetrySent) { $telemetrySent = $true if ($lastError) { Invoke-TelemetryCollection @TelemetryArgs -Stage End -Failed $true -Exception $lastError } else { Invoke-TelemetryCollection @TelemetryArgs -Stage End } } } } end { if (-not $telemetrySent) { $telemetrySent = $true if ($lastError) { Invoke-TelemetryCollection @TelemetryArgs -Stage End -Failed $true -Exception $lastError } else { Invoke-TelemetryCollection @TelemetryArgs -Stage End } } } } |