Add member to Azure DevOps team - powershell

I've able to get team or team member but I could not find away to add user to the team. Is there RESt_API, command line, or API that I could add user to the team using domain name "domain\user". Please advise. Great appreciate
Best Regards,

If you use Azure DevOps Service (https://dev.azure.com/xxxx), you could use Members - Add REST API.
If you use Azure DevOps Server, the REST API to add members to projects and team is not documented. As a workaround, we can track this rest api by pressing F12 in browser then select Network.
Sample:
POST http://TFS2019:8080/tfs/{Collection}/{project}/_api/_identity/AddIdentities?api-version=5.0
Request Body:
{
"newUsersJson": "[]",
"existingUsersJson": "[\"55b98726-c6f5-48d2-976b-xxxxxx\"]",
"groupsToJoinJson": "[\"7283653f-54b2-4ebf-86c3-xxxxxxx\"]",
"aadGroupsJson": "[]"
}
However as we can see we can only use the user and team/group GUID in the request json body. For the specific team/groups we can use the REST APIs Projects and teams to get their GUID.
For the user, actually it's used the TeamFoundationId, the unique TeamFoundationId is automatically generated when a user is added to Azure DevOps Server. We cannot generate the ID with external tools.
So, to use that REST API, we need to get the TeamFoundationId of the specific user which you want to add it to the projects/teams.
Currently, no REST API to list TeamFoundationId of the users in Azure DevOps Server 2019, however we can get it with Client API:
Below sample for your reference to get the TeamFoundationId of a specific user: (It will also export the user list with their TeamFoundationId to userlist.txt)
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using System.Linq;
using System.IO;
namespace Getuserlist
{
class Program
{
static void Main(string[] args)
{
TfsConfigurationServer tcs = new TfsConfigurationServer(new Uri("https://wsicads2019"));
IIdentityManagementService ims = tcs.GetService<IIdentityManagementService>();
TeamFoundationIdentity tfi = ims.ReadIdentity(IdentitySearchFactor.AccountName, "[DefaultCollection]\\Project Collection Valid Users", MembershipQuery.Expanded, ReadIdentityOptions.None);
TeamFoundationIdentity[] ids = ims.ReadIdentities(tfi.Members, MembershipQuery.None, ReadIdentityOptions.None);
using (StreamWriter file = new StreamWriter("userlist.txt"))
foreach (TeamFoundationIdentity id in ids)
{
if (id.Descriptor.IdentityType == "System.Security.Principal.WindowsIdentity" && id.UniqueName == "Domain\\User")
{ Console.WriteLine("[{0},{1}]", id.UniqueName, id.TeamFoundationId); }
file.WriteLine("[{0},{1}]", id.UniqueName, id.TeamFoundationId);
}
var count = ids.Count(x => ids.Contains(x));
Console.WriteLine(count);
Console.ReadLine();
}
}
}

Related

How do I give Permissions using Azure DevOps Server Rest APi

https://learn.microsoft.com/en-us/rest/api/azure/devops/security/?view=azure-devops-server-rest-5.0
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/access%20control%20entries?view=azure-devops-server-rest-5.0
Hi there, I'm having problems with trying to understand the way to set up permissions using the API in ADO 2019. I can see what the security namespace one API does. I can get bitwise that relates to, for examples, git repos. I can't see how to add permissions to a user or group. e.g. I can't see how to get a bitwise that has multiple permissions, do I just add them together? I can see the API that says how to add ACEs but that doesn't actually tell me how to add permissions really. I'll try to explain.
If I run the API for ACL , I get a pile of info back, one of which is token.
Okay, so surely if I get the GUID for the git repo using the git API to list them, the GUID will match up with the ID's in the token like the namespaces do. Nope.
The examples don't seem to be actual examples. I'm looking for 'If you have a git repo , here's how you would give someone permissions to it' 'here's an example of getting the existing permissions for a group and adding another'.
Instead it's just
'here's a string of guids getting put into the API' without explaining the pieces or what specifically it was doing. I can't seem to relate what's in the GUI for adding perms, to what the security API is bringing back.
Am Azure DevOps on prem so I'm more limited in tool selection. Other people I've asked say they gave up trying to use this. AzureDevops on twitter says I can connect with the team here. I'm asking how to do things with the security API and then I can go write it up and suggest how to update the docs. I'm clearly too thick to figure it out from what's there and I don't seem to be the only one. Thanks
For Azure DevOps Service, you can manage group membership using Graph API. But this api is not available for Azure DevOps Server.
In my opinion, for on-premise TFS/Azure DevOps Server, TFSSecurity command line is easier than TFS API to add permissions for a user or a group in a server-level, collection-level, or project-level group. You may consider using TFSSecurity command line:
https://learn.microsoft.com/en-us/azure/devops/server/command-line/tfssecurity-cmd?view=azure-devops-2019
You may also check the following code to get the permissions:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
namespace API
{
class Program
{
static void Main(string[] args)
{
string project = "http://xxx.xxx.xxx.xxx:8080/tfs";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
var tps = tpc.GetService<VersionControlServer>();
var ttt = tps.GetTeamProject("ProjectName");
ISecurityService securityService = tpc.GetService<ISecurityService>();
System.Collections.ObjectModel.ReadOnlyCollection<SecurityNamespace> securityNamespaces = securityService.GetSecurityNamespaces();
IGroupSecurityService gss = tpc.GetService<IGroupSecurityService>();
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "GroupName", QueryMembership.Expanded);//GourName format: [ProjectName]\\GourpName
IdentityDescriptor id = new IdentityDescriptor("Microsoft.TeamFoundation.Identity", SIDS.Sid);
List<SecurityNamespace> securityList = securityNamespaces.ToList<SecurityNamespace>();
string securityToken;
foreach (SecurityNamespace sn in securityList)
{
if (sn.Description.DisplayName == "Project")
{
securityToken = "$PROJECT:" + ttt.ArtifactUri.AbsoluteUri;
sn.SetPermissions(securityToken, id, 115, 0, true);
}
}
}
}
}

Node API to Create new Area Path?

I am creating a Azure DevOps extension that utilizes the Rest API and the Node API client.
https://github.com/microsoft/azure-devops-node-api
I am trying to create a process that creates a new team within a team project. The Core api group has methods to work with Teams, and I can successfully Create a Team. However, I see no way to create a new Area Path for this team.
I can't find an API that would seem to allow me to either create a new Area path for that Team, or even if I did, how I would set the Team's Area to be that new Area Path.. What am I missing? There HAS to be an API way to work with Area, but really don't see it in the API Documentation. I've looked through the WorkItem APIs, the Project-related APIS, and I can't find any Area-related calls.
Here is some code on how I've created a Team. that works fine.
var coreApiObject: CoreApi.CoreApi = await vsts.getCoreApi();
var newTeam:CoreInterfaces.WebApiTeam = {name: teamName,
description: 'Onboarding Backlog for ' + teamName,
id: undefined,
projectId: projectRef.id,
projectName: projectRef.name,
url: undefined};
var projectId:string = "";
if(projectRef.id)
{
projectId = projectRef.id;
}
var teamResult:CoreInterfaces.WebApiTeam = await coreApiObject.createTeam(newTeam, projectId);

How to Identify caller when grant_type is client_credentials?

I have ASP.NET Web application and I am using IdentityServer3 for user authentication. Our customers login to web application using userid/password.
Now I have one more Web API and some of our customers need to call this web api from their applications. (server to server communication). So based on this, in identityserver i did the following
1> Created a new scope name api
2> Created a new client for Web API and configured with allowed scope api and offline_access
3> Set flow to ClientCredentials
4> Set AccessTokenType to Jwt
5> For each customer i created different secret key
Now our customers can get access token at connect/token endpoint and then make call to API using the access token. The API validates the token with IdentityServer, and then returns the result. All good till here.
However, in API project i also need to identify the customer aka caller. Based on customer i need to do some logic
public class ResourcesController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal;
// need to identify caller here
return Json(new
{
message = "OK",
});
}
}
(One option i can think of is taking customer id is as part of API url. Something like http://api.domain.com/v1/customerid/resources)
Is there anyway to make a use of IdentityServer to identify customer?
I've actually had a similar need some time ago. For the simplest solution, you should be able to assign a custom claim to each of the Identity Server client that you have created for your customers.
AlwaysSendClientClaims = true,
Claims = new List<Claim>()
{
new Claim("CustomerId", "0121021")
}
These client claims will then be included in the access token and therefore available to you in your backend.
public class ResourcesController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal;
// need to identify caller here
var customerId = caller?.Claims.Where(p => p.Type.Equals("CustomerId")).First().Value;
// need to identify caller here
return Json(new
{
message = "OK",
});
}
}

How to use Azure AD Graph API to create a new AppRoleAssignment

I'm trying to figure out how to create a new appRoleAssignment using the Azure AD Graph API. (It appears that the newer Microsoft Graph does NOT support creating app role assignments just yet). I want to use the default role.
var assignment = new Dictionary<string, string>();
assignment["id"] = "00000000-0000-0000-0000-000000000000";
assignment["principalId"] = "user-guid";
assignment["resourceId"] = "service-principal-guid";
var url = "https://graph.windows.net/{tenant.onmicrosoft.com}/servicePrinciapls/{service-principal-guid}/appRoleAssignments";
I also tried posting to:
var url = "https://graph.windows.net/{tenant.onmicrosoft.com}/appRoleAssignments";
I'm POSTing the data in the hopes to create the assignment but it is giving a 404 error.
The assignment dictionary gets converted to JSON and posted.
In this answer we discussed the endpoint to GET app role assignments for a user. The same endpoint is the one you would POST to to create a new app role assignment:
POST https://graph.windows.net/{tenant-id}/users/{id}/appRoleAssignments?api-version=1.6
...
{
"principalId":"{user-object-id}",
"resourceId":"{service-principal-object-id}",
"id":"00000000-0000-0000-0000-000000000000"
}
(In the example above, we use 00000000-0000-0000-0000-000000000000 as the app role ID because we want to create a default assignment (i.e. "no role"). This would correspond to the id of an AppRole in the ServicePrincipal object if we wanted to assign the user to a specific app role.)
Instead of using the servicePrincipal collection, we need to use the user entity to create the appRoleAssignment for the users. Here is an example for your reference:
POST:https://graph.windows.net/{tenant}/users/{userObjectId}/appRoleAssignments?api-version=1.6
authorization: Bearer {access_token}
Content-Type: application/json
{
"id":"00000000-0000-0000-0000-000000000000",
"resourceId":"{servicePrincipId}",
"principalId":"{userObjectId}"
}

Azure Batch - Setting custom user identity for tasks

I am using Azure Batch C# Client API 6.1. I am trying to have all my runs using the same user identity.
I am setting a custom user identity as below, as per MSDN documentation.
var task = new CloudTask("{guid}", "command string")
{
DisplayName = "display name",
UserIdentity = new UserIdentity("customUserid")
}
However when the job runs, the task executes under a random user account.
Would anyone know how to make it work OR even if it is supported by the backend Azure Batch service?
Thanks in advance
In order to use named user accounts, you need to first specify a list of UserAccount on your CloudPool during creation.
pool.UserAccounts = new List<UserAccount>
{
new UserAccount("myadminaccount", "adminpassword", ElevationLevel.Admin),
new UserAccount("mynonadminaccount", "nonadminpassword", ElevationLevel.NonAdmin),
};
You will then be able to execute tasks assigned to this pool with UserIdentity properties as you have in your example.
Unfortunately the MSDN documentation for this feature is lagging behind currently, but should be updated soon.