Is there an existing issue for this?
Azure.DevOps.PSModule version
0.2.2
Related function
Get-AdoMembership, Add-AdoGroupMember, Remove-AdoMembership (proposed)
Use case
As a DevOps Engineer managing Azure DevOps organization identity and access management
I want a generic Add-AdoMembership cmdlet that directly uses subject and container descriptors to create membership relationships
So that I can have a consistent, descriptor-based API surface that aligns with Get-AdoMembership and Remove-AdoMembership, enabling more flexible membership management workflows without needing to know origin IDs
Notes
- Currently,
Add-AdoGroupMember exists but uses a different API endpoint (/graph/groups) and requires an OriginId parameter
- The Memberships API (
/graph/memberships/{subjectDescriptor}/{containerDescriptor}) provides a more direct approach using descriptors
- Having
Get-AdoMembership, Add-AdoMembership, and Remove-AdoMembership creates a consistent, intuitive cmdlet family
- The descriptor-based approach is more flexible as it works with any subject/container relationship
- Users already have descriptors from
Get-AdoGroup, Get-AdoDescriptor, or other cmdlets - no need to track origin IDs
- Enables symmetrical operations: if you can GET and REMOVE memberships by descriptor, you should be able to ADD them the same way
Proposed solution
Create an Add-AdoMembership cmdlet that complements the existing membership management cmdlets:
Cmdlet Signature
function Add-AdoMembership {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
param (
[Parameter(ValueFromPipelineByPropertyName)]
[ValidateScript({ Confirm-CollectionUri -Uri $_ })]
[string]$CollectionUri = ($env:DefaultAdoCollectionUri -replace 'https://', 'https://vssps.'),
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)]
[string[]]$SubjectDescriptor,
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$ContainerDescriptor,
[Parameter()]
[Alias('ApiVersion')]
[ValidateSet('7.1-preview.1', '7.2-preview.1')]
[string]$Version = '7.1-preview.1'
)
}
Key Features
- PUT HTTP Method: Calls the Azure DevOps Graph API using PUT method
- Descriptor-Based: Works directly with subject and container descriptors (no origin ID needed)
- Pipeline Support: Accept
SubjectDescriptor from pipeline for bulk operations
- Confirmation Prompts: Include
-WhatIf and -Confirm support for safe operations
- Descriptor Validation: Validate descriptor format before API calls
- Error Handling: Clear error messages for invalid descriptors or existing memberships
- Consistency: Matches parameter patterns with
Get-AdoMembership and Remove-AdoMembership
- Idempotency: Handle cases where membership already exists gracefully
API Endpoint
PUT https://vssps.dev.azure.com/{organization}/_apis/graph/memberships/{subjectDescriptor}/{containerDescriptor}?api-version=7.1-preview.1
Example Usage
# Add a single membership using descriptors
$params = @{
CollectionUri = 'https://vssps.dev.azure.com/my-org'
SubjectDescriptor = 'aadgp.00000000-0000-0000-0000-000000000000'
ContainerDescriptor = 'vssgp.00000000-0000-0000-0000-000000000001'
}
Add-AdoMembership @params
# Add multiple users to a group via pipeline
$userDescriptors = @(
'aad.MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAy',
'aad.MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAz'
)
$userDescriptors | Add-AdoMembership @params
# Retrieve group members and add them to another group
$params = @{
CollectionUri = 'https://vssps.dev.azure.com/my-org'
}
$sourceGroup = Get-AdoGroup @params -GroupName 'Developers'
$targetGroup = Get-AdoGroup @params -GroupName 'Contributors'
Get-AdoMembership @params -ContainerDescriptor $sourceGroup.descriptor |
Add-AdoMembership @params -ContainerDescriptor $targetGroup.descriptor
# Preview changes without executing
Add-AdoMembership @params -WhatIf
# Add without confirmation prompt (automation scenarios)
Add-AdoMembership @params -Confirm:$false
Comparison: Add-AdoGroupMember vs Add-AdoMembership
| Aspect |
Add-AdoGroupMember |
Add-AdoMembership |
| API Endpoint |
/graph/groups |
/graph/memberships |
| HTTP Method |
POST |
PUT |
| Primary Parameter |
OriginId (GUID) |
SubjectDescriptor (string) |
| Use Case |
Add Entra ID groups by origin ID |
Add any subject by descriptor |
| Requires |
Knowledge of origin ID |
Only descriptor (from Get cmdlets) |
| Naming Pattern |
Group-specific operation |
Generic membership operation |
| Consistency |
Different from Get/Remove |
Matches Get-AdoMembership pattern |
Implementation Checklist
Benefits
- Consistency: Creates a unified membership management API surface (Get, Add, Remove)
- Flexibility: Works with descriptors from any source, not just origin IDs
- Discoverability: Intuitive naming - users looking for membership operations find all related cmdlets
- Simplicity: Simpler workflows when descriptors are already available from other cmdlets
- Pipeline-Friendly: Enables chaining operations with other descriptor-based cmdlets
- Completeness: Provides full CRUD operations for membership management
Relationship with Add-AdoGroupMember
Add-AdoGroupMember remains valuable for specific Entra ID group scenarios where origin ID is readily available
Add-AdoMembership provides a more generic, descriptor-based alternative
- Both cmdlets can coexist, serving different use cases
- Consider
Add-AdoGroupMember as a specialized convenience wrapper
Add-AdoMembership aligns better with the Get/Remove cmdlet patterns
Testing Scenarios
- Successfully add a valid membership relationship
- Handle existing membership gracefully (idempotency)
- Validate proper error handling for invalid descriptors
- Confirm pipeline input processing for bulk operations
- Verify
-WhatIf and -Confirm behavior
- Test with AAD, AADGP, and VSSGP descriptor types
- Validate API version parameter functionality
- Test subject-to-subject and subject-to-container relationships
- Verify error handling for insufficient permissions
- Test edge cases (self-referencing, circular dependencies)
Migration Path
For users currently using Add-AdoGroupMember, provide guidance:
# Old pattern (using Add-AdoGroupMember with OriginId)
Add-AdoGroupMember -GroupDescriptor $groupDesc -OriginId $originId
# New pattern (using Add-AdoMembership with SubjectDescriptor)
# First get the descriptor from origin ID if needed
$subject = Get-AdoGroup -OriginId $originId
Add-AdoMembership -SubjectDescriptor $subject.descriptor -ContainerDescriptor $groupDesc
# Or even better - pipe directly
Get-AdoGroup -OriginId $originId |
Add-AdoMembership -ContainerDescriptor $groupDesc
Is there an existing issue for this?
Azure.DevOps.PSModule version
0.2.2
Related function
Get-AdoMembership, Add-AdoGroupMember, Remove-AdoMembership (proposed)
Use case
As a DevOps Engineer managing Azure DevOps organization identity and access management
I want a generic
Add-AdoMembershipcmdlet that directly uses subject and container descriptors to create membership relationshipsSo that I can have a consistent, descriptor-based API surface that aligns with
Get-AdoMembershipandRemove-AdoMembership, enabling more flexible membership management workflows without needing to know origin IDsNotes
Add-AdoGroupMemberexists but uses a different API endpoint (/graph/groups) and requires an OriginId parameter/graph/memberships/{subjectDescriptor}/{containerDescriptor}) provides a more direct approach using descriptorsGet-AdoMembership,Add-AdoMembership, andRemove-AdoMembershipcreates a consistent, intuitive cmdlet familyGet-AdoGroup,Get-AdoDescriptor, or other cmdlets - no need to track origin IDsProposed solution
Create an
Add-AdoMembershipcmdlet that complements the existing membership management cmdlets:Cmdlet Signature
Key Features
SubjectDescriptorfrom pipeline for bulk operations-WhatIfand-Confirmsupport for safe operationsGet-AdoMembershipandRemove-AdoMembershipAPI Endpoint
Example Usage
Comparison: Add-AdoGroupMember vs Add-AdoMembership
/graph/groups/graph/membershipsImplementation Checklist
Add-AdoMembership.ps1insrc/Azure.DevOps.PSModule/Public/Graph/Memberships/src/Azure.DevOps.PSModule/Tests/Graph/Memberships/Add-AdoMembership.Tests.ps1docs/Add-AdoMembership.mdAdd-AdoGroupMembercmdletBenefits
Relationship with Add-AdoGroupMember
Add-AdoGroupMemberremains valuable for specific Entra ID group scenarios where origin ID is readily availableAdd-AdoMembershipprovides a more generic, descriptor-based alternativeAdd-AdoGroupMemberas a specialized convenience wrapperAdd-AdoMembershipaligns better with the Get/Remove cmdlet patternsTesting Scenarios
-WhatIfand-ConfirmbehaviorMigration Path
For users currently using
Add-AdoGroupMember, provide guidance: