How to get subject id of Build Service - azure-devops

I am trying to configure permission in Azure DevOps using az devops cli following this answer (Assigning group permissions using to Azure DevOps CLI).
I successes update Force Push to Allow For Contributors group, using this command line:
az devops security permission update `
--id $namespaceId `
--subject $subject `
--token "$repoV2" `
--allow-bit $bit `
--merge true `
--org https://dev.azure.com/$org/
I extracted subject id by this command:
$subject = az devops security group list `
--org "https://dev.azure.com/$org/" `
--scope organization `
--subject-types vssgp `
--query "graphGroups[?#.principalName == 'ForcePush'].descriptor | [0]"
Now I want to do give Contribute (GenericContribute) to ProjectName Build Service (organization), (note: with red question mark in image). It is neither a user nor group, even thus it is under users category. How can I change permission for this using command line?
Note: It will be fine for me if the solution either az devops cli, rest api or graphs api.

Update:
Original Answer:
Refer to this official document so that we will know the namespace id:
https://learn.microsoft.com/en-us/azure/devops/organizations/security/namespace-reference?view=azure-devops
namespace id in your situation is: '2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87'
How to achieve your requirements:
Just Send API call to this:
https://dev.azure.com/<Organization Name>/_apis/AccessControlEntries/2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87
Request Method:
POST
Request Body:
{
"token": "repoV2/<Project ID>/<repo ID>/",
"merge": true,
"accessControlEntries": [
{
"descriptor": "Microsoft.TeamFoundation.ServiceIdentity;<Organization ID>:Build:<Project ID>",
"allow": 4,
"deny": 0,
"extendedInfo": {
"effectiveAllow": 4,
"effectiveDeny": 0,
"inheritedAllow": 4,
"inheritedDeny": 0
}
}
]
}
How to get the above IDs:
1, Organization ID.
I will suggest a simple method here(Of course you can try to use API to get it):
Turn on the browser, press F12 to turn on the debug mode and then go to this place:
https://dev.azure.com/<Organization Name>/
After that, search this: https://spsprodsea2.vssps.visualstudio.com/
You will get the organization ID here:
2, Project ID.
Just follows this API:
https://dev.azure.com/<Organization Name>/_apis/projects?api-version=6.0
https://learn.microsoft.com/en-us/rest/api/azure/devops/core/projects/list?view=azure-devops-rest-6.0
Just search the name in the response and you will get the ID. In this situation, the project build service account is managed via project id.
3, Repository ID.
https://dev.azure.com/<Organization Name>/<Project Name>/_apis/git/repositories?api-version=6.0
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/list?view=azure-devops-rest-6.0
Search the repository name and you will get the ID.
Success on my side:

To get the organization Id dynamically you just have to retrieve the value of the System.CollectionId variable as following:
$orgId = $(System.CollectionId)
Documentation: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#system-variables-devops-services

Related

aqquire localhost.json from azufunction (powershell commands install failed and I found no az-command for cmd.exe) Any Solutions?

I installed last year the powershell az core tools with big problems but got it working.
I used this 2 Commands to get the local.settings.json iwth actual values:
Connect-AzAccount -Tenant 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -SubscriptionId 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
func azure functionapp fetch-app-settings '<function-name>' --output-file local.settings.json
On installing the powershell core tools we spend a few hours and failed , so i tried to find similar command für standard command line (CMD.exe) but I found no similar command that worked so.
I found only this:
az login --tenant "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"
this sets the correct tenant and this worked.
I found additionally thsis commad to set the subscription but i got no response:
# change the active subscription using the subscription ID
az account set --subscription "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
And I could request the config setting on screen with that command:
az functionapp config appsettings list --name MyFunctionApp --resource-group MyResourceGroup
But i found no way to create with the az command the local.setings.json and the file is in wrong format so piping it in a file will not work too.
[
...
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"slotSetting": false,
"value": "dotnet"
},
...
]
Can anyone help me to get the file local.settings.json with actual config values with the az commands from standard windows shell.
Generally, local.settings.json file is ignored while publishing to Azure Function App as it is specified in the .gitignore file:
While publishing/deploying the function app, make sure to publish with the setting --publish-local-settings -i.
Syntax:
func azure functionapp publish <FunctionAppName> --publish-local-settings -i
Then, all the local.settings.json config values can be published and the values using the PowerShell cmdlet will be displayed:
Get-AzFunctionAppSetting -Name FunctionAppName -ResourceGroupName RGName | ConvertTo-Json | Out-File "local.settings.json"
OR use the same Az cmdlet to get the correct format of config settings defined in local.settings.json that are published to Azure function app.
to get the file local.settings.json with actual config values
Using az command for saving the published local.settings.json config values in a file:
az functionapp config appsettings list --name MyFunctionApp --resource-group MyResourceGroup --output json > local.settings.json

How can I get the Subscription Name if i know the resource Group Name using Powershell

So, I have the resource Group name and i want to programmatically (using powershell) set the subscription to the incoming resource group.
When i do a Get-AzResourceGroup I get the ResourceId which contains the the subscription id as part of a long string /subscriptions/<subscription id here>/resourceGroups/resourcegroupname. Is there a way to extract the subscription Id from that string?
You can get your subscription ID by triggering the below. You will also need to have azure cli installed.
az account list --refresh --query "[?contains(name, 'YOUR_SUBSCRIPTION')].id"
You can also split the output from powershell.
$myinput= "/subscriptions/xxxxxx-xxxxxx-xxxxxx-xxxxx-xxxxxx/resourceGroups/resourcegroupname".Split("/")
Write-Host $myinput[2]

Reference Wiki page from inside customized work item

I have created a customized work item. It there any way to link this work item with pre-created wiki page. I don't want to link it with work item manually, just kind of automatic link when create a new work item.
The most convenient workaround is to create a custom field for your work item. And create a rule to automatically set the wiki page url as value of the custom field.
Check tutorial here to Add a custom field.
Check here to Add a rule to a work item type, which will be triggered when a work item is created, and set the wiki url as the custom field value.
There is another workaround using azure pipeline and rest api.
Please check below steps:
1, create web hook to be triggered by Work item created event
When creating your webhook, you need to provide the following info:
Request Url - https://dev.azure.com/<ADO Organization>/_apis/public/distributedtask/webhooks/<WebHook Name>?api-version=6.0-preview
Secret - This is optional. If you need to secure your JSON payload, provide the Secret value
2, Create a new "Incoming Webhook" service connection.
Webhook Name: The name of the webhook should match webhook created in your external service.
3, Create a yaml pipeline.
Add service connection resources in the yaml pipeline see below:
resources:
webhooks:
- webhook: MyWebhookTrigger
connection: MyWebhookConnection #the name of the Incoming Webhook service connection created in above step.
Add script task in your pipeline to call work item update rest api. See below scripts:
steps:
- powershell: |
$workitemId= ${{ parameters.MyWebhookTrigger.resource.id}}
$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/wit/workitems/$($workitemId)?api-version=6.1-preview.3"
$body ='
[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "ArtifactLink",
"url": "vstfs:///Wiki/WikiPage/{projectName}/{wikiName}/{wikiPage}",
"attributes": {
"name": "Wiki Page"
}
}
}
]'
Invoke-RestMethod -Uri $url -Headers #{Authorization = "Bearer $(system.accesstoken)"} -ContentType "application/json-patch+json" -Method patch -body $body
Please check out this document for more information.
Above steps actually do below things:
New workitem is created-->automatically Trigger Azure pipeline-->Azure pipeline run script to call rest api to add the wiki page to the workitem.

How to assign group permissions to Azure DevOps Service Connections via API?

I create service connections via the terraform Azure DevOps module. This works well, but they are mainly accessible by myself, same as those I create manually.
My team members should also have the possibility to access and modify those service connections, and members of a different team should be able to view the service connections. Unfortunately, I have not found a way how to assign specific permissions to a service connection via azure cli.
What I have done so far:
I find it quite hard to understand the documentation (for example https://learn.microsoft.com/en-us/cli/azure/ext/azure-devops/devops/security/permission?view=azure-cli-latest#ext-azure-devops-az-devops-security-permission-update):
I have generated the list of "namespaces" with az devops security permission namespace list --organization=https://dev.azure.com/myname. This gives me
{
"actions": [
{
"bit": 1,
"displayName": "Use Service Connection",
"name": "Use",
"namespaceId": "x-x-x-x"
},
{
"bit": 2,
"displayName": "Administer Service Connection",
"name": "Administer",
"namespaceId": "x-x-x-x"
},
{
"bit": 4,
"displayName": "Create Service Connection",
"name": "Create",
"namespaceId": "x-x-x-x"
},
{
"bit": 8,
"displayName": "View Authorization",
"name": "ViewAuthorization",
"namespaceId": "x-x-x-x"
},
{
"bit": 16,
"displayName": "View Service Connection",
"name": "ViewEndpoint",
"namespaceId": "x-x-x-x"
}
],
"dataspaceCategory": "Default",
"displayName": "ServiceEndpoints",
"elementLength": -1,
"extensionType": null,
"isRemotable": false,
"name": "ServiceEndpoints",
"namespaceId": "x-x-x-x",
"readPermission": 0,
"separatorValue": "/",
"structureValue": 1,
"systemBitMask": 0,
"useTokenTranslator": true,
"writePermission": 2
},
I have created a group with az devops security group create --name 'Some group name'
--description 'Something to describe this group'; this works, although it is not an AAD group.
I have tried to add permissions for my colleague with az devops security permission update --organization=https://dev.azure.com/myname --id="x-x-x-x" --subject="my.colleague#example.org", but it asks me for a token as a parameter. I cannot find anything about how to generate the token in the documentation, and I also do not know if it actually would help or if this command is the right one to reach my goal.
Any hints?
Tokens are arbitrary strings representing resources in Azure DevOps. Token format differs per resource type, however hierarchy and separator characters are common between all tokens.
For the tokens, you can refer to Security tokens for permissions management for details, there are listed Token examples for different namespaces.
Another example for your reference (reference jessehouwing's blog) :
az login
az extension add --name "azure-devops"
# Find the group identifier of the group you want to set permissions for
$org = "gdbc2019-westeurope"
# There is a weird edge case here when an Azure DevOps Organization has a Team Project with the same name as the org.
# In that case you must also add a query to filter on the right domain property `?#.domain == '?'`
$subject = az devops security group list `
--org "https://dev.azure.com/$org/" `
--scope organization `
--subject-types vssgp `
--query "graphGroups[?#.principalName == '[$org]\Project Collection Administrators'].descriptor | [0]"
$namespaceId = az devops security permission namespace list `
--org "https://dev.azure.com/$org/" `
--query "[?#.name == 'Git Repositories'].namespaceId | [0]"
$bit = az devops security permission namespace show `
--namespace-id $namespaceId `
--org "https://dev.azure.com/$org/" `
--query "[0].actions[?#.name == 'PullRequestBypassPolicy'].bit | [0]"
az devops security permission update `
--id $namespaceId `
--subject $subject `
--token "repoV2/" `
--allow-bit $bit `
--merge true `
--org https://dev.azure.com/$org/
Besides, you could also take a look the steps in this similar question: Update permissions for Azure DevOps group for EventSubscription through Azure CLI?

VSO NuGet Publisher Build Step Fails

I am using Visual Studio Online - Package Manager Preview, along with the new build system. The package manager preview adds a number of build steps, including a "NuGet Publisher" step, which should push packages to the private feed hosted by Visual Studio Online.
Now the documentation is a little out of step here. As is the documentation on auth and personal access tokens. There are some indications that you shouldn't need auth between VSO and the Package Manager as long as you have permissions set up (the build service account has permissions to the service endpoint and to the package manager extension). The actual build step asks you to select from your list of Service Endpoints, so that is what I have attempted.
When I place no credentials on the Service Endpoint, I get the error:
Server Key must be set, set the password on the generic service
When I attempt to place the API key against the Service Endpoint it seems to be discarded on save... and the error changes to:
2015-11-18T08:35:24.5678951Z Invoking nuget with push C:\a\1\s\EventViewer\bin\Release\Project.Name.1.1.12.0.nupkg -s https://example.pkgs.visualstudio.com/DefaultCollection/_packaging/example/nuget/v3/index.json usfusmx4ez6mlfqwpp2abzc7e37denfcp7bxsep2hqij3tp4qwvq on C:\a\1\s\EventViewer\bin\Release\Project.Name.1.1.12.0.nupkg
2015-11-18T08:35:24.5688946Z C:\LR\MMS\Services\Mms\TaskAgentProvisioner\Tools\agents\default\agent\worker\tools\NuGet.exe push C:\a\1\s\EventViewer\bin\Release\Project.Name.1.1.12.0.nupkg -s https://example.pkgs.visualstudio.com/DefaultCollection/_packaging/Example/nuget/v3/index.json usfusmx4ez6mlfqwpp2abzc7e37denfcp7bxsep2hqij3tp4qwvq
2015-11-18T08:35:25.3467312Z Please provide credentials for: https://example.pkgs.visualstudio.com/DefaultCollection/_packaging/Example/nuget/v3/index.json
2015-11-18T08:35:25.3667189Z ##[error]Object reference not set to an instance of an object.
2015-11-18T08:35:25.3677179Z UserName: Password:
2015-11-18T08:35:25.4647059Z ##[error]Unexpected exit code 1 returned from tool NuGet.exe
I have also attempted to use a personal access token to no avail.
How do I get the publish step working?
The in-box NuGet Publish task has two options: "external" feeds and "internal" feeds. External feeds are intended for 3rd party services like NuGet.org, Artifactory, and expect a service connection with an API key.
Internal feeds are those hosted by Team Services. Instead of a service connection, you add the URL of the feed's NuGet endpoint. The build system relies on the Project Collection Build Service (for collection-scoped build definitions) or Project Build Service (for "this project"-scoped build defs) being a Reader or Contributor to the feed. Docs for all that are available here.
UPDATE: It is all fixed now so you can use the standard packaging steps in vNext and they work like a charm.
For the time being, I am substituting the NuGet Publisher step with a PowerShell build step.
This slots into the build after the "NuGet Packager" step and allows me to specify all of the credentials by setting up a package source before pusing the package.
$feedUrl = "https://example.pkgs.visualstudio.com/DefaultCollection/_packaging/Example/nuget/v3/index.json"
$packagePath = $ENV:BUILD_REPOSITORY_LOCALPATH + "\YourOrg.YourComponent." + $ENV:BUILD_BUILDNUMBER + ".nupkg"
Write-Host "Adding package Source"
$addSourceCommand = $ENV:BUILD_REPOSITORY_LOCALPATH + "\nuget sources add -name ""Example"" -source " + $feedUrl + " -username ""your.username"" -password ""yourpassword"""
Invoke-Expression -Command $addSourceCommand
Write-Host "Pushing package to NuGet"
$pushCommand = $ENV:BUILD_REPOSITORY_LOCALPATH + "\nuget push $packagePath -Source " + $feedUrl + " -ApiKey Example"
Invoke-Expression -Command $pushCommand
I landed here because I'm researching/configuring an internal deploy -- where I'm running my own NuGet Server (nuget.server, as opposed to visual studio online). The error was the same (or has similar text):
Object reference not set to an instance of an object
My solution, it turned out, was that the URL wasn't right.
The correct version is: http://server-name/NuGet/api/v2/package
For completeness, I had: http://server-name/NuGet/ which was wrong.