Can we inherit the tags from Azure VM and then assign same tags to NIC & OS Disk. How is it done

Girish Prajwal 706 Reputation points
2020-11-04T12:27:11.3+00:00

Hi Team,

I would want to inherit the Tags from VM to depended resources like OS disk and NIC cards at the time of VM creation. We have around 8 tag key/value which is assigned for a VM. We need same tag values to be assigned to NIC & Osdisks too. Please suggest my options.

Azure Policy
Azure Policy
An Azure service that is used to implement corporate governance and standards at scale for Azure resources.
883 questions
{count} votes

Accepted answer
  1. SwathiDhanwada-MSFT 18,756 Reputation points
    2020-11-11T14:19:04.947+00:00

    @Girish Prajwal The below snippets shows on how to retrieve disks and NIC from a resource group which contains single vm. Merge these commands into your script and revert if you need further assistance.

    # Retrieves resource group  
    $rgs = Get-AzResourceGroup -Name rgname  
    $vmname = Get-AzVM -ResourceGroupName $Rgname -Name $vm.Name   
    $vmtags = (Get-AzVM -ResourceGroupName $Rgname -Name $vm).Tags  
      
    #Retrieves NIC of the vm  
    $vmNic = $vmname.NetworkProfile.NetworkInterfaces.Id  
      
    #Lists all the disks in resource group  
    $vmdisk = Get-AzDisk -ResourceGroupName $Rgname  
      
    #loop checks if disk is linked to vm and update the tags yo disk  
    foreach ($d in $vmdisk) {  
                    $dManagedBy = $d.ManagedBy  
         
                    if ($d.ManagedBy -eq $vmname.Id) {  
                        Write-Output "Applying Tags to $d" $vmtags  
                        $Settagdisk = Update-AzTag -ResourceId $d.Id  -Tag $vmtags -Confirm  
                    }  
                }  
    
    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Girish Prajwal 706 Reputation points
    2020-11-12T11:34:57.743+00:00

    Here is the Updated Script. You left out on the NIC. I was able to gather the details for NIC and completed the script. Thank you once again.

    # List all Resources within the Subscription
        $rgs = Get-AzResourceGroup
    # For each Resource apply the Tag of the Resource Group
        Foreach ($rg in $rgs)
        {
        $Rgname = $rg.Resourcegroupname
        $resouce = $rg.ResourceId
        $vms = (Get-AzVM -ResourceGroupName $Rgname).Name
        foreach ($vm in $vms)
        {
        $vmname = (Get-AzVM -ResourceGroupName $Rgname -Name $vm).Name
        $vmtags = (Get-AzVM -ResourceGroupName $Rgname -Name $vm).Tags
        $vmNic = Get-AzNetworkInterface -ResourceGroupName $Rgname
        $NICId = $vmNic.Id
        $vmdisk = Get-AzDisk -ResourceGroupName $Rgname
        $vmId = (Get-AzVM -ResourceGroupName $Rgname -Name $vm).Id
    
                     foreach ($d in $vmdisk) {
                     $dManagedBy = $d.ManagedBy
    
                     if ($d.ManagedBy -eq $vmId) {
                      Write-Output "Applying Tags to $d" $vmtags
                      $Settagdisk = Update-AzTag -ResourceId $d.Id  -Tag $vmtags -Operation Merge -Confirm 
                      }
                      foreach ($N in $vmNic) {
                     $NManagedBy = $N.Id
                      if ($N.Id -eq $NICId){
                       Write-Output "Applying Tags to $N.Id" $vmtags
                      $SettagNic = Update-AzTag -ResourceId $N.Id -Tag $vmtags -Operation Merge -Confirm
    
        }
        }
        }
        }
        }
    
    0 comments No comments

  2. Girish Prajwal 706 Reputation points
    2020-11-10T08:06:48.46+00:00
    Hi Swathi,
    Azure policy is not an answer. I want it via powershell/arm templates to assign it.
    We are not using policy in our environment.
    # List all Resources within the Subscription
        $rgs = Get-AzResourceGroup
    # For each Resource apply the Tag of the Resource Group
        Foreach ($rg in $rgs)
        {
        $Rgname = $rg.Resourcegroupname
        $resouce = $rg.ResourceId
        $vms = (Get-AzVM -ResourceGroupName $Rgname).Name 
        foreach ($vm in $vms)
        {
        $vmname = Get-AzVM -ResourceGroupName $Rgname -Name $vm -Status
        #$osdisk = $vmname.StorageProfile.OsDisk.Name
        $vmtags = (Get-AzVM -ResourceGroupName $Rgname -Name $vm).Tags
            if ($vmtags -eq $null)
        {
        Write-Output "-------------------------"
        Write-Output "Applying Tags to $($osdisk)" $vmtags
        $Settag = Update-AzTag -ResourceId $resouce  -Tag $vmtags -Confirm
        }
        Else
                    {
                        $vmtagfinal = @{}
                        $vmtagfinal = $vmtags                  
                                Foreach ($resouce in $vmtags.GetEnumerator())
                                {
    
                                If ($vmtags.Keys -inotcontains $vmtags.Key)
                                    {                        
                                            Write-Output "------------------------------------------------"
                                            Write-Output "Key doesn't exist in RG Tags adding to Hash Table" $resourcetag
                                            Write-Output "------------------------------------------------"
                                            $RGTagFinal.Add($vmtags.Key,$vmtags.Value)
    
                                    }    
    
                                }
                        Write-Output "---------------------------------------------"
                        Write-Output "Applying the following Tags to $($resourceid)" $vmtagfinal
                        Write-Output "---------------------------------------------"
                        $Settag = Set-AzResource -ResourceId $resourceid -Tag $vmtagfinal -Force
                        #$Settag = Set-AzResource -ResourceId $resourceid -Tag $RGTagFinal -WhatIf
                    }   
            }
        }
    
        Help me correct the script above. It is picking the Tags from the VM. but Since for OS Disk, I am not getting the details OS Disk ID & Network Interfce ID.
    
    Regards,
    Girish 
    
    0 comments No comments

  3. Jack Tu 0 Reputation points Microsoft Employee
    2023-08-11T07:02:55.89+00:00

     I just worked it out, after you select the subscription via the cloud shell.

     

    You can run the below script to get tags from the vm level under a specified subscription and then apply the same tag to the disks and network interface card that is associated with the vm. I have run it in my lab and works perfectly.

    Notes: The customized script is Microsoft Best Effort support, it’s not guaranteed to be flawless, please test in your testing sub scription before use it directly in your product environment.

    Copyright (c) Microsoft Corporation.MIT LicensePermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Script Details:

    
    
    
    
    
    # Get the list of virtual machines
    $vms = Get-AzVM
    
    # Loop through each virtual machine
    foreach ($vm in $vms) {
        # Get VM details
       $vmResourceGroup = $vm.ResourceGroupName
        $vmName = $vm.Name
        $vmId = $vm.Id
    
        Write-Host "Processing VM: $vmName in Resource Group: $vmResourceGroup"
    
        # Get VM Tags
        $vmTags = (Get-AzResource -ResourceGroupName $vmResourceGroup -ResourceName $vmName -ResourceType "Microsoft.Compute/virtualMachines").Tags
    
        # Get the VM's all disk resource ids
        $diskIds = Get-AzDisk | Where-Object { $_.ManagedBy -eq $vmId } | Select-Object -ExpandProperty Id
    
        # Update tags for disks
        foreach ($diskId in $diskIds) {
            Write-Host "Applying tags to Disk: $diskId"
            Update-AzTag -ResourceId $diskId -Tag $vmTags -Operation Merge
        }
    
        # Get the VM's NIC (Network Interface) resource ids
        $nicIds = $vm.NetworkProfile.NetworkInterfaces.Id
    
        # Apply VM Tags to all NICs
        foreach ($nicId in $nicIds) {
            Write-Host "Applying tags to NIC: $nicId"
            Update-AzTag -ResourceId $nicId -Tag $vmTags -Operation Merge
        }
    
        Write-Host "Completed processing VM: $vmName"
    }
    
    
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.