Azure Powershell command cannot find my VM under my resource group? - azure

I'm trying to change the TCP Port timeout on my Ubuntu VM in Azure, and am following this guide to do so, however I seem to get stuck at Step 8 where I have to type the following command:
Get-AzureRmVM -Name "digitron" -ResourceGroup "DIGITRON-RG" |
Get-AzureRmPublicIpAddress
Where it spits back the following error:
Get-AzureRmPublicIpAddress : The Resource 'Microsoft.Network/publicIPAddresses/digitron' under resource group
'DIGITRON-RG' was not found.
StatusCode: 404
ReasonPhrase: Not Found
OperationID : '5031da35-262c-4e1a-a85b-885a6a0fd36c'
At line:1 char:63
+ ... "digitron" -ResourceGroup "DIGITRON-RG" | Get-AzureRmPublicIpAddress
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzureRmPublicIpAddress], NetworkCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Network.GetAzurePublicIpAddressCommand
What's strange here is if I run the command Get-AzureRmVm, the powershell will spit back:
ResourceGroupName Name Location VmSize OsType NIC ProvisioningState
DIGITRON-RG digitron eastus Standard_DS2_v2 Linux digitron727 Succeeded
Now reading the error makes me think that the VM itself has no public IP address, but I've set it in the Azure Portal as seen in this image (where it says 40.71.98.172 etc):
Why is the Powershell giving me this error?

The Resource 'Microsoft.Network/publicIPAddresses/digitron' under
resource group 'DIGITRON-RG' was not found.
Because Get-AzureRmPublicIpAddress can't get the right parameter, this error means the resource can't find in DIGITRON-RG. For test, we can use Get-AzureRmResource to test the resource exist or not:
PS > Get-AzureRmResource | ?{$_.name = "digitron"}
By the way, the command Get-AzureRmPublicIpAddress need parameters: -Name (the name of the public IP address), -ResourceGroupName (the name of the resource group)
PS > Get-AzureRmPublicIpAddress -Name "jason-ip" -ResourceGroupName "jason"
Name : jason-ip
ResourceGroupName : jason
Location : eastus
Id : /subscriptions/5xxxxabb-222b-49c3-9488-0361e29a7b15/resourceGroups/jason/providers/Microsoft.Network/publicIPAddresses/jason-ip
Etag : W/"5a7200b2-7c2b-4c7a-be27-0bbb7c8f4665"
ResourceGuid : 32xxxf-750a-46a4-abda-c25xxx2b64
ProvisioningState : Succeeded
Tags :
PublicIpAllocationMethod : Dynamic
IpAddress : 13.92.255.103
PublicIpAddressVersion : IPv4
IdleTimeoutInMinutes : 30
IpConfiguration : {
"Id": "/subscriptions/5xxxxb-222b-49c3-9xx8-0361e29a7b15/resourceGroups/jason/providers/Microsoft.Network/networkInterfaces/jason647/ipConfigurations/ipconfig1"
}
DnsSettings : null
We can use this command to get the public IP direct, and increase the timrout to 30 minutes.

Below is the script I used to get the Private and Public IP for an Azure ARM VM:
$rg = Get-AzureRmResourceGroup -Name "MyResourceGroup01"
$vm = Get-AzureRmVM -ResourceGroupName $rg.ResourceGroupName -Name "MyVM01"
$nic = Get-AzureRmNetworkInterface -ResourceGroupName $rg.ResourceGroupName -Name $(Split-Path -Leaf $VM.NetworkProfile.NetworkInterfaces[0].Id)
$nic | Get-AzureRmNetworkInterfaceIpConfig | Select-Object Name,PrivateIpAddress,#{'label'='PublicIpAddress';Expression={Set-Variable -name pip -scope Global -value $(Split-Path -leaf $_.PublicIpAddress.Id);$pip}}
(Get-AzureRmPublicIpAddress -ResourceGroupName $rg.ResourceGroupName -Name $pip).IpAddress
#Output:
Name PrivateIpAddress PublicIpAddress
---- ---------------- ---------------
ipconfig1 10.0.0.10 MyVM01-pip
40.80.217.1

Related

I need to Specify OS Disk Name while Creating Azure VMSS using PowerShell

I want to Specify OS Disk Name while Creating VMSS using PowerShell to overcome the random OS Disk name like "VMSSNAME_1686_disk1_b5f021da0ba7409fbe7d028bdd50".
Command :
Set-AzVmssStorageProfile $vmssConfig `
-OsDiskCreateOption "FromImage" `
-ImageReferenceId $galleryImage.Id -OsDiskName $OSDiskName
# Set up information for authenticating with the virtual machine
Set-AzVmssOsProfile $vmssConfig `
-AdminUsername $username `
-AdminPassword $Password `
-ComputerNamePrefix "UKSSPAG"
# Attach the virtual network to the config object
Add-AzVmssNetworkInterfaceConfiguration -VirtualMachineScaleSet $vmssConfig -Name "NICConfig" -Primary $true -IPConfiguration $ipConfig
# Create the scale set with the config object (this step might take a few minutes)
New-AzVmss -ResourceGroupName $resourceGroup -VMScaleSetName $scaleSetName -VirtualMachineScaleSet $vmssConfig
Error :
New-AzVmss : Parameter 'osDisk.name' is not allowed.
ErrorCode: InvalidParameter
ErrorMessage: Parameter 'osDisk.name' is not allowed.
ErrorTarget: osDisk.name
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : e97450a3-ed89-46f8-84fa-6779a002a3e9
At line:1 char:1
+ New-AzVmss -ResourceGroupName $resourceGroup -VMScaleSetName $scaleSe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzVmss], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.Automation.NewAzureRmVmss

Set-AzVMCustomScriptExtension in catch?

Attempting to add an extension when not detected but keep failing to find the secret sauce to get this to work. Mind you I am a BASH guy and this is a first foray into PowerShell..
#requires -version 2
# Required parameter $subscription: name of the subscription to enable Custom Script Extensions in
param (
# NOTE: See below for reason...
# [Parameter(Mandatory = $true)] [String] $subscription
# NOTE: Prompting is great for using the script interactively, but if this will also be executed
# from a build server or ...
# NOTE: Once the parameter is marked as mandatory PowerShell it will prompt for value. That said,
# if you remove the mandatory attribute then you can set a default value as a T_THROW ...
# NOTE: This _does_ contain shortcomings if this will be used as a pipeline param ...
# https://stackoverflow.com/questions/33600279/is-it-possible-to-force-powershell-script-to-throw-if-a-required-pipeline-para
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]$SubscriptionName=$(Throw "`SubscriptionName` is mandatory, please provide a value...")
)
# Connect to the current Azure account
Write-Output "Pulling Azure account credentials..."
Start-Process "https://microsoft.com/devicelogin" # steals focus...
# Login to Azure account
Connect-AzAccount
# Set the active subscription
$null = Get-AzSubscription -SubscriptionName "$SubscriptionName" |Set-AzContext
# TODO: error handling
$vms = Get-AzVM
$cseName = "VulnerabilityManagementTools"
ForEach ($vm in $vms) {
try {
$cseStatus = Get-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroupName `
-VMName $vm.Name `
-Name $cseName `
-Status
}
catch {
Write-Output "Enabling Custom Script Extension for $vm."
Set-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroup `
-Location $vm.Location `
-VMName $vm.Name `
-Name $cseName `
-TypeHandlerVersion "1.1" `
-StorageAccountName "VulnerabilityManagementTools" `
-FileName "VulnerabilityManagementInstaller.ps1" `
-ContainerName "VulnerabilityManagementTools"
}
}
End up err'ing out with
PS /.../automation-scripts> ./EnableCustomScriptExtension.ps1 SubscriptionName
Pulling Azure account credentials...
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXX to authenticate.
Account SubscriptionName TenantId Environment
------- ---------------- -------- -----------
XXXX#analytics.com SubName XXXXXX-XXXX AzureCloud
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{NAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{NAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/XXXXX/extensions/VulnerabilityManagementTools' under resource group '{RESOURCE_GROUPNAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{RESOURCE_GROUPNAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/{VMName}/extensions/VulnerabilityManagementTools' under resource group '{RESOURCEX_GROUPNAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/{VMName}/extensions/VulnerabilityManagementTools' under resource group '{RESOURCEX_GROUPNAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand`
In your case, you just need to use the if(){}else{} statement, try the script as below instead of the ForEach part of yours, it works fine on my side.
ForEach ($vm in $vms) {
$cseStatus = Get-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroupName `
-VMName $vm.Name `
-Name $cseName `
-Status `
-ErrorAction SilentlyContinue
if ($cseStatus){
Write-Host "The extension has been set for" $vm.Name
}else{
Write-Host "Enabling Custom Script Extension for" $vm.Name
Set-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroup `
-Location $vm.Location `
-VMName $vm.Name `
-Name $cseName `
-TypeHandlerVersion "1.1" `
-StorageAccountName "VulnerabilityManagementTools" `
-FileName "VulnerabilityManagementInstaller.ps1" `
-ContainerName "VulnerabilityManagementTools"
}
}
Test result:
You'll need to create an Azure AD Service Principal using password authentication and use the credentials of this to pass to the Connect-AzAccount cmdlet as follows:
$credentials = Get-Credential
Connect-AzAccount -ServicePrincipal -Credentials $credentials
The service account will need to have the necessary permissions to use the Set-AzVMCustomScriptExtensions cmdlet.
More information on creating the service account here:
https://learn.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-2.8.0

Easier way of retrieving an Azure VM's Public IP address

Using the name/resource group of a specific VM, I'm trying to get the VM's public IP address.
This code works but it seems unwieldy in comparison to other AzureRM cmdlets.
$VM = Get-AzureRmVM -ResourceGroupName MyResourceGroup -Name MyVMName
$NIC = $VM.NetworkProfile.NetworkInterfaces[0].Id -replace '.*\/'
$NI = Get-AzureRmNetworkInterface -Name $NIC -ResourceGroupName MyResourceGroup
$NIIC = Get-AzureRmNetworkInterfaceIpConfig -NetworkInterface $NI
$PIP = $NIIC.PublicIpAddress.Id -replace '.*\/'
$PIP = Get-AzureRmPublicIpAddress -Name $PIP -ResourceGroupName MyResourceGroup
$PIP.IpAddress
Is there a quicker/easier/shorter way of accessing this information?
As far as i know, Not Yet for PowerShell. But you can use Azure CLI
az vm list-ip-addresses -n <VMName> -g <ResourceGroup> | grep publicIpAddresses
Try the Azure CLI command:
az vm list-ip-addresses -g groupName -n vmName --query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" -o tsv
Or the PowerShell command just filter with your vm name:
$ipAddress= (Get-AzureRmPublicIpAddress -ResourceGroupName groupName | Where-Object { $_.IpConfiguration.Id -like "*vmName*" }
)
$ipAddress.IpAddress
It's possible. This script will list all VMs PIP in your Azure cloud.
OLD
$VM_int = Get-AzureRmResource -ODataQuery "`$filter=resourcetype 'Microsoft.Compute/virtualMachines'"
foreach($int in $VM_int){
$vmName = $int.Name
$ipAddress= (Get-AzureRmPublicIpAddress -ResourceGroupName $int.ResourceGroupName | Where-Object { $_.IpConfiguration.Id -like "*$vmName*" })
$vmName + ' --- ' + $ipAddress.IpAddress
}
UPDATE
Unfortunately, Get-AzVM doesn't provide the Public IP address of VM, but we can scrape its Network Interface Name and make a wildcard search of it through all assigned Public IPs which NIC name are matched.
It's not fast but will provide with correct results.
$array = #()
foreach ($vm in Get-AzVM) {
$vmNicName = $vm.NetworkProfile.NetworkInterfaces.Id.Split("/")[8]
$ipAddress = Get-AzPublicIpAddress | Where-Object {$_.IpConfiguration.Id -like "*$vmNicName*"}
if ($null -ne $ipAddress) {
$pipInput = New-Object psobject -Property #{
VM = $vm.Name
PublicIP = $ipAddress.IpAddress
}
$array += $pipInput
}
}
The way i got the value for my Linux VM's was using below code.
Get-AzureRmPublicIpAddress -ResourceGroupName <yourRG> -Name <yourVMName> | Select-Object {$_.IpAddress}
This will return something of this sort:
$_.IpAddress
------------
52.170.56.60
This outputs a bit of information however the public IP address is in there.
Get-AzPublicIpAddress -ResourceGroupName MyResourceGroup | Where-Object {$_.name -like "*MyVMName*" }
Or you can do this to just get the IP address:
Get-AzPublicIpAddress -ResourceGroupName MyResourceGroup | Where-Object {$_.name -like "*MyVMName*" } | Select-Object { $_.IpAddress }
Output is like:
$_.IpAddress
--------------
13.255.162.33
You can also match the AzPublicIpAddress IpConfiguration.Id with the VM's NetworkInterfaces.Id:
Get-AzPublicIpAddress | ?{$_.IpConfiguration.Id -match "$((Get-AzVM -Name $computername).NetworkProfile.NetworkInterfaces.Id).*" }
#Get the VM object
$vm = Get-AzVM -Name $vmName -Status
#Get name of network adapter object attached to VM
$NetworkInterfaceName = $vm.NetworkProfile.NetworkInterfaces.Id.Split("/") | Select -Last 1
#Get network adaptor object attached to VM
$NetworkInterfaceObject = Get-AzNetworkInterface -Name $NetworkInterfaceName
#Get public IP Address object name attached to network adaptor object
$ipObjectName = $NetworkInterfaceObject.IpConfigurations.PublicIpAddress.Id.Split("/") | Select -Last 1
#get publivc IP Address attached to public IP Address object
$ipObject = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -Name $ipObjectName
Write-Output $ipObject.IpAddress
Yet another method from within a Linux VM.
First, install the Azure command-line tools in the VM, see Azure docs
Second, execute the following in a shell on the VM:
az network public-ip list --query "[?dnsSettings.domainNameLabel=='MY_VM']"
where MY_VM is (hopefully) the host name of your VM. The command returns a multiline JSON string which is a list. Example is shown below:
[
{
"dnsSettings": {
"domainNameLabel": "MY_VM",
"fqdn": "my_vm.westeurope.cloudapp.azure.com"
},
"etag": "W/\"some_uuid...\"",
...
"ipAddress": "AAA.BBB.CCC.DDD",
},
...
]
How to parse the FQDN and the public IP out of this is left as an exercise to the reader :-)

Get-AzureRmRecoveryServicesBackupContainer : Requested value 'NotRegistered' was not found

I am using below command in Azure Automation Powershell script to get status of Recovery Services container - it simply checks if a VM is registered for backup.
Get-AzureRmRecoveryServicesVault -Name $AzureRecoveryServicesName | Set-AzureRmRecoveryServicesVaultContext
$BackupStatus = Get-AzureRmRecoveryServicesBackupContainer -ContainerType AzureVM -FriendlyName $VirtualMachineName -ResourceGroupName $ResourceGroupName
If a VM is not registered it throws an error and $BackupStatus is empty:
Get-AzureRmRecoveryServicesBackupContainer : Requested value 'NotRegistered' was not found.
At line:53 char:21
... kupStatus = Get-AzureRmRecoveryServicesBackupContainer -ContainerType ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [Get-AzureRmReco...BackupContainer], ArgumentException
FullyQualifiedErrorId :
Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.GetAzureRmRecoveryServicesBackupContainer
And if it is already registered I get $BackupStatus = Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models.AzureVmContainer.
I've tried:
$BackupStatus = (Get-AzureRmRecoveryServicesBackupContainer -ContainerType AzureVM -FriendlyName $VirtualMachineName -ResourceGroupName $ResourceGroupName).Status
But then the only difference is that I get $BackupStatus = Registered when VM is already in a container but same error occurs when VM is not registered.
What is the proper way to check if a VM is registered for backup or not? I am ok with what I'm getting - I can handle $BackupStatus values in a script - but I don't want this error message to show.
Strange thing is that in Powershell on PC with same Azure modules versions loaded (AzureRM​.RecoveryServices​.Backup 2.5.0) as in Automation Account I am getting a different behavior:
PS C:\windows\system32> $BackupStatus = Get-AzureRmRecoveryServicesBackupContainer -ContainerType AzureVM -FriendlyName $VirtualMachineName -ResourceGroupName $ResourceGroupName
PS C:\windows\system32> $BackupStatus
Name ResourceGroupName Status ContainerType
---- ----------------- ------ -------------
UbuntuBckptest rhel68128 Registered AzureVM
It returns an object instead of a string.
If you want to set $BackupStatus value according to Get-AzureRmRecoveryServicesBackupContainer command executed result. We could put the Get-AzureRmRecoveryServicesBackupContainer in try...catch.
The following just the code sample
$BackupStatus;
try
{
$BackupStatus=Get-AzureRmRecoveryServicesBackupContainer
}
catch
{
# we can add condition for example : if($BackupStatus.Contains("NotRegistered"))
$BackupStatus = "NotRegistered"
}
# we can add condition :get the type of $BackupStatus for example :if($BackupStatus.GetType().Name.equals("String"))`
$BackupStatus = "Registered"

Why is the ID for a subnet created using Azure Resource Manager Powershell cmdlets null?

I am trying to provision some network resources in Azure and I am running into a blocker with a step that tries to reference a previously created subnet's Id property.
Here's the command to retrieve the subnet details:
$gwsubnet = Get-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $vnet
And then outputting the value of $gwsubnet in the console:
Name : GatewaySubnet
Id :
Etag :
ProvisioningState :
AddressPrefix : 10.1.1.0/24
IpConfigurations : null
NetworkSecurityGroup : null
RouteTable : null
Note that the Id property is null. This causes an error for a future step, e.g.:
$gwipconfig = New-AzureRmVirtualNetworkGatewayIpConfig -Name config1 -SubnetId $gwsubnet.Id -PublicIpAddressId $gwpip.Id
Gives the following error:
New-AzureRmVirtualNetworkGatewayIpConfig : Cannot validate argument on parameter 'SubnetId'. The argument is null or empty. Supply an argument that is not null or empty and then try the
command again.
At line:1 char:99
+ ... nfig -SubnetId $gwsubnet.Id -PublicIpAddressId $gwpip.Id
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-AzureRmVirtualNetworkGatewayIpConfig], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Azure.Commands.Network.NewAzureVirtualNetworkGatewayIpConfigCommand
I'm struggling with how to have my subnet have an Id assigned to it. Is this something that I need to logout/login again to see? thanks for the help.
The problem you are having is that the subnet Id isn't created until you have created the virtual network.
When you run Get-AzureRmVirtualNetworkSubnetConfig all you create is a configuration to attach to New-AzureRmVirtualNetwork Once you have run that command it will connect to Azure, deploy the Vnet, create the subnet and at that state it will create a subnet Id.
The following code will show you what I mean...
$DNSNameLabel = "mydnsname"
$NetworkName = "MyNet"
$NICName = "MyNIC"
$PublicIPAddressName = "MyPIP"
$SubnetName = "MySubnet"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SingleSubnet = New-AzureRmVirtualNetworkSubnetConfig `
-Name $SubnetName `
-AddressPrefix $SubnetAddressPrefix
#At this point nothing is created, so there is no valid subnet id
$Vnet = New-AzureRmVirtualNetwork -Name $NetworkName `
-ResourceGroupName $ResourceGroupName `
-Location $LocationName `
-AddressPrefix $VnetAddressPrefix `
-Subnet $SingleSubnet
#vnet and subnet are created, both get an id and etag
$vnet = Get-AzureRmVirtualNetwork -Name $NetworkName
-ResourceGroupName $ResourceGroupName
$vnet.Subnets[0].Id
Which will give
/subscriptions/{Subscription ID}/resourceGroups/MyResourceGroup/providers/Microsoft.Network/virtualNetworks/MyNet/subnets/MySubnet

Resources