I'm a total Powershell newb and still learning.
I am trying to get a list of Azure Webjobs that has been stopped in a webapp. I understand when i run the command az webapp webjob continuous list, id get a large set of array data.
I am having troubles with splitting it up, could someone advise how would i split it up as individual jobs and their properties?
i tried $webjobs = ($webname.Split('}')) and it wont split up the giant array.
This is my current code
$groups = get-AzResourceGroup | where{$_.ResourceGroupName -like "Dev"}
foreach($group in $groups){
Write-Host -ForegroundColor Cyan "processing resourceGroup" $group.ResourceGroupName
$webApps = Get-AzWebApp -ResourceGroupName $group.ResourceGroupName
foreach($webApp in $webApps){
write-host -ForegroundColor Yellow $webApp.Name
$webname = (az webapp webjob continuous list --name $webApp.Name --resource-group $group.ResourceGroupName --query '[].name' -o tsv)
$webstatus = (az webapp webjob continuous list --name $webApp.Name --resource-group $group.ResourceGroupName --query '[].status' -o tsv)
Write-host $webname
Write-host $webstatus
}
}
The result i get is...
processing resourceGroup dev
hub-dev-app-hub
hubv3-dev-app-hub/Data hubv3-dev-app-hub/ProcessToolData hubv3-dev-app-hub/ToolDataNotifications hubv3-dev-app-hub/UploadLasToSftp hubv3-dev-app-hub/ApplicationInsightsProfiler3 hubv3-dev-app-hub/DaaS
Running Running Running Running Running Stopped
hubv3-dev-app-authservice
hubv3-dev-app-authservice/ApplicationInsightsProfiler3
Running
hubv3-dev-app-api
hubv3-dev-app-api/ApplicationInsightsProfiler3
Running
What i am hoping to achieve is
hub-dev-app-hub
hubv3-dev-app-hub/Data Running
hubv3-dev-app-hub/ProcessToolData Running
hubv3-dev-app-hub/ToolDataNotifications Running
hubv3-dev-app-hub/UploadLasToSftp Running
hubv3-dev-app-hub/ApplicationInsightsProfiler3 Running
hubv3-dev-app-hub/DaaS Stopped
Any help would be greatly appreciated.
The result you get is expected for the code written. Taking into account tsv docs, means that $webname and $webstatus are arrays. When you write Write-Host $webstatus it will print all the data in the array, in this case:
Running
Running
Running
Running
Running
Stopped
What you could do is the following:
$webname = (az webapp webjob continuous list --name $webApp.Name --resource-group $group.ResourceGroupName --query '[].name' -o tsv)
$webstatus = (az webapp webjob continuous list --name $webApp.Name --resource-group $group.ResourceGroupName --query '[].status' -o tsv)
for ($i = 0; $i -lt $webname.length; $i++) {
Write-Host $webname[$i]
Write-Host $webstatus[$i]
}
But what you should do is use another query: [].[name, status]. Have a look at jmesPath.
This is better because you only do 1 request instead of two, and it should have the format that you would expect, i.e. array of name and status.
$webjobInfo = (az webapp webjob continuous list --name $webApp.Name --resource-group $group.ResourceGroupName --query '[].[name, status]' -o tsv)
Write-Host $webJobInfo
Related
There is an solution in the Stack overflow that contains the commands for deleting the resources in a resource group but it's not working for us.
In the Azure Cloud Shell,
When using the command given from above link, getting the error as:
unrecognized arguments: ConvertFron-Json Foreach-Object {az resource delete --ids /usr/bin/cloudshellhelp.id --verbose
for the command: az resource list --resource-group senthil-b-rg ConvertFrom-Json Foreach-Object {az resource delete --resource-group senthil-b-rg --ids $_.id --verbose}
If I keep pipe (|) symbol in the command:
az resource list --resource-group senthil-b-rg \
| ConvertFrom-Json | Foreach-Object {az resource delete --resource-group senthil-b-rg --ids $_.id --verbose}
Errors are
bash:ConvertFrom-Json: command not found
bash: Foreach-Object: command not found
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipleError: [Errno 32] Broken pipe
I tried to reproduce the same in my environment and got the same error as below:
az resource list --resource-group myresourcegroup \
| ConvertFrom-Json | Foreach-Object {az resource delete --resource-group myresourcegroup --ids $_.id --verbose}
Response:
In my resource group, I have resources like below:
To resolve the error, I tried to run the same command in PowerShell and got the same warning as below:
But the resources got deleted in the Portal:
Please note that, while deleting the resources you need to follow the order:
Make sure to delete the child (nested) resources initially.
Delete the resources that manage the other resources.
Reference:
Delete resource group and resources - Azure Resource Manager | Microsoft Docs
UPDATE:
To get rid of the warning, you need to add --only-show-errors in the command like below:
$resources = az resource list --resource-group myresourcegroup | ConvertFrom-Json
foreach ($resource in $resources) {
az resource delete --resource-group myresourcegroup --ids $resource.id --only-show-errors
}
Response:
Make sure to remove --verbose as --only-show-errors doesn't work with it.
I can able to get the resource details by using the tag using the Azure CLI command
az resource list --tag AppID=XXXX --query [].name
However, how can filter resources use more than one tag? Could you please help?
Example:
az resource list --tag AppID=XXXX, Region=DEV --query [].name
Based on the above requirement we have created a script using both Azure CLI cmdlets & PowerShell cmdlet to filter the resources using more than one Tag.
Script using PowerShell Cmdlet:
connect-azaccount
$resource = Get-AzResource -ResourceGroupName <resourcegroupName> -TagName env -TagValue prod |Select-Object -Property ResourceId
$resourcearray=$resource
foreach ( $resource in $resourcearray){
$Tagvalue=(Get-AzTag -ResourceId $resource.ResourceId)
if ($Tagvalue.Properties.TagsProperty.Count -gt 1)
{
$Tagvalue.Id -replace "/providers/Microsoft.Resources/tags/default",""
}
}
Here is the output for reference :
Script using Azure CLI cmdlets:
$re= az resource list --tag env=prod
$rearray = $re |ConvertFrom-Json
foreach ( $re in $rearray)
{
$tagcount=$(az tag list --resource-id $re.id --query "properties.tags|length(#)")
if ($tagcount -ge 1)
{
$re.id
}
Here is the output for reference :
The goal is to delete all resources in a resourcegroup without deleting it using azure CLI.
From reading the doc, I can do this:
az resource delete -g MyResourceGroup -n MyVm
Therefore I assumed I can do the following
az resource list --resource-group MyResourceGroup | az resource delete
A similar command in Azure Powershell would work like the above. I am quite new to CLI, is this method possible? What is the efficient way of removing all resources in a resource group (if we have multiple types of resources)
If can you run Azure CLI in powershell, you could use ConvertFrom-Json to convert the JSON result to a list of objects from az resource list, then run az resource delete on each object id using a foreach loop.
$resources = az resource list --resource-group myResourceGroup | ConvertFrom-Json
foreach ($resource in $resources) {
az resource delete --resource-group myResourceGroup --ids $resource.id --verbose
}
We could also run this entirely in the pipeline using Foreach-Object, which is close to what you are trying to do.
az resource list --resource-group myResourceGroup
| ConvertFrom-Json
| Foreach-Object {az resource delete --resource-group myResourceGroup --ids $_.id --verbose}
If you don't want to use powershell at all, we can use bash to parse the JSON output ourselves using grep and awk.
#!/bin/bash
resources="$(az resource list --resource-group myResourceGroup | grep id | awk -F \" '{print $4}')"
for id in $resources; do
az resource delete --resource-group myResourceGroup --ids "$id" --verbose
done
As #Hong Ooi helpfully pointed out in the comments, the main issue with the above is that some resources depend on other resources, so order of deletion matters. One example is that you cannot delete virtual machine disks before the virtual machine is deleted.
To get around this, we could define an ordering of resource types in which to delete resources, as shown in the example hash table below:
$resourceOrderRemovalOrder = [ordered]#{
"Microsoft.Compute/virtualMachines" = 0
"Microsoft.Compute/disks" = 1
"Microsoft.Network/networkInterfaces" = 2
"Microsoft.Network/publicIpAddresses" = 3
"Microsoft.Network/networkSecurityGroups" = 4
"Microsoft.Network/virtualNetworks" = 5
}
Then sort the resources by their resource types and delete them:
$resources = az resource list --resource-group myResourceGroup | ConvertFrom-Json
$orderedResources = $resources
| Sort-Object #{
Expression = {$resourceOrderRemovalOrder[$_.type]}
Descending = $False
}
$orderedResources | ForEach-Object {
az resource delete --resource-group myResourceGroup --ids $_.id --verbose
}
Or in one pipeline if you prefer:
az resource list --resource-group myResourceGroup
| ConvertFrom-Json
| Sort-Object #{Expression = {$resourceOrderRemovalOrder[$_.type]}; Descending = $False}
| ForEach-Object {az resource delete --resource-group myResourceGroup --ids $_.id --verbose}
There is a faster and simpler approach:
az deployment group create --mode complete --template-uri data:application/json,%7B%22%24schema%22%3A%22https%3A%2F%2Fschema.management.azure.com%2Fschemas%2F2019-04-01%2FdeploymentTemplate.json%23%22%2C%22contentVersion%22%3A%221.0.0.0%22%2C%22resources%22%3A%5B%5D%7D --name clear-resources --resource-group <RG_NAME>
The above data URI (which may also be Base64-encoded) represents this file:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": []
}
In an Azure DevOps pipeline you have to pass an actual file with the JSON contents above as DevOps only allows HTTP(s) schemes with --template-uri:
az deployment group create --mode complete --template-file ./clear-resources.json --resource-group <RG_NAME>
For Task 1 I have a CLI task which simply gets the subnet name and subnet ref as below
$subnetname1 = az network vnet subnet list --resource-group vnetrg01 --vnet-name vnet01 --query "[].name" -o tsv
$subnetref1 = az network vnet subnet list --resource-group vnetrg01 --vnet-name vnet01 --query "[].id" -o tsv
For task 2 I want to deploy an arm template which will use parameters from the pipleine variables in Azure Devops
So for example the result of $subnetref1 in Task 1 above needs to populate the pipleline variable for subnetref (which is setup as a variable in the pipleine) which will then be passed to the arm template override parameters
cant seem to get this working
You can do it with Powershell command,
In the first PowerShell task set the variable as environment variable:
$subnetname1 = az network vnet subnet list --resource-group vnetrg01 --vnet-name vnet01 --query "[].name" -o tsv
Write-Host $subnetname1
Write-Host ("##vso[task.setvariable variable=subnetname1;]$subnetname1")
In the second task read the variable in this way:
$subnetname1 = $env:subnetname1
Write-Host $subnetname1
I am trying to set up Azure Key Vault for my application by following this tutorial: https://blogs.technet.microsoft.com/kv/2015/06/02/azure-key-vault-step-by-step/
In the Create and configure key vault section in the tutorial, Right after doing these two steps:
I am not able to do this step:
It shows error message in my PowerShell:
New-AzureRmKeyVault : 'vaultName' does not match expected pattern '^[a-zA-Z0-9-]{3,24}$'.
At line:1 char:1
+ New-AzureRmKeyVault -VaultName ProfileKeyVault -ResourceGro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmKeyVault], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.KeyVault.NewAzureKeyVault
Try putting the vault name in quotes.
New-AzureRmKeyVault -VaultName 'Contoso03Vault' -ResourceGroupName 'Group14' -Location 'East US'
When I got the error
'vaultName' does not match expected pattern
I found using Powershell with raw Az CLI Commands you have to use Double Quotes to create the KeyVault.
az keyvault create --name "vault-Name-01" --resource-group $resourceGroupName --location $location --sku Standard --enabled-for-disk-encryption true
In a Powershell script you pass in the variable wrapped with double quotes
[string]$vaultName = "vault-Name-01"
az keyvault create --name $vaultName --resource-group $resourceGroupName --location $location -sku Standard --enabled-for-disk-encryption true
Then when you want to set a value you remove the double quotes:
az keyvault secret set --vault-name $vaultName.Replace("`"","") --name $_.name --value $_.value
Further investigation reveals the problem applies to listing and showing the vault secrets and I bumped into the infamous error:
Max retries exceeded attempting to connect to vault. The vault may not exist or you may need to flush your DNS cache and try again later.
The KeyVault exists, because I can list the vaults secrets using the VaultName without quotes:
$secretNames = az keyvault secret list --vault-name $sourceVaultName.Replace("`"","") -o json --query "[].name" | ConvertFrom-Json
However you'll get the Max Retires error if you don't include a quoted $sourceVaultName when trying to show the secrets:
$secrets = $secretNames | % {
$secret = az keyvault secret show --name $_ --vault-name $sourceVaultName -o json | ConvertFrom-Json
[PSCustomObject]#{
name = $_;
value = $secret.value;
}
}
If any of these calls timeout and the result is blank refer to this solution: https://stackoverflow.com/a/67472219/495455
It's almost like two developers worked on the code and had different opinions... https://github.com/Azure/azure-cli/issues/13952