From 94b22d3fc73f3897dec750350e9e2eb1afc1c563 Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Sat, 14 Feb 2026 14:58:49 +0000
Subject: [PATCH 1/7] Implement Get-AdoUser
---
CHANGELOG.md | 13 +-
docs/Get-AdoUser.md | 283 ++++++++++++++
docs/Get-AdoUserEntitlement.md | 2 +-
.../Azure.DevOps.PSModule.psd1 | 1 +
.../Public/Graph/Users/Get-AdoUser.ps1 | 211 +++++++++++
.../Get-AdoUserEntitlement.ps1 | 4 +-
.../Tests/Graph/Users/Get-AdoUser.Tests.ps1 | 351 ++++++++++++++++++
7 files changed, 861 insertions(+), 4 deletions(-)
create mode 100644 docs/Get-AdoUser.md
create mode 100644 src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
create mode 100644 src/Azure.DevOps.PSModule/Tests/Graph/Users/Get-AdoUser.Tests.ps1
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f53858c..3056e92 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,7 +19,18 @@ All notable changes to this project will be documented in this file.
-->
-## [0.4.0]
+
+## [UNRELEASED]
+
+### What's Changed
+- new(Get-AdoUser): Add user support (#)
+
+### Breaking Changes
+- _None_
+
+
+
+## [0.4.0] - 2026-02-13
### Summary
Feature release adding repository initialization support, enhanced user entitlement data, and improved check/approval resource management.
diff --git a/docs/Get-AdoUser.md b/docs/Get-AdoUser.md
new file mode 100644
index 0000000..76a8d33
--- /dev/null
+++ b/docs/Get-AdoUser.md
@@ -0,0 +1,283 @@
+
+
+
+
+
+# Get-AdoUser
+
+## SYNOPSIS
+
+Get a single or multiple users in an Azure DevOps organization.
+
+## SYNTAX
+
+### __AllParameterSets
+
+```text
+Get-AdoUser [[-CollectionUri] ] [[-ScopeDescriptor] ] [[-SubjectTypes] ]
+ [[-Name] ] [[-UserDescriptor] ] [[-Version] ]
+ [-WhatIf] [-Confirm] []
+```
+
+## ALIASES
+
+This cmdlet has the following aliases,
+- N/A
+
+## DESCRIPTION
+
+This function retrieves a single or multiple users in an Azure DevOps organization through REST API.
+
+## EXAMPLES
+
+### EXAMPLE 1
+
+#### PowerShell
+
+```powershell
+Get-AdoUser
+```
+
+Retrieves all users in the Azure DevOps organization.
+
+### EXAMPLE 2
+
+#### PowerShell
+
+```powershell
+$project = Get-AdoProject -Name 'my-project-1'
+$projectDescriptor = (Get-AdoDescriptor -StorageKey $project.Id)
+
+$params = @{
+ CollectionUri = 'https://dev.azure.com/my-org'
+ ScopeDescriptor = $projectDescriptor
+ SubjectTypes = 'vssgp'
+}
+Get-AdoUser @params
+```
+
+Retrieves all users in the specified project with subject types 'vssgp'.
+
+### EXAMPLE 3
+
+#### PowerShell
+
+```powershell
+$params = @{
+ SubjectTypes = 'vssgp'
+ ScopeDescriptor = $prjDscr
+ Name = @(
+ 'Project Administrators',
+ 'Contributors'
+ )
+}
+Get-AdoUser @params
+```
+
+Retrieves the 'Project Administrators' and 'Contributors' users in the specified scope with subject types 'vssgp'.
+
+### EXAMPLE 4
+
+#### PowerShell
+
+```powershell
+@(
+ 'vssgp.00000000-0000-0000-0000-000000000000',
+ 'vssgp.00000000-0000-0000-0000-000000000001',
+ 'vssgp.00000000-0000-0000-0000-000000000002'
+) | Get-AdoUser
+```
+
+Retrieves the users with the specified descriptors.
+
+## PARAMETERS
+
+### -CollectionUri
+
+Optional.
+The collection URI of the Azure DevOps collection/organization, e.g., .
+
+```yaml
+Type: System.String
+DefaultValue: $env:DefaultAdoCollectionUri
+SupportsWildcards: false
+Aliases: []
+ParameterSets:
+- Name: (All)
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: false
+ ValueFromPipelineByPropertyName: true
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues: []
+HelpMessage: ''
+```
+
+### -ScopeDescriptor
+
+Optional.
+Specify a non-default scope (collection, project) to search for users.
+
+```yaml
+Type: System.String
+DefaultValue: ''
+SupportsWildcards: false
+Aliases: []
+ParameterSets:
+- Name: (All)
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: false
+ ValueFromPipelineByPropertyName: true
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues: []
+HelpMessage: ''
+```
+
+### -SubjectTypes
+
+Optional.
+A comma separated list of user subject subtypes to reduce the retrieved results, e.g. Microsoft.IdentityModel.Claims.ClaimsIdentity
+
+```yaml
+Type: System.String[]
+DefaultValue: ('vssgp', 'aadgp')
+SupportsWildcards: false
+Aliases: []
+ParameterSets:
+- Name: (All)
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: false
+ ValueFromPipelineByPropertyName: true
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues:
+- vssgp
+- aadgp
+HelpMessage: ''
+```
+
+### -Name
+
+Optional.
+A user's display name to filter the retrieved results.
+Supports wildcards for pattern matching.
+
+```yaml
+Type: System.String[]
+DefaultValue: ''
+SupportsWildcards: false
+Aliases:
+- DisplayName
+- userName
+ParameterSets:
+- Name: Listusers
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: false
+ ValueFromPipelineByPropertyName: true
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues: []
+HelpMessage: ''
+```
+
+### -UserDescriptor
+
+Optional.
+The descriptor of a specific user to retrieve.
+When provided, retrieves a single user by its descriptor.
+
+```yaml
+Type: System.String
+DefaultValue: ''
+SupportsWildcards: false
+Aliases: []
+ParameterSets:
+- Name: ByDescriptor
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: true
+ ValueFromPipelineByPropertyName: true
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues: []
+HelpMessage: ''
+```
+
+### -Version
+
+Optional.
+The API version to use for the request.
+Default is '7.2-preview.1'.
+The -preview flag must be supplied in the api-version for this request to work.
+
+```yaml
+Type: System.String
+DefaultValue: 7.2-preview.1
+SupportsWildcards: false
+Aliases:
+- ApiVersion
+ParameterSets:
+- Name: (All)
+ Position: Named
+ IsRequired: false
+ ValueFromPipeline: false
+ ValueFromPipelineByPropertyName: false
+ ValueFromRemainingArguments: false
+DontShow: false
+AcceptedValues:
+- 7.1-preview.1
+- 7.2-preview.1
+HelpMessage: The -preview flag must be supplied in the api-version for this request to work.
+```
+
+### CommonParameters
+
+This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,
+-InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable,
+-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see
+[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216).
+
+## INPUTS
+
+- N/A
+
+## OUTPUTS
+
+### PSCustomObject
+
+Returns one or more user objects with the following properties:
+- displayName: The display name of the user
+- originId: The origin ID of the user
+- principalName: The principal name of the user
+- origin: The origin of the user (e.g., 'aad', 'vsts')
+- subjectKind: The subject kind (e.g., 'user')
+- description: The description of the user
+- mailAddress: The mail address of the user
+- descriptor: The descriptor of the user
+- collectionUri: The collection URI used for the query
+- continuationToken: (Optional) Token for retrieving the next page of results
+
+## NOTES
+
+- Retrieves users in an Azure DevOps organization
+- Requires authentication to Azure DevOps. Use `Set-AdoDefault` to configure default organization and project values.
+- The cmdlet automatically retrieves authentication through `Invoke-AdoRestMethod` which calls `New-AdoAuthHeader`.
+
+## RELATED LINKS
+
+-
+-
diff --git a/docs/Get-AdoUserEntitlement.md b/docs/Get-AdoUserEntitlement.md
index abdd30f..76c78bc 100644
--- a/docs/Get-AdoUserEntitlement.md
+++ b/docs/Get-AdoUserEntitlement.md
@@ -253,7 +253,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### PSCustomObject
-The dictionary contains user entitlements:
+ Returns one or more user entitlement objects with the following properties:
- `accessLevel`: User's access level denoted by a license.
- `extensions`: User's extensions.
- `groupAssigments`: [Readonly] GroupEntitlements that this user belongs to.
diff --git a/src/Azure.DevOps.PSModule/Azure.DevOps.PSModule.psd1 b/src/Azure.DevOps.PSModule/Azure.DevOps.PSModule.psd1
index 97f7e36..0572ec0 100644
--- a/src/Azure.DevOps.PSModule/Azure.DevOps.PSModule.psd1
+++ b/src/Azure.DevOps.PSModule/Azure.DevOps.PSModule.psd1
@@ -94,6 +94,7 @@
'Get-AdoTeamIteration'
'Get-AdoTeamIterationList'
'Get-AdoTeamSettings'
+ 'Get-AdoUser'
'Get-AdoUserEntitlement'
'New-AdoCheckApproval'
'New-AdoCheckBranchControl'
diff --git a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1 b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
new file mode 100644
index 0000000..ebc3887
--- /dev/null
+++ b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
@@ -0,0 +1,211 @@
+function Get-AdoUser {
+ <#
+ .SYNOPSIS
+ Get a single or multiple users in an Azure DevOps organization.
+
+ .DESCRIPTION
+ This function retrieves a single or multiple users in an Azure DevOps organization through REST API.
+
+ .PARAMETER CollectionUri
+ Optional. The collection URI of the Azure DevOps collection/organization, e.g., https://vssps.dev.azure.com/my-org.
+
+ .PARAMETER ScopeDescriptor
+ Optional. Specify a non-default scope (collection, project) to search for users.
+
+ .PARAMETER SubjectTypes
+ Optional. A comma separated list of user subject subtypes to reduce the retrieved results, e.g. 'msa', 'aad', 'svc' (service identity), 'imp' (imported identity), etc.
+
+ .PARAMETER Name
+ Optional. A user's display name to filter the retrieved results.
+
+ .PARAMETER UserDescriptor
+ Optional. The descriptor of the desired user.
+
+ .PARAMETER Version
+ The API version to use. Default is '7.2-preview.1'.
+ The -preview flag must be supplied in the api-version for this request to work.
+
+ .OUTPUTS
+ PSCustomObject
+
+ Returns one or more user objects with the following properties:
+ - `subjectKind`: This field identifies the type of the graph subject (ex: Group, Scope, User).
+ - `directoryAlias`: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
+ - `domain`: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
+ - `principalName`: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
+ - `mailAddress`: The email address of record for a given graph member. This may be different than the principal name.
+ - `origin`: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
+ - `originId`: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
+ - `displayName`: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
+ - `descriptor`: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
+ - `metaType`: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
+ - `isDeletedInOrigin`: When true, the group has been deleted in the identity provider
+ - `collectionUri`: The collection URI.
+
+ .LINK
+ - https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/get
+ - https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/list
+
+ .EXAMPLE
+ Get-AdoUser
+
+ Retrieves all users in the Azure DevOps organization.
+
+ .EXAMPLE
+ $project = Get-AdoProject -Name 'my-project-1'
+ $projectDescriptor = (Get-AdoDescriptor -StorageKey $project.Id)
+
+ $params = @{
+ CollectionUri = 'https://dev.azure.com/my-org'
+ ScopeDescriptor = $projectDescriptor
+ SubjectTypes = 'aad'
+ }
+ Get-AdoUser @params
+
+ Retrieves all users in the specified project with subject types 'aad'.
+
+ .EXAMPLE
+ @(
+ 'aad.00000000-0000-0000-0000-000000000000',
+ 'aad.00000000-0000-0000-0000-000000000001',
+ 'aad.00000000-0000-0000-0000-000000000002'
+ ) | Get-AdoUser
+
+ Retrieves the users with the specified descriptors.
+
+ .NOTES
+ Retrieves users in an Azure DevOps organization.
+ #>
+ [CmdletBinding(DefaultParameterSetName = 'ListUsers')]
+ [OutputType([PSCustomObject])]
+ param (
+ [Parameter(ValueFromPipelineByPropertyName)]
+ [string]$CollectionUri = $env:DefaultAdoCollectionUri,
+
+ [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ListUsers')]
+ [string]$ScopeDescriptor,
+
+ [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ListUsers')]
+ [ValidateSet('msa', 'aad', 'svc', 'imp')]
+ [string[]]$SubjectTypes = @('msa', 'aad', 'svc', 'imp'),
+
+ [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ListUsers')]
+ [Alias('DisplayName', 'UserName')]
+ [string[]]$Name,
+
+ [Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, ParameterSetName = 'ByDescriptor')]
+ [string]$UserDescriptor,
+
+ [Parameter(HelpMessage = 'The -preview flag must be supplied in the api-version for this request to work.')]
+ [Alias('ApiVersion')]
+ [ValidateSet('7.1-preview.1', '7.2-preview.1')]
+ [string]$Version = '7.2-preview.1'
+ )
+
+ begin {
+ Write-Verbose ("Command: $($MyInvocation.MyCommand.Name)")
+ Write-Debug ("CollectionUri: $CollectionUri")
+ Write-Debug ("ScopeDescriptor: $ScopeDescriptor")
+ Write-Debug ("SubjectTypes: $($SubjectTypes -join ',')")
+ Write-Debug ("Name: $($Name -join ',')")
+ Write-Debug ("UserDescriptor: $UserDescriptor")
+ Write-Debug ("Version: $Version")
+
+ Confirm-Default -Defaults ([ordered]@{
+ 'CollectionUri' = $CollectionUri
+ })
+
+ if ($CollectionUri -notmatch 'vssps\.') {
+ $CollectionUri = $CollectionUri -replace 'https://', 'https://vssps.'
+ }
+ }
+
+ process {
+ try {
+ $queryParameters = [List[string]]::new()
+
+ if ($UserDescriptor) {
+ $uri = "$CollectionUri/_apis/graph/users/$UserDescriptor"
+ } else {
+ $uri = "$CollectionUri/_apis/graph/users"
+
+ if ($ScopeDescriptor) {
+ $queryParameters.Add("scopeDescriptor=$($ScopeDescriptor)")
+ }
+
+ if ($SubjectTypes) {
+ $queryParameters.Add("subjectTypes=$([string]::Join(',', $SubjectTypes))")
+ }
+ }
+
+ $params = @{
+ Uri = $uri
+ Version = $Version
+ QueryParameters = if ($queryParameters.Count -gt 0) { $queryParameters -join '&' } else { $null }
+ Method = 'GET'
+ }
+
+ try {
+ $continuationToken = $null
+
+ do {
+ $pagedParams = [List[string]]::new()
+
+ if ($queryParameters.Count) {
+ $pagedParams.AddRange($queryParameters)
+ }
+ if ($continuationToken) {
+ $pagedParams.Add("continuationToken=$([uri]::EscapeDataString($continuationToken))")
+ }
+
+ $params.QueryParameters = if ($pagedParams.Count) { $pagedParams -join '&' } else { $null }
+
+ $results = Invoke-AdoRestMethod @params
+ $users = if ($UserDescriptor) { @($results) } else { $results.value }
+
+ if ($Name) {
+ $users = foreach ($n_ in $Name) {
+ $users | Where-Object { -not $n_ -or $_.displayName -like $n_ }
+ }
+ }
+
+ foreach ($u_ in $users) {
+ $obj = [ordered]@{
+ subjectKind = $u_.subjectKind
+ directoryAlias = $u_.directoryAlias
+ domain = $u_.domain
+ principalName = $u_.principalName
+ mailAddress = $u_.mailAddress
+ origin = $u_.origin
+ originId = $u_.originId
+ displayName = $u_.displayName
+ descriptor = $u_.descriptor
+ isDeletedInOrigin = $u_.isDeletedInOrigin
+ metaType = $u_.metaType
+ collectionUri = $CollectionUri
+ }
+ [PSCustomObject]$obj
+ }
+
+ $continuationToken = ($results.continuationToken | Select-Object -First 1)
+
+ } while ($continuationToken)
+ } catch {
+ if ($_.ErrorDetails.Message -match 'InvalidSubjectTypeException') {
+ Write-Warning "Subject with scope descriptor $ScopeDescriptor does not exist, skipping."
+ } elseif ($_.ErrorDetails.Message -match 'GraphSubjectNotFoundException') {
+ Write-Warning "Subject with user descriptor $UserDescriptor does not exist, skipping."
+ } else {
+ throw $_
+ }
+ }
+
+ } catch {
+ throw $_
+ }
+ }
+
+ end {
+ Write-Verbose ("Exit: $($MyInvocation.MyCommand.Name)")
+ }
+}
diff --git a/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1 b/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
index 607aef8..cf2eba0 100644
--- a/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
+++ b/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
@@ -29,9 +29,9 @@
Optional. Version of the API to use. Default is '7.1'.
.OUTPUTS
- System.Collections.Specialized.OrderedDictionary
+ PSCustomObject
- The dictionary contains user entitlements:
+ Returns one or more user entitlement objects with the following properties:
- `accessLevel`: User's access level denoted by a license.
- `extensions`: User's extensions.
- `groupAssigments`: [Readonly] GroupEntitlements that this user belongs to.
diff --git a/src/Azure.DevOps.PSModule/Tests/Graph/Users/Get-AdoUser.Tests.ps1 b/src/Azure.DevOps.PSModule/Tests/Graph/Users/Get-AdoUser.Tests.ps1
new file mode 100644
index 0000000..1b5a24d
--- /dev/null
+++ b/src/Azure.DevOps.PSModule/Tests/Graph/Users/Get-AdoUser.Tests.ps1
@@ -0,0 +1,351 @@
+BeforeAll {
+ # Import the module
+ $modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\..\..'
+ $moduleName = Join-Path -Path $modulePath -ChildPath 'Azure.DevOps.PSModule\Azure.DevOps.PSModule.psd1'
+
+ # Remove module if already loaded
+ Get-Module Azure.DevOps.PSModule | Remove-Module -Force
+
+ # Import the module
+ Import-Module $moduleName -Force -Verbose:$false
+}
+
+Describe 'Get-AdoUser' {
+ BeforeAll {
+ # Sample response data for mocking
+ $mockCollectionUri = 'https://vssps.dev.azure.com/my-org'
+ $mockUserDescriptor = 'aad.00000000-0000-0000-0000-000000000001'
+ $mockScopeDescriptor = 'scp.00000000-0000-0000-0000-000000000002'
+
+ $mockUser1 = [PSCustomObject]@{
+ subjectKind = 'user'
+ directoryAlias = 'testuser1'
+ domain = '00000000-0000-0000-0000-000000000001'
+ principalName = 'testuser1@domain.com'
+ mailAddress = 'test.user1@domain.com'
+ origin = 'aad'
+ originId = '00000000-0000-0000-0000-000000000001'
+ displayName = 'User1, Test'
+ descriptor = 'aad.00000000-0000-0000-0000-000000000001'
+ isDeletedInOrigin = $null
+ metaType = 'member'
+ }
+
+ $mockUser2 = [PSCustomObject]@{
+ subjectKind = 'user'
+ directoryAlias = 'testuser2'
+ domain = '00000000-0000-0000-0000-000000000002'
+ principalName = 'testuser2@domain.com'
+ mailAddress = 'test.user2@domain.com'
+ origin = 'aad'
+ originId = '00000000-0000-0000-0000-000000000002'
+ displayName = 'User2, Test'
+ descriptor = 'aad.00000000-0000-0000-0000-000000000002'
+ isDeletedInOrigin = $null
+ metaType = 'guest'
+ }
+
+ $mockListResponse = [PSCustomObject]@{
+ value = @($mockUser1, $mockUser2)
+ }
+ }
+
+ Context 'Core Functionality Tests' {
+ BeforeEach {
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockListResponse }
+ Mock -ModuleName Azure.DevOps.PSModule Confirm-Default { }
+ Mock -ModuleName Azure.DevOps.PSModule Start-Sleep { }
+ }
+
+ It 'Should retrieve all users in organization' {
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ $result | Should -HaveCount 2
+ $result[0].displayName | Should -Be 'User1, Test'
+ $result[1].displayName | Should -Be 'User2, Test'
+ }
+
+ It 'Should return PSCustomObject with expected properties' {
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ $result[0].PSObject.Properties.Name | Should -Contain 'subjectKind'
+ $result[0].PSObject.Properties.Name | Should -Contain 'directoryAlias'
+ $result[0].PSObject.Properties.Name | Should -Contain 'domain'
+ $result[0].PSObject.Properties.Name | Should -Contain 'principalName'
+ $result[0].PSObject.Properties.Name | Should -Contain 'mailAddress'
+ $result[0].PSObject.Properties.Name | Should -Contain 'origin'
+ $result[0].PSObject.Properties.Name | Should -Contain 'originId'
+ $result[0].PSObject.Properties.Name | Should -Contain 'displayName'
+ $result[0].PSObject.Properties.Name | Should -Contain 'isDeletedInOrigin'
+ $result[0].PSObject.Properties.Name | Should -Contain 'metaType'
+ $result[0].PSObject.Properties.Name | Should -Contain 'collectionUri'
+ }
+
+ It 'Should construct API URI correctly for listing users' {
+ # Act
+ Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Uri -eq "$mockCollectionUri/_apis/graph/users"
+ }
+ }
+
+ It 'Should use GET method for API call' {
+ # Act
+ Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Method -eq 'GET'
+ }
+ }
+
+ It 'Should use default API version 7.2-preview.1' {
+ # Act
+ Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Version -eq '7.2-preview.1'
+ }
+ }
+
+ It 'Should filter users by Name parameter' {
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -Name 'User1, Test'
+
+ # Assert
+ $result | Should -HaveCount 1
+ $result.displayName | Should -Be 'User1, Test'
+ }
+
+ It 'Should support wildcard filtering by name' {
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -Name '*User1*'
+
+ # Assert
+ $result | Should -HaveCount 1
+ $result.displayName | Should -Be 'User1, Test'
+ }
+
+ It 'Should automatically iterate continuation tokens when listing users' {
+ # Arrange
+ $firstPage = [PSCustomObject]@{
+ value = @($mockUser1)
+ continuationToken = 'token123'
+ }
+ $secondPage = [PSCustomObject]@{
+ value = @($mockUser2)
+ continuationToken = $null
+ }
+ $script:userCallCount = 0
+
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod {
+ $script:userCallCount++
+ if ($script:userCallCount -eq 1) {
+ return $firstPage
+ }
+ return $secondPage
+ }
+
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -SubjectTypes @('aad')
+
+ # Assert
+ $result | Should -HaveCount 2
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 2
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -ParameterFilter {
+ $QueryParameters -match 'continuationToken=token123'
+ }
+ }
+ }
+
+ Context 'Parameter Set Tests' {
+ BeforeEach {
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockUser1 }
+ Mock -ModuleName Azure.DevOps.PSModule Confirm-Default { }
+ Mock -ModuleName Azure.DevOps.PSModule Start-Sleep { }
+ }
+
+ It 'Should retrieve group by descriptor using ByDescriptor parameter set' {
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -UserDescriptor $mockUserDescriptor
+
+ # Assert
+ $result | Should -Not -BeNullOrEmpty
+ $result.descriptor | Should -Be $mockUserDescriptor
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Uri -eq "$mockCollectionUri/_apis/graph/users/$mockUserDescriptor"
+ }
+ }
+
+ It 'Should include scopeDescriptor query parameter when specified' {
+ # Arrange
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockListResponse }
+
+ # Act
+ Get-AdoUser -CollectionUri $mockCollectionUri -ScopeDescriptor $mockScopeDescriptor
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $QueryParameters -match "scopeDescriptor=$mockScopeDescriptor"
+ }
+ }
+
+ It 'Should include subjectTypes query parameter' {
+ # Arrange
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockListResponse }
+
+ # Act
+ Get-AdoUser -CollectionUri $mockCollectionUri -SubjectTypes @('aad', 'svc')
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $QueryParameters -match 'subjectTypes=aad,svc'
+ }
+ }
+
+ }
+
+ Context 'Pipeline Support Tests' {
+ BeforeEach {
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockUser1 }
+ Mock -ModuleName Azure.DevOps.PSModule Confirm-Default { }
+ Mock -ModuleName Azure.DevOps.PSModule Start-Sleep { }
+ }
+
+ It 'Should accept UserDescriptor from pipeline' {
+ # Arrange
+ $descriptors = @(
+ 'aad.00000000-0000-0000-0000-000000000001',
+ 'aad.00000000-0000-0000-0000-000000000002'
+ )
+
+ # Act
+ $result = $descriptors | Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ $result | Should -HaveCount 2
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 2
+ }
+
+ It 'Should accept objects with UserDescriptor property from pipeline' {
+ # Arrange
+ $objects = @(
+ [PSCustomObject]@{ UserDescriptor = 'aad.00000000-0000-0000-0000-000000000001' }
+ [PSCustomObject]@{ UserDescriptor = 'aad.00000000-0000-0000-0000-000000000002' }
+ )
+
+ # Act
+ $result = $objects | Get-AdoUser -CollectionUri $mockCollectionUri
+
+ # Assert
+ $result | Should -HaveCount 2
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 2
+ }
+ }
+
+ Context 'Error Handling Tests' {
+ BeforeEach {
+ Mock -ModuleName Azure.DevOps.PSModule Confirm-Default { }
+ Mock -ModuleName Azure.DevOps.PSModule Start-Sleep { }
+ }
+
+ It 'Should handle InvalidSubjectTypeException gracefully with warning' {
+ # Arrange
+ $invalidSubjectError = [System.Management.Automation.ErrorRecord]::new(
+ [System.Exception]::new('Invalid subject type'),
+ 'InvalidSubjectTypeException',
+ [System.Management.Automation.ErrorCategory]::InvalidArgument,
+ $null
+ )
+ $invalidSubjectError.ErrorDetails = [System.Management.Automation.ErrorDetails]::new('{"message":"InvalidSubjectTypeException: Subject does not exist"}')
+
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { throw $invalidSubjectError }
+ Mock -ModuleName Azure.DevOps.PSModule Write-Warning { }
+
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -ScopeDescriptor 'invalid-scope' -WarningAction SilentlyContinue
+
+ # Assert
+ $result | Should -BeNullOrEmpty
+ Should -Invoke Write-Warning -ModuleName Azure.DevOps.PSModule -Times 1
+ }
+
+ It 'Should handle GraphSubjectNotFoundException gracefully with warning' {
+ # Arrange
+ $notFoundError = [System.Management.Automation.ErrorRecord]::new(
+ [System.Exception]::new('Subject not found'),
+ 'GraphSubjectNotFoundException',
+ [System.Management.Automation.ErrorCategory]::ObjectNotFound,
+ $null
+ )
+ $notFoundError.ErrorDetails = [System.Management.Automation.ErrorDetails]::new('{"message":"GraphSubjectNotFoundException: Group descriptor not found"}')
+
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { throw $notFoundError }
+ Mock -ModuleName Azure.DevOps.PSModule Write-Warning { }
+
+ # Act
+ $result = Get-AdoUser -CollectionUri $mockCollectionUri -UserDescriptor 'invalid-descriptor' -WarningAction SilentlyContinue
+
+ # Assert
+ $result | Should -BeNullOrEmpty
+ Should -Invoke Write-Warning -ModuleName Azure.DevOps.PSModule -Times 1
+ }
+
+ It 'Should propagate unexpected errors' {
+ # Arrange
+ $genericError = [System.Management.Automation.ErrorRecord]::new(
+ [System.Exception]::new('Server error'),
+ 'ServerError',
+ [System.Management.Automation.ErrorCategory]::InvalidOperation,
+ $null
+ )
+ $genericError.ErrorDetails = [System.Management.Automation.ErrorDetails]::new('{"message":"Internal server error"}')
+
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { throw $genericError }
+
+ # Act & Assert
+ { Get-AdoUser -CollectionUri $mockCollectionUri } | Should -Throw
+ }
+ }
+
+ Context 'CollectionUri Handling Tests' {
+ BeforeEach {
+ Mock -ModuleName Azure.DevOps.PSModule Invoke-AdoRestMethod { return $mockListResponse }
+ Mock -ModuleName Azure.DevOps.PSModule Confirm-Default { }
+ Mock -ModuleName Azure.DevOps.PSModule Start-Sleep { }
+ }
+
+ It 'Should use environment default CollectionUri when not specified' {
+ # Arrange
+ $env:DefaultAdoCollectionUri = 'https://dev.azure.com/default-org'
+
+ # Act
+ Get-AdoUser
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Uri -match 'https://vssps.dev.azure.com/default-org'
+ }
+ }
+
+ It 'Should work with vssps.dev.azure.com CollectionUri' {
+ # Arrange
+ $vsspsUri = 'https://vssps.dev.azure.com/test-org'
+
+ # Act
+ Get-AdoUser -CollectionUri $vsspsUri
+
+ # Assert
+ Should -Invoke Invoke-AdoRestMethod -ModuleName Azure.DevOps.PSModule -Times 1 -ParameterFilter {
+ $Uri -eq "$vsspsUri/_apis/graph/users"
+ }
+ }
+ }
+}
From b02460674a794e4b596e782d3a48d9f8dc517dc8 Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Sat, 14 Feb 2026 16:45:44 +0100
Subject: [PATCH 2/7] new(Get-AdoUser): Add user support (#124)
---
CHANGELOG.md | 2 +-
docs/Get-AdoUser.md | 117 ++++++++----------
.../Public/Graph/Users/Get-AdoUser.ps1 | 4 +-
3 files changed, 55 insertions(+), 68 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3056e92..1443dc5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,7 +23,7 @@ All notable changes to this project will be documented in this file.
## [UNRELEASED]
### What's Changed
-- new(Get-AdoUser): Add user support (#)
+- new(Get-AdoUser): Add user support (#124)
### Breaking Changes
- _None_
diff --git a/docs/Get-AdoUser.md b/docs/Get-AdoUser.md
index 76a8d33..84d193a 100644
--- a/docs/Get-AdoUser.md
+++ b/docs/Get-AdoUser.md
@@ -2,9 +2,9 @@
document type: cmdlet
external help file: Azure.DevOps.PSModule-Help.xml
HelpUri: https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/list
-Locale: en-NL
+Locale: nl-NL
Module Name: Azure.DevOps.PSModule
-ms.date: 01/02/2026
+ms.date: 02-14-2026
PlatyPS schema version: 2024-05-01
title: Get-AdoUser
-->
@@ -20,12 +20,18 @@ Get a single or multiple users in an Azure DevOps organization.
## SYNTAX
-### __AllParameterSets
+### ListUsers (Default)
-```text
-Get-AdoUser [[-CollectionUri] ] [[-ScopeDescriptor] ] [[-SubjectTypes] ]
- [[-Name] ] [[-UserDescriptor] ] [[-Version] ]
- [-WhatIf] [-Confirm] []
+```powershell
+Get-AdoUser [-CollectionUri ] [-ScopeDescriptor ] [-SubjectTypes ]
+ [-Name ] [-Version ] []
+```
+
+### ByDescriptor
+
+```powershell
+Get-AdoUser [-CollectionUri ] [-UserDescriptor ] [-Version ]
+ []
```
## ALIASES
@@ -58,42 +64,24 @@ $project = Get-AdoProject -Name 'my-project-1'
$projectDescriptor = (Get-AdoDescriptor -StorageKey $project.Id)
$params = @{
- CollectionUri = 'https://dev.azure.com/my-org'
+ CollectionUri = 'https://dev.azure.com/my-org'
ScopeDescriptor = $projectDescriptor
- SubjectTypes = 'vssgp'
+ SubjectTypes = 'aad'
}
Get-AdoUser @params
```
-Retrieves all users in the specified project with subject types 'vssgp'.
+Retrieves all users in the specified project with subject types 'aad'.
### EXAMPLE 3
#### PowerShell
-```powershell
-$params = @{
- SubjectTypes = 'vssgp'
- ScopeDescriptor = $prjDscr
- Name = @(
- 'Project Administrators',
- 'Contributors'
- )
-}
-Get-AdoUser @params
-```
-
-Retrieves the 'Project Administrators' and 'Contributors' users in the specified scope with subject types 'vssgp'.
-
-### EXAMPLE 4
-
-#### PowerShell
-
```powershell
@(
- 'vssgp.00000000-0000-0000-0000-000000000000',
- 'vssgp.00000000-0000-0000-0000-000000000001',
- 'vssgp.00000000-0000-0000-0000-000000000002'
+ 'aad.00000000-0000-0000-0000-000000000000',
+ 'aad.00000000-0000-0000-0000-000000000001',
+ 'aad.00000000-0000-0000-0000-000000000002'
) | Get-AdoUser
```
@@ -123,18 +111,20 @@ AcceptedValues: []
HelpMessage: ''
```
-### -ScopeDescriptor
+### -Name
Optional.
-Specify a non-default scope (collection, project) to search for users.
+A user's display name to filter the retrieved results.
```yaml
-Type: System.String
+Type: System.String[]
DefaultValue: ''
SupportsWildcards: false
-Aliases: []
+Aliases:
+- DisplayName
+- UserName
ParameterSets:
-- Name: (All)
+- Name: ListUsers
Position: Named
IsRequired: false
ValueFromPipeline: false
@@ -145,45 +135,41 @@ AcceptedValues: []
HelpMessage: ''
```
-### -SubjectTypes
+### -ScopeDescriptor
Optional.
-A comma separated list of user subject subtypes to reduce the retrieved results, e.g. Microsoft.IdentityModel.Claims.ClaimsIdentity
+Specify a non-default scope (collection, project) to search for users.
```yaml
-Type: System.String[]
-DefaultValue: ('vssgp', 'aadgp')
+Type: System.String
+DefaultValue: ''
SupportsWildcards: false
Aliases: []
ParameterSets:
-- Name: (All)
+- Name: ListUsers
Position: Named
IsRequired: false
ValueFromPipeline: false
ValueFromPipelineByPropertyName: true
ValueFromRemainingArguments: false
DontShow: false
-AcceptedValues:
-- vssgp
-- aadgp
+AcceptedValues: []
HelpMessage: ''
```
-### -Name
+### -SubjectTypes
Optional.
-A user's display name to filter the retrieved results.
-Supports wildcards for pattern matching.
+A comma separated list of user subject subtypes to reduce the retrieved results, e.g.
+'msa', 'aad', 'svc' (service identity), 'imp' (imported identity), etc.
```yaml
Type: System.String[]
-DefaultValue: ''
+DefaultValue: "@('msa', 'aad', 'svc', 'imp')"
SupportsWildcards: false
-Aliases:
-- DisplayName
-- userName
+Aliases: []
ParameterSets:
-- Name: Listusers
+- Name: ListUsers
Position: Named
IsRequired: false
ValueFromPipeline: false
@@ -260,22 +246,23 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### PSCustomObject
Returns one or more user objects with the following properties:
-- displayName: The display name of the user
-- originId: The origin ID of the user
-- principalName: The principal name of the user
-- origin: The origin of the user (e.g., 'aad', 'vsts')
-- subjectKind: The subject kind (e.g., 'user')
-- description: The description of the user
-- mailAddress: The mail address of the user
-- descriptor: The descriptor of the user
-- collectionUri: The collection URI used for the query
-- continuationToken: (Optional) Token for retrieving the next page of results
+- `subjectKind`: This field identifies the type of the graph subject (ex: Group, Scope, User).
+- `directoryAlias`: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
+- `domain`: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
+- `principalName`: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
+- `mailAddress`: The email address of record for a given graph member. This may be different than the principal name.
+- `origin`: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
+- `originId`: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
+- `displayName`: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
+- `descriptor`: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
+- `metaType`: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
+- `isDeletedInOrigin`: When true, the group has been deleted in the identity provider
+- `collectionUri`: The collection URI.
## NOTES
-- Retrieves users in an Azure DevOps organization
-- Requires authentication to Azure DevOps. Use `Set-AdoDefault` to configure default organization and project values.
-- The cmdlet automatically retrieves authentication through `Invoke-AdoRestMethod` which calls `New-AdoAuthHeader`.
+Retrieves users in an Azure DevOps organization.
+
## RELATED LINKS
diff --git a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1 b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
index ebc3887..04797f4 100644
--- a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
+++ b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
@@ -19,10 +19,10 @@
Optional. A user's display name to filter the retrieved results.
.PARAMETER UserDescriptor
- Optional. The descriptor of the desired user.
+ Optional. The descriptor of a specific user to retrieve. When provided, retrieves a single user by its descriptor.
.PARAMETER Version
- The API version to use. Default is '7.2-preview.1'.
+ The API version to use for the request. Default is '7.2-preview.1'.
The -preview flag must be supplied in the api-version for this request to work.
.OUTPUTS
From 3f7f10fa5a10a4c5b68a49da7422eb035293da2d Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Sat, 14 Feb 2026 16:50:57 +0100
Subject: [PATCH 3/7] Update changelog
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1443dc5..5006468 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,7 +23,7 @@ All notable changes to this project will be documented in this file.
## [UNRELEASED]
### What's Changed
-- new(Get-AdoUser): Add user support (#124)
+- feat(Get-AdoUser): Add user support (#124)
### Breaking Changes
- _None_
From 972899a043a61c07f500a7f8a416d4b0e01e663c Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Sat, 14 Feb 2026 17:49:24 +0100
Subject: [PATCH 4/7] Update changelog
---
CHANGELOG.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5006468..0eeead6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,9 @@ All notable changes to this project will be documented in this file.
## [UNRELEASED]
+### Summary
+- _None_
+
### What's Changed
- feat(Get-AdoUser): Add user support (#124)
@@ -40,6 +43,7 @@ Feature release adding repository initialization support, enhanced user entitlem
- feat: Add `ResourceId` parameter to all Check and Approval cmdlets
- feat: Add `New-AdoPushInitialCommit` cmdlet for creating initial commits in Azure DevOps repositories
- chore: Using namespace `System.Collections.Generic` declaration at the module root
+- chore(Build.ps1): Update module version to 0.4.0
### Breaking Changes
- _None_
@@ -87,7 +91,6 @@ Hotfix release focused on bug fixes and code quality improvements. Achieved 100%
- chore: Update CHANGELOG to reflect recent changes and fixes
- chore: Update build version to 0.2.3
-
### Breaking Changes
- With the output names update in `Add-AdoTeamIteration` and `Get-AdoTeamIteration` cmdlets the output names `team` and `project` are not available anymore, use `teamName` and `projectName` instead.
From 8873d1a4b602d0020c68fd8d92b9554e71dbe9c6 Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Sun, 15 Feb 2026 14:03:41 +0100
Subject: [PATCH 5/7] Undo change
---
docs/Get-AdoUserEntitlement.md | 2 +-
.../UserEntitlements/Get-AdoUserEntitlement.ps1 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/Get-AdoUserEntitlement.md b/docs/Get-AdoUserEntitlement.md
index 76c78bc..abdd30f 100644
--- a/docs/Get-AdoUserEntitlement.md
+++ b/docs/Get-AdoUserEntitlement.md
@@ -253,7 +253,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### PSCustomObject
- Returns one or more user entitlement objects with the following properties:
+The dictionary contains user entitlements:
- `accessLevel`: User's access level denoted by a license.
- `extensions`: User's extensions.
- `groupAssigments`: [Readonly] GroupEntitlements that this user belongs to.
diff --git a/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1 b/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
index cf2eba0..607aef8 100644
--- a/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
+++ b/src/Azure.DevOps.PSModule/Public/MemberEntitlementManagement/UserEntitlements/Get-AdoUserEntitlement.ps1
@@ -29,9 +29,9 @@
Optional. Version of the API to use. Default is '7.1'.
.OUTPUTS
- PSCustomObject
+ System.Collections.Specialized.OrderedDictionary
- Returns one or more user entitlement objects with the following properties:
+ The dictionary contains user entitlements:
- `accessLevel`: User's access level denoted by a license.
- `extensions`: User's extensions.
- `groupAssigments`: [Readonly] GroupEntitlements that this user belongs to.
From 2126a78655a8a09094ae15b6f2404d441657b2dd Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Mon, 16 Feb 2026 13:01:56 +0000
Subject: [PATCH 6/7] Remove backticks
---
docs/Get-AdoUser.md | 24 +++++++++----------
.../Public/Graph/Users/Get-AdoUser.ps1 | 24 +++++++++----------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/docs/Get-AdoUser.md b/docs/Get-AdoUser.md
index 84d193a..564f127 100644
--- a/docs/Get-AdoUser.md
+++ b/docs/Get-AdoUser.md
@@ -246,18 +246,18 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### PSCustomObject
Returns one or more user objects with the following properties:
-- `subjectKind`: This field identifies the type of the graph subject (ex: Group, Scope, User).
-- `directoryAlias`: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
-- `domain`: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
-- `principalName`: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
-- `mailAddress`: The email address of record for a given graph member. This may be different than the principal name.
-- `origin`: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
-- `originId`: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
-- `displayName`: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
-- `descriptor`: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
-- `metaType`: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
-- `isDeletedInOrigin`: When true, the group has been deleted in the identity provider
-- `collectionUri`: The collection URI.
+- subjectKind: This field identifies the type of the graph subject (ex: Group, Scope, User).
+- directoryAlias: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
+- domain: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
+- principalName: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
+- mailAddress: The email address of record for a given graph member. This may be different than the principal name.
+- origin: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
+- originId: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
+- displayName: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
+- descriptor: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
+- metaType: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
+- isDeletedInOrigin: When true, the group has been deleted in the identity provider
+- collectionUri: The collection URI.
## NOTES
diff --git a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1 b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
index 04797f4..020c26b 100644
--- a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
+++ b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
@@ -29,18 +29,18 @@
PSCustomObject
Returns one or more user objects with the following properties:
- - `subjectKind`: This field identifies the type of the graph subject (ex: Group, Scope, User).
- - `directoryAlias`: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
- - `domain`: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
- - `principalName`: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
- - `mailAddress`: The email address of record for a given graph member. This may be different than the principal name.
- - `origin`: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
- - `originId`: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
- - `displayName`: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
- - `descriptor`: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
- - `metaType`: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
- - `isDeletedInOrigin`: When true, the group has been deleted in the identity provider
- - `collectionUri`: The collection URI.
+ - subjectKind: This field identifies the type of the graph subject (ex: Group, Scope, User).
+ - directoryAlias: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
+ - domain: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
+ - principalName: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
+ - mailAddress: The email address of record for a given graph member. This may be different than the principal name.
+ - origin: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
+ - originId: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
+ - displayName: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
+ - descriptor: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
+ - metaType: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
+ - isDeletedInOrigin: When true, the group has been deleted in the identity provider
+ - collectionUri: The collection URI.
.LINK
- https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/get
From 0d606691a9c0a8b4391e8d6251bd56e655b0a098 Mon Sep 17 00:00:00 2001
From: Antoine Boot <2473792+Antiohne@users.noreply.github.com>
Date: Tue, 17 Feb 2026 13:37:52 +0000
Subject: [PATCH 7/7] Remove PSCustomObject documentation
---
docs/Get-AdoUser.md | 14 --------------
.../Public/Graph/Users/Get-AdoUser.ps1 | 14 --------------
2 files changed, 28 deletions(-)
diff --git a/docs/Get-AdoUser.md b/docs/Get-AdoUser.md
index 564f127..1ee44e7 100644
--- a/docs/Get-AdoUser.md
+++ b/docs/Get-AdoUser.md
@@ -245,20 +245,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### PSCustomObject
-Returns one or more user objects with the following properties:
-- subjectKind: This field identifies the type of the graph subject (ex: Group, Scope, User).
-- directoryAlias: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
-- domain: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
-- principalName: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
-- mailAddress: The email address of record for a given graph member. This may be different than the principal name.
-- origin: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
-- originId: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
-- displayName: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
-- descriptor: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
-- metaType: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
-- isDeletedInOrigin: When true, the group has been deleted in the identity provider
-- collectionUri: The collection URI.
-
## NOTES
Retrieves users in an Azure DevOps organization.
diff --git a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1 b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
index 020c26b..13dcdd4 100644
--- a/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
+++ b/src/Azure.DevOps.PSModule/Public/Graph/Users/Get-AdoUser.ps1
@@ -28,20 +28,6 @@
.OUTPUTS
PSCustomObject
- Returns one or more user objects with the following properties:
- - subjectKind: This field identifies the type of the graph subject (ex: Group, Scope, User).
- - directoryAlias: The short, generally unique name for the user in the backing directory. For AAD users, this corresponds to the mail nickname, which is often but not necessarily similar to the part of the user's mail address before the @ sign. For GitHub users, this corresponds to the GitHub user handle.
- - domain: This represents the name of the container of origin for a graph member. (For MSA this is "Windows Live ID", for AD the name of the domain, for AAD the tenantID of the directory, for VSTS groups the ScopeId, etc)
- - principalName: This is the PrincipalName of this graph member from the source provider. The source provider may change this field over time and it is not guaranteed to be immutable for the life of the graph member by VSTS.
- - mailAddress: The email address of record for a given graph member. This may be different than the principal name.
- - origin: The type of source provider for the origin identifier (ex:AD, AAD, MSA)
- - originId: The unique identifier from the system of origin. Typically a sid, object id or Guid. Linking and unlinking operations can cause this value to change for a user because the user is not backed by a different provider and has a different unique id in the new provider.
- - displayName: This is the non-unique display name of the graph subject. To change this field, you must alter its value in the source provider.
- - descriptor: The descriptor is the primary way to reference the graph subject while the system is running. This field will uniquely identify the same graph subject across both Accounts and Organizations.
- - metaType: The meta type of the user in the origin, such as "member", "guest", etc. See UserMetaType for the set of possible values.
- - isDeletedInOrigin: When true, the group has been deleted in the identity provider
- - collectionUri: The collection URI.
-
.LINK
- https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/get
- https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/list