So I’ve recently been using lots of VM’s and I end up getting through them fairly quickly – deleting and creating them regularly.
What I ended up with was loads of ghost services in the portal that were, once upon a time, associated with a VM in the distant past.
Given PowerShell is awesome, I set about automating the removal of these using the azure cmdlts. The trick is that I don’t want to remove services or VM’s that are currently “Stopped Deallocated” only those ghost services.
The script has three stages:
- Find all VM’s and their associated services.
- Find all the services without active deployments.
- Identify if any of these empty services have VM’s associated with them.
- Perform remove action on these services.
$performRemove = $true
#Find all services used by your VMs
$servicesUsedByVms = @{}
$vms = Get-AzureVM
foreach ($v in $vms)
{
$servicesUsedByVms.Add($v.ServiceName, $v)
}
#Find all services without active deployments
$servicesWithoutDeployments = @{}
$services = Get-AzureService
foreach ($s in $services)
{
$response = Get-AzureDeployment -ServiceName $s.ServiceName -ErrorVariable depError -ErrorAction SilentlyContinue | ?{$depError.Count -eq 1}
if ($depError.Count -eq 1 -and $depError.Item(0).Exception.ErrorDetails.Message -eq "No deployments were found.")
{
$servicesWithoutDeployments.Add($s.ServiceName, $s)
}
}
#Pull out Unused services and confirm they're not used by vm. Technically not necessary but being careful
$unusedServices = @{}
foreach ($s in $servicesWithoutDeployments.Keys)
{
if ($servicesUsedByVms.ContainsKey($s))
{
"Contained - VM Paused: " + $s
}
else
{
"Does not Contained paused VM. Marked for Removal: " + $s
$unusedServices.Add($s, $servicesWithoutDeployments.Values[$s])
}
}
#Preform action on that service
foreach ($s in $unusedServices.Keys)
{
if ($performRemove)
{
Start-Job -scriptBlock {
param($s)
Write-host "Performing Remove " + $s -ForegroundColor DarkYellow
Remove-AzureService -ServiceName $s -Force
write-host "Remove Completed" -ForegroundColor DarkYellow
} -ArgumentList $s
}
}
# Wait for it all to complete
While (Get-Job -State "Running")
{
Start-Sleep 10
}
# Getting the information back from the jobs
Get-Job | Receive-Job