I have json body in powershell variable and want to get value from it.
Json Body :
"value": [
{
"id": 1,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Default",
"isHosted": false,
"poolType": "automation",
"size": 3
},
{
"id": 2,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Hosted",
"isHosted": true,
"poolType": "automation",
"size": 10
},
{
"id": 4,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Hosted VS2017",
"isHosted": true,
"poolType": "automation",
"size": 10
}]
I want to get the id value where name=Hosted VS2017 i.e 4
powershell :
Write-Host "json body:" $projects
$id = $projects.value | where { $_.name -eq "Hosted VS2017" }
Write-Host "id :" $id
You need to convert your JSON into a powershell object before you can work with it:
$projects = $projects | ConvertFrom-Json
Then you can access its members:
#requires -Version 3
$projects.value | ? name -eq 'Hosted VS2017'
Related
I'm looking a way (or Query) to add the workItem Fields on the response of this query:
{
"query": "Select [System.Id], [System.Title] From WorkItems Where [System.WorkItemType] = 'Task' OR [System.WorkItemType] = 'Bug'"
}
Current Response:
{
"queryType": "flat",
"queryResultType": "workItem",
"asOf": "2020-08-17T15:13:32.75Z",
"columns": [
{
"referenceName": "System.Id",
"name": "ID",
"url": "https://dev.azure.com/.../_apis/wit/fields/System.Id"
},
{
"referenceName": "System.Title",
"name": "Title",
"url": "https://dev.azure.com/..._apis/wit/fields/System.Title"
}
],
"workItems": [
{
"id": 27,
"url": "https://dev.azure.com/.../_apis/wit/workItems/27"
},
{
"id": 44,
"url": "https://dev.azure.com/.../_apis/wit/workItems/44"
}
]
}
I need to expand Fields on each workItem found like i would be doing a GET workitems API request, even if its possible to ?$expand=relations
This would be my expected output on WorkItems
Expected Response:
{
"queryType": "flat",
"queryResultType": "workItem",
"asOf": "2020-08-17T15:13:32.75Z",
"columns": [
{
"referenceName": "System.Id",
"name": "ID",
"url": "https://dev.azure.com/.../_apis/wit/fields/System.Id"
},
{
"referenceName": "System.Title",
"name": "Title",
"url": "https://dev.azure.com/.../_apis/wit/fields/System.Title"
}
],
"workItems": [
{
"id": 27,
"rev": 22,
"fields": {
"System.AreaPath": "Cloud",
"System.TeamProject": "Cloud",
"System.IterationPath": "Cloud\\Sprint 6",
"System.WorkItemType": "Task",
"System.State": "Closed",
"System.Reason": "Completed",
"System.AssignedTo": {...},
"System.CreatedDate": "2020-02-24T15:52:08.867Z",
"System.CreatedBy": {...},
"System.ChangedDate": "2020-06-24T14:48:26.593Z",
"System.ChangedBy": {...},
"System.CommentCount": 6,
"System.Title": "Add XCAL import support to AAT3 framework and GUI",
"Microsoft.VSTS.Common.StateChangeDate": "2020-06-24T14:48:26.593Z",
"Microsoft.VSTS.Common.ActivatedDate": "2020-06-03T00:47:20.397Z",
"Microsoft.VSTS.Common.ActivatedBy": {...},
"Microsoft.VSTS.Common.ClosedDate": "2020-06-24T14:48:26.593Z",
"Microsoft.VSTS.Common.ClosedBy": {...},
"Microsoft.VSTS.Common.Priority": 2,
"Microsoft.VSTS.Common.ValueArea": "Business",
"WEF_DA224280DD46429CA75C96DC1082D816_Kanban.Column": "New",
"WEF_DA224280DD46429CA75C96DC1082D816_Kanban.Column.Done": false,
"System.Description": "...",
"System.Parent": 45
},
"relations": [...],
"_links": {...},
"url": "...workItems/27"
},
{
"id": 44,
...
}
]
}
I am afraid that the WIQL Rest API couldn't return the detailed work item information.
But you could use the WIQL Get the work item ids and send the ids to Work item -List. In this case, you could get the work item information.
Here is a PowerShell Script sample:
$token = "PAT"
$url="https://dev.azure.com/Organizationname/_apis/wit/wiql?api-version=5.1"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$JSON = #'
{
"query": "SELECT [System.Id], [System.WorkItemType], [System.State],[System.AreaPath],[System.Tags],[System.CommentCount],[System.ChangedDate] FROM workitems WHERE[System.Id] IN(#follows) AND [System.TeamProject] = 'Azure' AND [System.State] <> '' ORDER BY [System.ChangedDate] DESC"
}
'#
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json
$listOfTasks = New-Object Collections.Generic.List[String]
ForEach( $workitem in $response.workItems ) {
$listOfTasks.Add($workitem.id)
}
$listOfTasks = $listOfTasks -join ','
$listOfTasks
$url1="https://dev.azure.com/Organizationname/ProjectName/_apis/wit/workitems?ids=$listOfTasks" +"&" + "`$expand" + "=all&api-version=5.1"
$response1 = Invoke-RestMethod -Uri $url1 -Headers #{Authorization = "Basic $token"} -Method Get
Write-Host "result = $($response1 | ConvertTo-Json -Depth 100)"
Explaination:
The first part is to get the workitem id output by wiql.
The second part is to add work item id list to work item list api to obtain specific information of all work items.
Here is the result:
I have following policy rule. Finally it should check existence of a resourcegroup on subscription level. If it does not exist, a remediation task deployment should be started. I would like to pass parameters to this rule.
{
"if": {
"field": "type",
"equals": "Microsoft.Resources/subscriptions"
},
"then": {
"effect": "DeployIfNotExists",
"details": {
"type": "Microsoft.Resources/subscriptions/resourceGroups",
"name": "my_resource_group",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/{builtinroleGUID}"
],
"existenceScope": "Subscription",
"existenceCondition": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"field": "name",
"equals": "parameters('resourceGroup')"
}
]
},
"deploymentScope": "Subscription",
"deployment": {
"location": "westeurope",
"properties": {
"mode": "incremental",
"parameters": {
"targetResourceGroup": {
"value": "[parameters('resourceGroup')]"
},
"ascWorkflowName": {
"value": "[parameters('securityAutomationWorkflowName')]"
},
"location": {
"value": "[parameters('location')]"
},
"logicAppName": {
"value": "[parameters('logicAppName')]"
},
"logicAppSubscription": {
"value": "[parameters('logicAppSubscription')]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"targetResourceGroup": {
"type": "string"
},
"ascWorkflowName": {
"type": "string"
},
"location": {
"type": "string",
"defaultValue": "westeurope"
},
"logicAppName": {
"type": "string"
},
"logicAppSubscription": {
"type": "string"
}
},
"variables": {
"logicAppName": "[parameters('logicAppName')]",
"logicAppTriggerName": "When_an_Azure_Security_Center_Recommendation_is_created_or_triggered",
"logicAppResourceId": "[concat('/subscriptions/', parameters('logicAppSubscription'), '/resourceGroups/', parameters('targetResourceGroup') , '/providers/Microsoft.Logic/workflows/', variables('logicAppName'))]",
"ascWorkflowTriggerId": "[concat('/subscriptions/', parameters('logicAppSubscription'), '/resourceGroups/', parameters('targetResourceGroup') , '/providers/Microsoft.Logic/workflows/', variables('logicAppName') ,'/triggers/', variables('logicAppTriggerName'))]"
},
"resources": [
{
"apiVersion": "2019-01-01-preview",
"name": "[parameters('ascWorkflowName')]",
"type": "Microsoft.Security/automations",
"location": "westeurope",
"tags": {},
"properties": {
"description": "Workflow to push security center recommendations to our logicApp that routes it to serviceNow",
"isEnabled": true,
"scopes": [
{
"description": "[concat('scope for current subscriptionId:', subscription().subscriptionId)]",
"scopePath": "[concat('/subscriptions/',subscription().subscriptionId)]"
}
],
"sources": [
{
"eventSource": "Assessments",
"ruleSets": [
{
"rules": [
{
"propertyJPath": "type",
"propertyType": "String",
"expectedValue": "Microsoft.Security/assessments",
"operator": "Contains"
}
]
}
]
}
],
"actions": [
{
"logicAppResourceId": "[variables('logicAppResourceId')]",
"actionType": "LogicApp",
"uri": "[listCallbackUrl(variables('ascWorkflowTriggerId'), '2016-06-01').value]"
}
]
}
}
]
}
}
}
}
}
}
With this setup I would expect that the resourceGroup parameter reference links to the parameter of the parent policy-set /initiative.
But what I get is an error using the azure-cli in powershell. Why do I get the error?
function ConvertTo-PolicyJson {
param (
[PSCustomObject] $inputObject
)
# See this issue with convertto-json array serialization problem -
# https://stackoverflow.com/questions/20848507/why-does-powershell-give-different-result-in-one-liner-than-two-liner-when-conve/38212718#38212718
# Remove the redundant ETS-supplied .Count property
$removed = Remove-TypeData System.Array -erroraction 'silentlycontinue'
$json = ConvertTo-Json $inputObject -Depth 10
return $json.replace('"', '\"').replace("`n","").replace("`r","" )
}
...
$policyRuleParametersJson = ConvertTo-PolicyJson #{
"resourceGroup" = #{
"type" = "String"
"defaultValue" = "$ResourceGroup"
"metadata" = #{
"description" = "The resource group where the resources are located in"
"displayName" = "Resource group"
"strongType" = "existingResourceGroups"
}
}}
...
$policySetJson = ConvertTo-PolicyJson #(
#{
"policyDefinitionId" = "/subscriptions/$Subscription/providers/Microsoft.Authorization/policyDefinitions/$ResourceGroupExistsPolicyName"
"parameters" = #{
"resourceGroup" = #{
"value" = "my_resource_group"
} }
...
$policyDefinitionSetCreateResult = az policy set-definition create `
--subscription $Subscription `
--definitions $policySetJson `
--params $policyRuleParametersJson `
--name $PolicySetName `
--description $PolicySetDescription `
--display-name $PolicySetDisplayName
The error I am getting is:
The policy set 'my-policy-set' has defined parameters 'resourceGroup' which are not used in referenced policy definitions. Please either remove these parameters from the definition or ensure that they are used.
But I have used the resourceGroup parameter as far as I know.
By the way I condensed the error example to one parameter (resourceGroup). Finally I would like to use more parameters.
Can somebody help please?
Trying to give an answer on my own question.
I guess you need to use uppercase initiative parameter names that do not collide with child parameter names. For instance use RESOURCEGROUP_1 or RESOURCEGROUP if your policy parameter has been named resourceGroup. There seems to be an implicit naming convention for those parameter names that has not been documented properly.
Facing an issue while creating a ADO release pipeline - with powershell ADO rest API.
Below is the code -
[string]$organisation = "",
[string]$project = "",
[string]$keepForever = "true",
[string]$user = "",
[string]$token = "")
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$postresults = "https://vsrm.dev.azure.com/$organisation/$project/_apis/release/definitions?api-version=5.0"
$body = #{
"name"="New release pipeline russ"
"comment"="test"
"environments"=#{
"name"="DEV"
}
"path"="\\"
"releaseNameFormat"="Release"
"description"=""
} | ConvertTo-Json
$result = Invoke-RestMethod -Uri $postresults -Method Post -Body $body -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
And the error that I got is --
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"VS402875:
Release pipeline needs to have at least one stage. Add a stage and try again.",
"typeName":"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.I
nvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data
","typeKey":"InvalidRequestException","errorCode":0,"eventId":3000}
At line:27 char:1
Found similar issue in VS developer community blog, unfortunately no help in it -
https://developercommunity.visualstudio.com/content/problem/582209/post-example-to-create-a-release-pipeline.html
Any inputs are much appreciate .
Thanks,
The environments in the body should include at least name, preDeployApprovals, postDeployApprovals, deployPhases, retentionPolicy, otherwise, you'll get error. The body should look like below:
{
"name": "New release pipeline russ",
"comment": "test",
"environments": [
{
"name": "PROD",
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": null,
"id": "aeb95c63-4fac-4948-84ce-711b0a9dda97"
},
"id": 0
}
]
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
]
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {},
"queueId": 391,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Run on agent",
"workflowTasks": []
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
}
}
],
"path": "\\",
"releaseNameFormat": "Release",
"description": ""
}
Have a question about ARM template deployment, specifically calling that deployment from Runbook Powershell workflow using New-AzureRmResourceGroupDeployment cmdlet.
I am trying to use dynamic copy loop in in doing so I am using following formatted parameter in the template:
"aseApAppSettings": {
"type": "object",
"defaultValue": {
"apps": [
{
"name": "app-api-ecom",
"kind": "api"
},
{
"name": "app-ecom",
"kind": "web"
}
]
}
},
Then I create resources based on that:
{
"type": "Microsoft.Web/sites",
"kind": "[parameters('aseApAppSettings').apps[copyIndex()].kind]",
"name": "[concat(parameters('aseApName'),'sv-',parameters('aseApAppSettings').apps[copyIndex()].name)]",
"apiVersion": "2016-08-01",
"location": "East US 2",
"scale": null,
"properties": {...
},
"copy": {
"name": "svLoop",
"count": "[length(parameters('aseApAppSettings').apps)]"
},
"dependsOn": []
},
All works when template is deployed through Template Deployment
I need to call for this deployment from Powershell Workflow runbook and having tough time defining the parameter
I've tried setting it as
{"apps":[{"name":"falcon-api-ecom","kind":"api"},{"name":"falcon-ecom","kind":"web"}]}
during test but it fails with message "Cannot find parameter"
So I have tried using ConvertFrom-Json
But it sends this to my template
"CliXml": "<Objs Version=\"1.1.0.1\"
xmlns=\"http://schemas.microsoft.com/powers...
Please help,
Thanks
Sample from Runbook
workflow Build-Ase {
param
(
#Environment Parameters
[Parameter(Mandatory = $true)]
[object]
$aseApAppSettings
)
$params = #{
"aseApAppSettings" = $aseApAppSettings;
}
$job = New-AzureRmResourceGroupDeployment -ResourceGroupName $vnetRGName -TemplateUri $templateParameterUri -TemplateParameterObject $params
Write-Output $job
Nested objects didn't work for me either, but passing them in as a json string combined with the json function did work for me
Deployment script
$addionalParameters = New-Object -TypeName Hashtable
$addionalParameter1 = "{ ""prop1"": [ { ""name"": ""a"", ""value"": ""1"" }, { ""name"": ""b"", ""value"": ""2"" } ], ""prop2"": { ""name"": ""c"", ""value"": ""3"" } }"
$addionalParameters["myComplexNestedOnjectAsJsonString"] = $addionalParameter1
$deploymentOutput = New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath `
-TemplateParameterFile $parametersFilePath #addionalParameters
Template
{
"parameters": {
"myComplexNestedObjectAsJsonString": {
"type": "string"
}
},
"variables": {
"myComplexNestedObject" : "[json(parameters('myComplexNestedObjectAsJsonString'))]"
},
"resources": [],
"outputs": {
"prop1A": {
"type": "string",
"value": "[variables('myComplexNestedObject').prop1[0].value]"
},
"prop2": {
"type": "string",
"value": "[variables('myComplexNestedObject').prop2.value]"
}
}
}
Try using splatting. For me its the only thing that works with complex nested parameter objects. Also note how the aseApAppSettings parameter is constructed.
$params = #{
$aseApAppSettings = #{ #( {name=...;kind=...},{...},...,{...} ) }
}
New-AzureRmResourceGroupDeployment -ResourceGroupName $vnetRGName -TemplateUri $templateParameterUri #params
ps. ... represent placeholders
I'm new to Chef and I'm having some problems to get the values from data_bags with nested attributes.
{
"id": "bareos-fd",
"description": "Client resource of the Director itself.",
"address": "localhost",
"job": {
"backup-bareos-fd": {
"jobdefs": "DefaultJob"
},
"BackupCatalog": {
"description": "Backup the catalog database (after the nightly save)",
"jobdefs": "DefaultJob",
"level": "Full",
"fileset": "Catalog",
"schedule": "WeeklyCycleAfterBackup",
"run_before": "/usr/lib/bareos/scripts/make_catalog_backup.pl MyCatalog",
"run_after": "/usr/lib/bareos/scripts/delete_catalog_backup",
"bootstrap": "|/usr/bin/bsmtp -h localhost -f \\\"\\(Bareos\\) \\\" -s \\\"Bootstrap for Job %j\\\" root#localhost",
"priority": "11"
},
"RestoreFiles": {
"type": "Restore",
"fileset": "LinuxAll",
"storage": "File",
"pool": "Incremental",
"messages": "Standard",
"where": "/tmp/bareos-restores"
}
}
}
How can I write a foreach to get the nested values (like BackupCatalog and its values?)
The object returned from data_bag_item works like a hash:
bag = data_bag_item('something', 'bareos-fd')
bag['job']['BackupCatalog'].each do |key, value|
# ...
end