src/Solutions/Customization/AppModule/Get-XrmAppModules.ps1

<#
    .SYNOPSIS
    Retrieve model-driven app records from Microsoft Dataverse.

    .DESCRIPTION
    Get appmodule records (model-driven apps) with optional name filter.
    Use -Unpublished to also retrieve apps that are in draft state.

    .PARAMETER XrmClient
    Xrm connector initialized to target instance. Use latest one by default. (Dataverse ServiceClient)

    .PARAMETER Name
    App display name filter. Optional.

    .PARAMETER Columns
    Specify expected columns to retrieve. (Default : all columns)

    .PARAMETER Unpublished
    When specified, uses RetrieveUnpublishedMultiple to include apps that are in draft
    (unpublished) state. Without this switch only published apps are returned.

    .PARAMETER UniqueName
    App unique name filter. Optional.

    .PARAMETER Id
    App unique identifier filter (appmoduleid). Optional.

    .OUTPUTS
    PSCustomObject[]. Array of appmodule records (XrmObject).

    .EXAMPLE
    $apps = Get-XrmAppModules;
    $app = Get-XrmAppModules -Name "Sales Hub";

    .EXAMPLE
    # Include unpublished drafts
    $allApps = Get-XrmAppModules -Unpublished;

    .EXAMPLE
    $app = Get-XrmAppModules -XrmClient $xrmClient -UniqueName "contoso_sales" -Unpublished -Columns "name";

    .LINK
    https://github.com/AymericM78/PowerDataOps/blob/main/documentation/commands/Get-XrmAppModules.md
#>

function Get-XrmAppModules {
    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param
    (
        [Parameter(Mandatory = $false, ValueFromPipeline)]
        [Microsoft.PowerPlatform.Dataverse.Client.ServiceClient]
        $XrmClient = $Global:XrmClient,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Columns = @("*"),

        [Parameter(Mandatory = $false)]
        [switch]
        $Unpublished,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]
        $UniqueName,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [Guid]
        $Id
    )
    begin {
        $StopWatch = [System.Diagnostics.Stopwatch]::StartNew();
        Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters);
    }
    process {
        $query = New-XrmQueryExpression -LogicalName "appmodule" -Columns $Columns;

        if ($PSBoundParameters.ContainsKey('Name')) {
            $query = $query | Add-XrmQueryCondition -Field "name" -Condition Equal -Values $Name;
        }
        if ($PSBoundParameters.ContainsKey('UniqueName')) {
            $query = $query | Add-XrmQueryCondition -Field "uniquename" -Condition Equal -Values $UniqueName;
        }
        if ($PSBoundParameters.ContainsKey('Id')) {
            $query = $query | Add-XrmQueryCondition -Field "appmoduleid" -Condition Equal -Values $Id;
        }

        $XrmClient | Get-XrmMultipleComponents -Query $query -Unpublished:$Unpublished;
    }
    end {
        $StopWatch.Stop();
        Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch;
    }
}

Export-ModuleMember -Function Get-XrmAppModules -Alias *;