How to add bulk users ( using a csv file ) to an AzureDevops Group using Powershell

63 views Asked by At

I need to add a long list of users to a new created azure devops group.

When I run the following script I get the error :

PS /Users/myuser # Get the descriptor of the group PS /Users/myuser> $groupsUrl = "$apiUrl/graph/groups?api-version=6.0-preview.1" PS /Users/myuser> $groups = Invoke-RestMethod -Uri $groupsUrl -Method Get -Headers $headers Invoke-RestMethod: Page Not Found

my code:

# Your Azure DevOps organization and PAT
$organization = " "
$personalAccessToken = " "
$apiUrl = "https://vsaex.dev.azure.com/$organization/_apis"

# Group name to add users to
$groupName = "  "

# Path to the CSV file
$csvFilePath = Resolve-Path "/Users/ /test.csv"

# Base64-encode the Personal Access Token and add it to the headers
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$headers = @{
    Authorization = "Basic $base64AuthInfo"
}

# Function to add a user to a group
function Add-UserToAzureDevOpsGroup {
    param(
        [string]$organization,
        [string]$groupId,
        [string]$memberId,
        [string]$pat
    )

    $uri = "https://vsaex.dev.azure.com/$organization/_apis/GroupEntitlements/$groupId/members/$memberId?api-version=7.0"

    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat"))

    Invoke-RestMethod -Uri $uri -Method Put -Headers @{Authorization=("Basic $base64AuthInfo")} -ContentType "application/json"
}

# Get the descriptor of the group
$groupsUrl = "$apiUrl/graph/groups?api-version=6.0-preview.1"
$groups = Invoke-RestMethod -Uri $groupsUrl -Method Get -Headers $headers
$group = $groups.value | Where-Object { $_.principalName -eq $groupName }
$groupDescriptor = $group.descriptor

# Import the user list from the CSV
$users = Import-Csv -Path $csvFilePath

# Loop through each user and add them to the group
foreach ($user in $users) {
    $userEmail = $user.UserName
    $userDescriptorUrl = "$apiUrl/graph/users?api-version=6.0-preview.1&subjectTypes=user&mailAddress=$userEmail"
    $userDescriptorObject = Invoke-RestMethod -Uri $userDescriptorUrl -Method Get -Headers $headers
    $userDescriptor = $userDescriptorObject.value.descriptor

    if ($userDescriptor) {
        Add-UserToGroup -userDescriptor $userDescriptor -groupDescriptor $groupDescriptor
        Write-Host "Added user ($userEmail) to group ($groupName)"
    } else {
        Write-Host "Could not find user descriptor for email ($userEmail)"
    }
}

the above code explains

1

There are 1 answers

0
wade zhou - MSFT On

The error is caused by the incorrect $apiUrl, for user list rest api, the url should be started with https://vssps.dev.azure.com, not https://vsaex.dev.azure.com. In addition, there are other syntax errors in your script.

You are using Members - Add rest api to add the user to the group, it requires groupid and memberid, it's NOT groupDescriptor and userDescriptor.

enter image description here

You need to change the rest api used.

  1. Use rest api Member Entitlements - Search Member Entitlements to get the memberid.
  2. Use rest api Groups - List to get the groupid.

I edited your script, and it's working on my side.

# Your Azure DevOps organization and PAT
$organization = "orgname"
$personalAccessToken = "PAT"

# Group name to add users to
$groupName = "[orgname]\TestGroup1"

# Path to the CSV file
$csvFilePath = Resolve-Path "/Users/tester1/test.csv"

# Base64-encode the Personal Access Token and add it to the headers
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$headers = @{
    Authorization = "Basic $base64AuthInfo"
}

# Function to add a user to a group
function Add-UserToAzureDevOpsGroup {
    param(
        [string]$organization,
        [string]$groupId,
        [string]$memberId,
        [string]$pat
    )

    $uri = "https://vsaex.dev.azure.com/$organization/_apis/GroupEntitlements/$groupId/members/$memberId" + "?api-version=7.0"

    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat"))

    Invoke-RestMethod -Uri $uri -Method Put -Headers @{Authorization=("Basic $base64AuthInfo")} -ContentType "application/json"
}

# Get the groupid of the group
$groupsUrl = "https://vssps.dev.azure.com/$organization/_apis/graph/groups?api-version=6.0-preview.1"
$groups = Invoke-RestMethod -Uri $groupsUrl -Method Get -Headers $headers
$group = $groups.value | Where-Object { $_.principalName -eq $groupName }
$groupid = $group.originId
echo $groupid    # check groupid

# Import the user list from the CSV
$users = Import-Csv -Path $csvFilePath

# Loop through each user and add them to the group
foreach ($user in $users) {
    $userEmail = $user.UserName
    $memberuri = "https://vsaex.dev.azure.com/$organization/_apis/memberentitlements?api-version=7.1-preview.2"
    $MemberEntitlements = Invoke-RestMethod -Uri $uri -Method GET -Headers $headers
    $User = $MemberEntitlements.items | Where-Object { $_.member.mailAddress -eq $userEmail }
    $memberId = $User.id

    echo $memberId      # check memberid 

    if ($memberId) {
        Add-UserToAzureDevOpsGroup -organization $organization -groupId $groupid -memberId $memberId -pat $personalAccessToken
        Write-Host "Added user ($userEmail) to group ($groupName)"
    } else {
        Write-Host "Could not find user descriptor for email ($userEmail)"
    }
}

My test.csv:

enter image description here

Execution result:

enter image description here

The DevOps User added in the group: enter image description here