Azure CLI - Delete resource without deleting resource group - azure

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>

Related

Delete all the resources but not the resource group using Azure CLI

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.

How to filter resources using more than one tag using azure CLI?

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 :

How to setup array with azure get command with powershell

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

How can i pass a variable between tasks in Azure Devops/VSTS

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

powershell script for deleting all secrets from azure key vaults

Looking for a Powershell script which will delete all secretes present in an given azure key vault.
I don't want to delete entire key vault, just want to delete secretes present in it.
Use Remove-AzKeyVaultSecret, Remove-AzKeyVaultCertificate & Remove-AzKeyVaultKey
With some powershell and the Azure CLI you can achieve this
az keyvault secret list --vault-name ${keyVaultName} | ConvertFrom-Json | ForEach-Object { az keyvault secret delete --vault-name ${keyVaultName} --name $($_ | Select-Object -ExpandProperty Name) }
What it does is
Get all the secrets from the fault name
Transforms the response into objects
For each item take the name from the object and run the az keyvault secret delete command.
The answer by Danny van der Sluis tries to delete all secrets at once in one command, which doesn't seem to work. Putting this in a ps1 script worked for me:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
After this, you might want to purge your vault in case you want to remake some secrets using the same name. I found it easy enough to do this through the Azure Portal, but you can also use this command:
az keyvault key purge --name "mykeyname"
Yesman's version worked well for me, however, the purge command should be for secrets, not keys so if you want to delete and purge all secrets this works:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret purge --vault-name "mysupersecretvault" --name $_.Name }

Resources