Azure housekeeping with bash and CLI 2.0

Occasionally it’s a good idea to do some housekeeping on your Azure subscription.

The three bash & Azure cli 2.0 scripts in this post will:

  1. Try to find any ‘orphaned’ .vhd disk files that are in your storage account and show the command needed to delete them. When you delete a VM you’ll typically leave behind a .vhd file in the storage account associated with that VM. As these are 128GB page blobs if you have created and destroyed a lot of VM’s the cost keeping these ‘orphaned’ .vhd’s you are no longer using can build up over time
  2. Find any ‘orphaned’ public IP’s you provisioned with deleted VM’s and show the command to delete them
  3. Find any ‘orphaned’ Network Interfaces and again show the command to delete them.

All three scripts assume you have completed the cli 2.0 login process. (az login) and set the subscription (az account set -s “Your Subscription name”)

You can confirm these have been done by checking the output of the az account show command , it should list the subscription you set.

MacBook-Pro:cli2 AndyT$ az account show
{
  "environmentName": "AzureCloud",
  "id": "12345678-abcd-1234-abcd-123456789abc",
  "isDefault": true,
  "name": "Your Subscription Name",
  "state": "Enabled",
  "tenantId": "87654321-1234-abcd-1234-abc123456789",
  "user": {
    "name": "yourlogin@your.domain",
    "type": "user"
  }
}
MacBook-Pro:cli2 AndyT$ 

So here are the scripts – use at your own risk!

1. Cleanup storage
i=0
for g in `az group list | grep name | awk {'print $2'} | cut -d'"' -f2` ; do
  echo Scanning Resource Group: $g
  j=0
  for f in `az storage account list -g $g --query '[*].{name: name}' | grep 'name\|enc\|sku' | awk {'print $2'} | cut -d'"' -f2 ` ; do  
    echo Stor Acc = $f
    k=`az storage account keys list --resource-group $g --account-name $f --query '[0].value'`
    for cont in `az storage container list --query '[*].{name: name}' --account-name $f --account-key $k | grep 'name' | awk {'print $2'} | cut -d'"' -f2 `
      do
      #echo Found Container = $cont  
      if [ $cont == "vhds" ] ; then
        echo Scanning for Blobs in vhds container  
        let j=0
        for blob in `az storage blob list --query '[*].{name: name,type: properties.blobType,lease: properties.lease.state, content: properties.contentSettings.contentType}' --container-name $cont --account-name $f | grep 'lease\|name\|type\|content' | awk {'print $2'} | cut -d'"' -f2`
        do
          if [ $j -eq 0 ] ; then
            bcontent[i]=$blob
          fi
          if [ $j -eq 1 ] ; then
              blease[i]=$blob
          fi
          if [ $j -eq 2 ] ; then
              bname[i]=$blob
          fi
          if [ $j -eq 3 ] ; then
              btype[i]=$blob
              brg[i]=$g
              bstor[i]=$f
              bcont[i]=$cont
          fi
          let j=j+1
          if [ $j -ge 4 ] ; then
              let j=0
              let i=i+1
          fi
        done
      fi
    done
  done
done
let i=i-1
echo $i
for k in `seq 0 $i`; do 
  if [ ${blease[$k]} != "leased" ] ; then
    if [ ${bcontent[$k]} == "application/octet-stream" ] ; then
      if [ ${btype[$k]} == "PageBlob" ] ; then
        fname="${bname[$k]}"
        fl=${#fname}
        let fb=$fl-4
        fext=${fname:$fb:$fl}
        if [ $fext == ".vhd" ] ; then
          printf "Delete:  %s " "${brg[$k]}"
          printf "  %s "  "${bstor[$k]}"
          printf "  %s "  "${bcont[$k]}"
          printf "  %s\n"  "${bname[$k]}"
          echo Command to use: az storage blob delete --account-name ${bstor[$k]} --container-name ${bcont[$k]} --name ${bname[$k]} --delete-snapshots include
          printf "\n\n"
        fi
      fi
    fi
  fi
done
2. Cleanup public ip’s
i=0
for g in `az group list | grep name | awk {'print $2'} | cut -d'"' -f2` 
do
  echo Scanning Resource Group = $g
  let j=0
  for n in `az network public-ip list -g $g  --query '[*].{name: name,ipc: ipConfiguration.id}' | grep 'name\|ipc' | awk {'print $2'}`
  do
    if [ $j -eq 1 ] ; then
      nname[i]=$n
      nn=`echo $n | cut -d',' -f 1 | cut -d'"' -f 2`
      nname[i]=$nn
    fi
    if [ $j -eq 0 ] ; then
      nc=`echo $n | cut -d',' -f 1`
      nvm[i]=$nc
      brg[i]=$g
    fi
    let j=j+1
    if [ $j -ge 2 ] ; then
      let j=0
      let i=i+1
    fi
  done
done
let i=i-1
echo "Found $i Public IP's - checking if any are orphaned ..."
for k in `seq 0 $i`; do
  if [ ${nvm[$k]} == "null" ] ; then
    printf "Delete: %s " "${brg[$k]}"
    printf "  %s "  "${nname[$k]}"
    printf "  %s \n"  "${nvm[$k]}"
    echo Command: az network public-ip delete -g ${brg[$k]} --name ${nname[$k]} --verbose
  fi
done
3. Cleanup network interfaces
i=0
for g in `az group list | grep name | awk {'print $2'} | cut -d'"' -f2` 
do
  echo Resource Group = $g
  let j=0
  for n in `az network nic list -g $g  --query '[*].{name: name,vm: virtualMachine}' | grep 'name\|vm' | awk {'print $2'}`
  do
    if [ $j -eq 0 ] ; then
      nname[i]=$n
      nn=`echo $n | cut -d',' -f 1 | cut -d'"' -f 2`
      nname[i]=$nn
    fi
    if [ $j -eq 1 ] ; then
      nvm[i]=$n
      brg[i]=$g
    fi
    let j=j+1
    if [ $j -ge 2 ] ; then
      let j=0
      let i=i+1
    fi
  done
done
let i=i-1
echo "Found $i NIC's - checking if any are orphaned ..."
for k in `seq 0 $i`; do
  if [ ${nvm[$k]} == "null" ] ; then
    printf "Delete: %s " "${brg[$k]}"
    printf "  %s "  "${nname[$k]}"
    printf "  %s \n"  "${nvm[$k]}"
    echo az network nic delete -g ${brg[$k]} --name ${nname[$k]} --verbose
  fi
done

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s