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
Related
Just wondering how to retrieve the VMs details in a given particular subnet in Azure.
I have used the below but it does not work anymore in powershell (Cloud shell)
Listing all azure vm belonging to particular subnet
Any help will be appreciated.
Thanks
The following code snippet has been tested against my environment :
$vms = Get-AzVM
$tgtSubnet = "MySubnet"
foreach($vm in $vms)
{
$networkInterface = Get-AzNetworkInterface -Name ($vm.NetworkProfile.NetworkInterfaces[0].Id.Split('/')[-1])
$subnetName = $networkInterface.IpConfigurations[0].Subnet.Id.split('/')[-1]
if($subnetName -eq $tgtSubnet)
{
Write-Output $vm
}
}
output:
Make sure Azure PowerShell is installed on your machine.
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.
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
I am trying to obtain IP addresses for all my virtual machines within my azure subscription. While I get the IP addresses of all my NICs, I can't seem to get them for my VMs. I am using AzureRm and powershell to obtain this information.
How do I obtain IP addresses of all my VMs within Azure using AzureRm?
You can use Azure PowerShell to get all the VM Public IPs, but there is something you should pay attention to.
The VM can be associated with more than one network interface and each network interface can also associate with a public Ip.
I assume that your VMs in the same resource group and each VM just have one network interface. Then the PowerShell script will like this:
$vms = Get-AzureRmVM -ResourceGroupName yourRGName
foreach ($vm in $vms)
{
$vmName = $vm.Name
$nic = $vm.NetworkProfile.NetworkInterfaces[0].Id.Split('/') | select -Last 1
if ( (Get-AzureRmNetworkInterface -ResourceGroupName yourRGName -Name $nic).IpConfigurations.PublicIpAddress -eq $null )
{
continue
}
$publicIpName = (Get-AzureRmNetworkInterface -ResourceGroupName yourRGName -Name $nic).IpConfigurations.PublicIpAddress.Id.Split('/') | select -Last 1
$publicIpAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName yourRGName -Name $publicIpName).IpAddress
Write-Output $vmName $publicIpAddress
}
The result will like this:
If your VMs in the different resource groups, you can first get the VMs information and then everything is on the way. If there just exist your VMs in subscription, you can get all the VMs with the PowerShell command Get-azureRMVM when you log in the subscription. But if they're not just your VMs in the subscription, I think you'd better get all your VMs through resource groups. Hope this will help you.
Because IP addresses in ARM are assigned to NICs not VM. You will have write a script to look at NICs assigned to VMs and look for IPs on those NICs.
You may refer the following steps to get all the public IP addresses in a Azure Subscription.
Gets all the public IP addresses in a subscription.
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Network/publicIPAddresses?api-version=2018-08-01
Click on Try it
=> Sign in => Pick an Azure account => Select subscription Id => Run
Check out the Public IP addresses in the subscription:
Note: Only running VMs will have public IP address.
For more details, refer "Public IP Address - List All".
Hope this helps.
Riffing on Charles Xu's excellent answer....
Converted to use the new 'Az' powershell module
foreach ($vm in $vms)
{
$vmName = $vm.Name
$resgrpName = $vm.ResourceGroupName
$nic = $vm.NetworkProfile.NetworkInterfaces[0].Id.Split('/') | select -Last 1
if ( (Get-AzNetworkInterface -ResourceGroupName $resgrpName -Name $nic).IpConfigurations.PublicIpAddress -eq $null )
{
continue
}
$publicIpName = (Get-AzNetworkInterface -ResourceGroupName $resgrpName -Name $nic).IpConfigurations.PublicIpAddress.Id.Split('/') | select -Last 1
$publicIpAddress = (Get-AzPublicIpAddress -ResourceGroupName $resgrpName -Name $publicIpName).IpAddress
Write-Output $vmName $publicIpAddress
}
It's wicked-slow, but does the job!
In AWS we have instance IDs to identify machines. What's the equivalent in Azure and how do I find that?
I'd like to list the instance ID in powershell so I can put that into a script.
If I have not misunderstood, I suppose you want to get the InstanceId of the VM in the Azure VM Scale set.
You could try to use Get-AzureRmVmssVM to get it.
Get-AzureRmVmssVM -ResourceGroupName <ResourceGroupName> -VMScaleSetName <VMScaleSetName>
Update:
If you want to get the ResourceId of azure resource, you could use Get-AzureRmResource to do it, just specify the properties what you want.
For example:
1.Get ResourceId of the specific resource:
$resource = Get-AzureRmResource -ResourceGroupName <ResourceGroupName> -ResourceType <ResourceType> -ResourceName <ResourceName>
$resource.ResourceId
2.Get ResourceIds of all resources in the specific resource group
$resource = Get-AzureRmResource -ResourceGroupName <ResourceGroupName>
$resource.ResourceId
3.Get ResourceIds of all resources under your subscription.
$resource = Get-AzureRmResource
$resource.ResourceId
The result will like(actual result will decided by your properties):