Azure Resource Tagging - azure

I am looking for a way to create one tag and use it to tag multiple resources. These resources I am tagging are not all in the same resource group / subscription and they are all different types of resources ranging from VMs to App services to Log Analytics Workspaces etc. There are over 3000 resources in total. The ultimate goal is to create a tag for each resource type, and then use powershell to filter by resource type and then send a particular command to each resource type. Below is an example.
VM Resources will get VM-Cleanup-Tag, and then I will run a command that will add that tag to all VM resources that I specify. Then I will run a command to filter by that tag and pipe another command in there such as stop-AzureVM. And then I will do that same thing for many other resource types. Any ideas will be greatly appreciated!

Just use the generic AzResource commands for this purpose
$tags = #{"VM-Cleanup-Tag"="True" ; "ResoucreType" = "VM" ; "etc"="etc"}
Get-AzResource -ResourceType Microsoft.Compute/virtualMachines | Set-AzResource -Tag $tags -Force
Then you can call of of those resources
$VMs_Cleanup = Get-AzResource -Tag #{"VM-Cleanup-Tag" = "True"}
$VMs_Cleanup | Stop-AzVM
or
foreach ($VM in $VMs_Cleanup) {
Stop-AzVM $VM
blah blah
}
Get Tags and append new ones
$tags = #{"VM-Cleanup-Tag"="True" ; "ResoucreType" = "VM" ; "etc"="etc"}
$Resource = Get-AzResource -Name $VMName
$tags.Keys | % {$Resource.Tags.Add($_,$tags.Item($_))}
Set-AzResource $VMName

Related

How to get the Resource Group of a resource in Azure?

I have resources in a Resource Group in Azure and it wont let me move the resource because it is in a Resource Group that is not the hosting Resource Group even though it has been moved .
I have tried to run the command in Powershell az resource list but cant seem to see the hosting Resource Group of the resource.
Is there a command I can run in Powershell that will give the current Resource Group of the resource and the hosting Resource Group of the resource?
Is there a Powershell command that will give the current Resource Group of the resource?
Yes its the Get-AzureRmResource command:
$resourceId = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}"
$resource = Get-AzureRmResource -ResourceId $resourceId
$resourceGroupName = $resource.ResourceGroupName
Fortunately there's an alternative to avoid specifying the "ResourceGroupName" which you're trying to find and that's specifying the ResourceType..
$resourceGroupName = Get-AzureRmResource -ResourceName {resourceName} -ResourceType {resourceType} | Select-Object -ExpandProperty ResourceGroupName
Also note the -ExpandProperties parameter in the documentation to include the resource properties.
Based on the shared information, I have understood that you want to know the
hosted resource group(in which resource group got created before move operation).
current resource group (currently where the resource resides in).
We don't have any direct cmdlets to pull this information.
You can make use of activity logs to see the resource move operation and pull the information of resources which were moved & respective target resource group names accordingly using the below cmdlet
Get-AzActivityLog -StartTime (get-date).AddDays(-90) -EndTime (get-date)| Where-Object {$_.Authorization.Action -like "Microsoft.Resources/subscriptions/resourceGroups/moveresources/action" -and $_.OperationName -like "Move Resource Group Resources" -and $_.EventName -like "Begin request" } | Select -ExpandProperty Properties
Sample screenshot for your reference:
Note: Using Get-AzActivityLog cmdlet you can pull logs for only last 90days.

Azure apply multiple tags to all resources under a specific Resource Group

I am trying to find out if its possible to apply multiple tags to all of the resources under a specific Resource Group in Azure. I don't know if this is possible because right now I am doing it manually via the Azure Portal but since our resources exploded I can't do it manually any more.
One of the workaround is that you can add multiple tags to all the resources in you Resource Group through Powershell using New-AzTag. Below is the command that worked for me.
$tags = #{"<Tag1Name>"="<Value1>"; "<Tag2Name>"="<Value2>"}
$rs = get-azresource -ResourceGroup <Your_Resource_Group>
foreach($r in $rs){
New-AzTag -ResourceId $r.ResourceId -Tag $tags
}
In case if you are updating the Tag you can follow the answer suggested by Stanley Gong - Update Azure resource tags for multiple resources - Stack Overflow
$rs = get-azresource -TagName Environment
foreach($r in $rs){
if($r.Tags.Environment -eq 'Non-Prodd'){
$r.Tags.Environment = "Non-Prod"
Set-AzResource -ResourceId $r.ResourceId -Tag $r.Tags -Force
}
}
This can be also done in Azure CLI using az tag create apart from using Azure portal and powershell.
REFERENCES: Tag resources - Microsoft Docs

Automation to delete unused VMs and their resources in Azure by last power on date

I need to create an automation that will delete VMs that were not started in the last two weeks and their associated resources (for example a Network interface or a Disk etc..) inside a single resource group. I thought about using a Powershell runbook in an automation account but I have some problems with that, I couldn't find a Powershell command to check last start date of all VMs in a resource group or a Powershell command to delete a VM and all its' associated resources.
If I had these two I could make a Powershell runbook that will check last start time of a VM and if the date exceeds two weeks it'd automatically delete it and its' associated resources.
Anyone knows how to accomplish these two things or maybe knows a different way to do this?
there is no easy way to do that (so no cmdlet that would do either of things you require). You'd need to script those 2 operations.
You'd probably need to use Get-AzVm and parse the output to figure out when was it powered on (not sure this is even exposed in the api) along with something like this https://adamtheautomator.com/remove-azure-virtual-machine-powershell/
I went through some searching on this and ended up creating this script that does the job:
$rgName = "resource group name"
$VMs = Get-AzVM -ResourceGroupName $rgName | ? {$_.Tags.Keys -notcontains "DontDelete"}
#$VMs = $VMs | ? {$_.Name -eq 'ePO'}
foreach ($VM in $VMs)
{
$vmName = $VM.Name
$vmID = $VM.Id
Get-AzVM -VMName $vmName | Stop-AzVM -Force
####################################################################################
$nicID = $VM.NetworkProfile.NetworkInterfaces.id
####################################################################################
$diskID = $VM.StorageProfile.OsDisk.ManagedDisk.Id
$snapshotConfig = New-AzSnapshotConfig -SourceUri $diskID -Location $VM.Location -CreateOption copy
$snapshot = New-AzSnapshot -Snapshot $snapshotConfig -SnapshotName "$vmName-snapshot" -ResourceGroupName $VM.ResourceGroupName
####################################################################################
Remove-AzResource -ResourceId $vmID -Force
Remove-AzResource -ResourceId $nicID -Force
Remove-AzResource -ResourceId $diskID -Force
}
Decided that instead of last powered on date I'll use a "DontDelete" tag for the VMs I don't want to delete and the rest will be deleted as well as their associated resources.
I added this script to a runbook in an automation account and ran it and it works perfectly.

How to get the NIC details for Application Security Group / Resource Group

I'm looking a PowerShell command which is used to list out the relationship between the network interface card and its associated application security group / resources group. I use the following commands and it only displays the VMName, IPAddress. The Application Security Group cannot be shown up.
I already use -ExpandProperty ApplicationSecurityGroups but still doesn't work.
$nics =Get-AzureRmNetworkInterface -ResourceGroupName "My-RG"
foreach($nic in $nics)
{
$vm = $vms | where-object -Property Id -EQ $nic.VirtualMachine.id
$Name = $nic.Name
$prv = $nic.IpConfigurations | select-object -ExpandProperty PrivateIpAddress
$alloc = $nic.IpConfigurations | select-object -ExpandProperty PrivateIpAllocationMethod
$asc = $nic.IpConfigurations | select-object -ExpandProperty ApplicationSecurityGroups
Write-Output "$Name, $prv , $asc"
}
It is quite hard to retrospectively query members of an ASG, the property is contained in arrays within arrays in the NIC configuration. I found an AZ cli command to retrieve this, hope it saves some time.
az network nic list --query '[].{Name:name,ASG:ipConfigurations[0].applicationSecurityGroups[].id}'
I've just tested your commands and I can get the application security group successfully, from a machine that is configured with an ASG. However, that will only work if you have put the VM in an ASG, ASG's are there to provide micro-segmentation inside a subnet, so you can group your app servers, DBs etc. together and apply NSG rules to groups rather than single servers.
If instead, you want to know what NSG the VM is in, you need a different command. NSG's are the resource that attaches to a VM or NIC and acts like a firewall. If you want that then you need to run:
$nsg = $nic | select-object -ExpandProperty NetworkSecurityGroup
However, this is only going to get you the NSG applied to the VM, you can also apply these at the VM level, so you are better running this command:
$effectiveRules=Get-AzureRmEffectiveNetworkSecurityGroup -NetworkInterfaceName <nicName> -ResourceGroupName <resourceGroup>
$effectiveRules.NetworSecurityGroup
This will list all NSGs applied either at NIC or Subnet level.
The thing is that you can only get the ASG information from property IpConfigurationsText as a string, so you'll need to update your query to this:
$nics = Get-AzureRmNetworkInterface -ResourceGroupName "My-RG"
foreach($nic in $nics)
{
$GetAzureNIC = Get-AzureRmNetworkInterface -ResourceGroupName "My-RG" -Name $nic.Name
$Name = $nic.Name
$prv = $nic.IpConfigurations.PrivateIpAddress
$alloc = $nic.IpConfigurations.PrivateIpAllocationMethod
$asgResourceID = ($GetAzureNIC.IpConfigurationsText | ConvertFrom-Json).ApplicationSecurityGroups.Id
$asgName = (Get-AzureRmResource -ResourceId $asgResourceID).Name
Write-Output "$Name, $prv, $alloc, $asgName, $asgResourceID"
}
EDIT: I've noticed that you also want to get the allocation method but don't use it in the Write-Output and updated the query to include both ASG name and ASG resource ID, pick whichever you need.

Get private IP of VM in Azure Dev Test Lab using Powershell

Just now I started with Azure DevTest Lab. I created a VM in lab using a json template. I want to use the public IP of the VM using powershell or may be I would like to return the same using template, if I can.
The challenge here is as per DTL concept the VM is created in a new resource group other than the one where your lab exists. I can definitely see the name of resource group of lab VM on portal but I am not able to figure out how this can be done using powershell. I am working on an automation so I need to do it by powershell.
Refer to the picture. The lab seems to be in a resource group in the same where the lab exist shown in green box. But, technically the lab VM resides in dynamically created resource gruop (RG name pattern = labname + VM name + Some Random digits) shown in light yellow in screenshot.
Other solutions are helpful but not complete. I am doing in this way - I am returning the default output of template that is vmId. Refer from template link
Now we need to manipulate this vmId to get the name of resource group where the lab VM has been created.
$result = New-AzureRmResourceGroupDeployment -ResourceGroupName "aatifdtlrg207912" -TemplateFile "D:\AzureDeploy.json" -TemplateParameterObject $paramValues
$VMId = $result.outputs.Values.value
$VMComputeId = (Get-AzureRmResource -Id $VMId).Properties.ComputeId
$RGNameofVM = $VMComputeId.split("/")
$RGNameofVM = $RGNameofVM[4]
$IP = (Get-AzureRmNetworkInterface -Name $VMName -ResourceGroupName $RGNameofVM ).IpConfigurations.PrivateIpAddress
Well, generally a more elegant solution, oposed to bruteforce would be to use Get-AzureRmResource
$Resource = Get-AzureRmResource -ResourceId "/subscriptions/$sub_GUID/resourcegroups/$RG_devlab_Name/providers/microsoft.devtestlab/labs/$LabName/virtualmachines/$VMName"
$Resource.Properties.computeId -match 'resourceGroups/(.+)/providers'
$RGName = $Matches[1]
$IP = (Get-AzureRmNetworkInterface -Name $VMName-ResourceGroupName $RGName).IpConfigurations.PrivateIpAddress
Well, as we know for DevTest Labs there is no direct way for powershell. You can use the below powershell script to get the Private IP Address of the VM by just passing the Virtual machine name. We can use Find-AzureRmResource and Get-AzureRmResource by passing the ResourceId:
$vmNicdetails = Find-AzureRmResource -ResourceNameContains mytestVM | Where {$_.ResourceType -eq 'Microsoft.Network/networkInterfaces'}
$nicdetails = Get-AzureRmResource -ResourceId $vmNicdetails.ResourceId
$ipconfig = Get-AzureRmResource -ResourceId
$nicdetails.Properties.ipConfigurations.id -ApiVersion '2017-03-01'
$ipconfig.Properties.privateIPAddress

Resources