question

YahavHorevCloudTeamai-2791 avatar image
0 Votes"
YahavHorevCloudTeamai-2791 asked azure-cxp-api edited

How to find Disks that are not attached/used more than xx days?

Hey guys i need your help please.

i need to find a way how to locate all my disks in my azure account that are not in used or not attached more than xx days ,
please help me to find the best way to do that ..

azure-disk-storageazure-managed-disks
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SathyamoorthyVijayakumar-MSFT avatar image
0 Votes"
SathyamoorthyVijayakumar-MSFT answered SathyamoorthyVijayakumar-MSFT edited

@YahavHorevCloudTeamai-2791 - I understand your requirement locating all the disks which have been unattached for a certain number of days.

Unfortunately - Get-AzDisk / Rest API for getting the list doesn't return the last modified date - So, there is currently no direct way to find whether the disk was in use.

There has been a feedback documented @ the below URL :
https://feedback.azure.com/forums/34192--general-feedback/suggestions/40411429-managed-disk-last-modify-date

Alternatively, you are looking for options to delete disks that have been unattached you can refer through the article :
- https://docs.microsoft.com/en-us/azure/virtual-machines/windows/find-unattached-disks (Powershell)
- https://docs.microsoft.com/en-us/azure/virtual-machines/disks-find-unattached-portal (Portal)

However, the above will not help in identifying the days for which it has been unattached.

I did a quick testing at my end and found an alternative that may meet your requirement.


Logic:

When the disk is unattached there is an activity log created with Action Create / Update disk. You can view this in the Activity log of the disk.

Note : I tested at my end - for all the unattached disks there was final Create or Update Event like below around the same time when the disk was unattached. I'd recommend confirming the similar behavior at your end.

103981-image.png

So, once we identify the disks that are unattached (managed by eq null). We can query activity log of the unattached disks for the for say X days. if there is no logs created in the X days - we can safely assume the disk was unattached prior to those X days. If you find events/logs during the period X days - then the disk was unattached recently.

Implementation :

You can manually do this in the portal. Identify the disks by following this article (https://docs.microsoft.com/en-us/azure/virtual-machines/disks-find-unattached-portal#unmanaged-disks-find-and-delete-unattached-disks)

103945-image.png

Filter for the Timespan for an unattached disk
103880-image.png


Alternatively, I wrote a small snippet that makes use of the REST API to get the log activity which does the above activity programmatically.

Note: I did try Get-Azlog commandlet did not return the results - possibility that it is making use of the Stable version of the API. This action is achievable only in the preview version of the API - Per my research.

 #Got the token by running Connect-AzAccount and running the below code. But you can use a better approach
 $token = (Get-AzAccessToken).Token
    
 $subscriptionid = "<YourSUBSID>"
    
 #Getting all the disks in your Subscription
 $disks = Invoke-RestMethod -Method Get -Uri "https://management.azure.com/subscriptions/$subscriptionid/providers/Microsoft.Compute/disks?api-version=2020-12-01" -Headers @{"Authorization"="Bearer $token"}
    
 #Getting the unattached disks from the above list 
 $unattacheddisks = $disks.value |  ? {$_.managedBy -eq $null }
    
 foreach ($disk in $unattacheddisks)
 {
 $resourceid = $disk.id
    
 #eventTimestamp is between 2021-05-09 to 2021-06-09  - You can generate a time stamp dynamically for smaller or a larger time span. 
 $filter = "eventTimestamp ge '2021-05-09T17:59:08Z' and eventTimestamp le '2021-06-09T17:59:08Z' and eventChannels eq 'Admin, Operation' and resourceId eq '$resourceid' and levels eq 'Critical,Error,Warning,Informational'"
    
 #Getting the Activity logs.This is the  preview API
 $log= Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/  $subscriptionid/providers/microsoft.insights/eventtypes/management/values?api-version=2017-03-01-preview&`$filter=$filter"  -Headers @{"Authorization"="Bearer $token"}
    
 #if there is no log returned - no activity
 if($log.value.Count -eq 0 )
 {
 Write-Host $disk.name + " : - There is no activitiy in 30 days" -ForegroundColor Yello
 }
 else
 {
 Write-Host $disk.name + " : - There is  activitiy in 30 days" -ForegroundColor Green
 }
 }

Output :
103868-image.png



Please do not forget to "Accept the answer" wherever the information provided helps you. This will help others in the community as well.














image.png (6.8 KiB)
image.png (14.3 KiB)
image.png (19.9 KiB)
image.png (11.6 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

YahavHorevCloudTeamai-2791 avatar image
0 Votes"
YahavHorevCloudTeamai-2791 answered

Hey !
First of all i am so gradeful for your Detalied answers!!
i have been out for a few days and my task was changed to :
1) get the vms in deallocated state for more than x days ,
2) if those VMs have a disk that is greater than 50GB size , tag the VMs and the disks
3) delete the tagged resources.

but anyway you answer to find those disks will help me now.
i will give it a try and will let you know if it worked.
** sharing with you my code for this one :)


 $ids = New-Object System.Collections.ArrayList
 $mergedTags = @{"Candidate"="Delete Me"}
 $vms =  (Get-AzVM -Status)
     foreach ($vm in $vms ) {
        $getStatuses = Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status  
        $getTodaysDate = Get-Date
        $ts = New-TimeSpan  -Start (($getStatuses.Statuses).Time).DateTime -End $getTodaysDate  
            [bool]$flag = 0
            if (($vm.PowerState -eq "VM deallocated") -AND ($ts.Days -gt 30)) {
            $ids.Add($vm.Id)
                 foreach ($disk in $getStatuses.Disks.Name) {
                     $diskSize = Get-AzDisk -ResourceGroupName $vm.ResourceGroupName -Name $disk
                     if ($diskSize.DiskSizeGB -gt 50) {
                         $flag = 1
                         $ids.Add($diskSize.Id)
                         if ($flag = 1) {
                             Update-AzTag -ResourceId $vm.Id -Tag $mergedTags -Operation Merge
                             Update-AzTag -ResourceId $diskSize.Id -Tag $mergedTags -Operation Merge
                         }
                     }
                 }
             }
         }
     } 


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.