Public/Feature/FeatureStatesQuery/Get-AdoFeatureState.ps1

function Get-AdoFeatureState {
    <#
    .SYNOPSIS
        Get the feature states for an Azure DevOps project.
 
    .DESCRIPTION
        This cmdlet retrieves the feature states for an Azure DevOps project through REST API.
        Returns the states for Boards, Repos, Pipelines, Test Plans, and Artifacts features.
 
    .PARAMETER CollectionUri
        Optional. The collection URI of the Azure DevOps collection/organization, e.g., https://dev.azure.com/my-org.
 
    .PARAMETER ProjectName
        Optional. The ID or name of the project. Defaults to the value of $env:DefaultAdoProject.
 
    .PARAMETER Version
        Optional. The API version to use. Default is '4.1-preview.1'.
 
    .OUTPUTS
        [PSCustomObject]@{
            feature : Feature name (e.g., 'boards', 'repos', 'pipelines', 'testPlans', 'artifacts')
            state : State of the feature (e.g., 'enabled', 'disabled')
            featureId : Feature ID (e.g., 'ms.vss-code.version-control')
            projectName : Name of the project
            collectionUri : Collection URI used
        }
 
    .LINK
        https://learn.microsoft.com/en-us/rest/api/azure/devops/feature-management/featurestatesquery
 
    .EXAMPLE
        $params = @{
            CollectionUri = 'https://dev.azure.com/my-org'
            ProjectName = 'my-project-1'
        }
        Get-AdoFeatureState @params
 
        Retrieves the feature states for the specified project.
 
    .EXAMPLE
        Get-AdoFeatureState -ProjectName 'my-project-1'
 
        Retrieves the feature states using the default collection URI from environment variable.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([PSCustomObject])]
    param (
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateScript({ Confirm-CollectionUri -Uri $_ })]
        [string]$CollectionUri = $env:DefaultAdoCollectionUri,

        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('ProjectId')]
        [string]$ProjectName = $env:DefaultAdoProject,

        [Parameter()]
        [Alias('ApiVersion')]
        [ValidateSet('4.1-preview.1')]
        [string]$Version = '4.1-preview.1'
    )

    begin {
        Write-Verbose ("Command: $($MyInvocation.MyCommand.Name)")
        Write-Debug ("CollectionUri: $CollectionUri")
        Write-Debug ("ProjectName: $ProjectName")
        Write-Debug ("Version: $Version")

        Confirm-Default -Defaults ([ordered]@{
                'CollectionUri' = $CollectionUri
                'ProjectName'   = $ProjectName
            })
    }

    process {
        try {
            # Get project ID if name was provided, id is required for the API call
            try {
                [System.Guid]::Parse($ProjectName) | Out-Null
                $projectId = $ProjectName
            } catch {
                $projectId = (Get-AdoProject -CollectionUri $CollectionUri -Name $ProjectName).id
                if (-not $projectId) { return }
            }

            $uri = "$CollectionUri/_apis/FeatureManagement/FeatureStatesQuery/host/project/$projectId"

            $body = [PSCustomObject]@{
                featureIds    = @(
                    'ms.vss-work.agile'           # boards
                    'ms.vss-code.version-control' # repos
                    'ms.vss-build.pipelines'      # pipelines
                    'ms.vss-test-web.test'        # testPlans
                    'ms.azure-artifacts.feature'  # artifacts
                )
                featureStates = @{}
                scopeValues   = @{
                    project = $projectId
                }
            }

            $params = @{
                Uri     = $uri
                Version = $Version
                Method  = 'POST'
                Body    = $body
            }

            if ($PSCmdlet.ShouldProcess($CollectionUri, "Get Feature States for project '$ProjectName'")) {
                $results = Invoke-AdoRestMethod @params

                foreach ($featureId in $results.featureStates.PSObject.Properties.Name) {
                    # Get user-friendly feature name
                    $feature = switch ($featureId) {
                        'ms.vss-work.agile' { 'boards' }
                        'ms.vss-code.version-control' { 'repos' }
                        'ms.vss-build.pipelines' { 'pipelines' }
                        'ms.vss-test-web.test' { 'testPlans' }
                        'ms.azure-artifacts.feature' { 'artifacts' }
                        default { $featureId }
                    }
                    # Get feature state
                    $state = $results.featureStates.$featureId.state

                    [PSCustomObject]@{
                        feature       = $feature
                        state         = $state
                        featureId     = $featureId
                        projectName   = $ProjectName
                        collectionUri = $CollectionUri
                    }
                }
            } else {
                Write-Verbose "Calling Invoke-AdoRestMethod with $($params | ConvertTo-Json -Depth 10)"
            }
        } catch {
            throw $_
        }
    }

    end {
        Write-Verbose ("Exit: $($MyInvocation.MyCommand.Name)")
    }
}