Retieve Azure VM public ip and establish the RDP session through PowerShell

I don’t know for some reason Microsoft doesn’t provide some solutions directly, directly as in cannot achieve the outcome with a single command in PowerShell, for example to get the public ip address of an Azure VM, in fact I expected it to be as simple as this…


Get-AzureRmPublicIpAddress -ResourceGroupName lab-rg -Name Workstation

However there is no such command with those parameters, but still it’s not very complicated. I have written a small PowerShell wrapper to retrieve the public ip address of Azure VM and added few more functionalities as well apart from getting only the public ip address it will start the VM if it is not running by enabling the ‘-StartIfVMIsNotRunning’ flag and connect to RDP session with ‘-ConnectRDP’ flag.

Note: Most of the organizations use either private ip or dns name to connect to the VM from their network, and this is only useful for small businesses or where there is no need of domain authentication and access from outside the local network.

The script has two parameter sets ‘Name’ and ‘Object’, which accepts ResourceGroupName and VMName or VMObject along with the other common parameters, and the parameters are as below…


[Parameter(Mandatory=$true,ParameterSetName='Name')]
[string] $ResourceGroupName, # ResourceGroup Name when the ParameterSetName is 'Name'
[Parameter(Mandatory=$true,ParameterSetName='Name')]
[string] $VMName, # Virtual Machine Name when the ParameterSetName is 'Name'
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName='Object')]
[Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine]
$VMObject, # VM Object when the ParameterSetName is 'Object'
[Parameter(Mandatory=$false,ParameterSetName='Name')]
[Parameter(Mandatory=$false,ParameterSetName='Object')]
[switch] $StartIfVMIsNotRunning, # Start the VM, if it is not running
[Parameter(Mandatory=$false,ParameterSetName='Name')]
[Parameter(Mandatory=$false,ParameterSetName='Object')]
[switch] $ConnetRDP, # Connect Remote Desktop Session
[Parameter(Mandatory=$true,ParameterSetName='Help')]
[switch] $H # Get Help

Since the latest AzureRM (6.13.1) PowerShell module has some significant changes in the outcome of some CmdLets, ensuring the latest module is loaded…

# Ensure the 6.13.1 version AzureRM module is loaded,
# because some commands output have been changed in this version
[System.Version] $RequiredModuleVersion = '6.13.1'
[System.Version] $ModuleVersion = (Get-Module -Name AzureRM).Version
if ($ModuleVersion -lt $RequiredModuleVersion)
{
Write-Verbose -Message "Import latest AzureRM module"
break
}

Login into Azure account, if not logged in already…


# Login in into the Azure account, if it is not already logged in
if([string]::IsNullOrEmpty($(Get-AzureRmContext)))
{
$null = Add-AzureRmAccount
}

Retrieve the VM running state and ensure it is running, if ‘-StartIfVMIsNotRunning’ flag is enabled then the VM will be started if it is not running. If VM is not running and ‘PublicIPAllocationMethod’ is set to static then still public ip can be retrieved, but if it is dynamic then the VM should be in running state itself…


# Retrieve the virtual machine running status
try
{
if ($PSCmdlet.ParameterSetName -eq 'Name')
{
[Microsoft.Azure.Commands.Compute.Models.PSVirtualMachineInstanceView] $VM = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName -Status
}
elseif ($PSCmdlet.ParameterSetName -eq 'Object')
{
[Microsoft.Azure.Commands.Compute.Models.PSVirtualMachineInstanceView] $VM = Get-AzureRmVM -ResourceGroupName $VMObject.ResourceGroupName -Name $VMObject.Name -Status
}
}
catch
{
Write-Verbose -Message $_.Exception.Message
break
}

# Check whether the vm PowerState is running
[Microsoft.Azure.Management.Compute.Models.InstanceViewStatus] $VMStatus = $VM.Statuses | Where-Object { $_.Code -match 'running' }
if ([string]::IsNullOrEmpty($VMStatus))
{
[bool] $ISVMRunning = $false } else { [bool] $ISVMRunning = $true
}

# If VM is not running and -StartIfVMIsNotRunning flag is enabled, then start the VM
if ($ISVMRunning -eq $false -and $StartIfVMIsNotRunning -eq $true)
{
$null = Start-AzureRMVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name
$ISVmRunning = $true
}

Now retrieve the public ip address of an Azure VM…


# Get Public IP address
[Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine] $VirtualMachine = Get-AzureRMVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name
[string] $NICId = $VirtualMachine.NetworkProfile.NetworkInterfaces.id
[Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResource] $NICResource = Get-AzureRmResource -ResourceId $NICId
[string] $PIPId = $NICResource.Properties.ipConfigurations.properties.publicIPAddress.id
[Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResource] $PIPResource = Get-AzureRmResource -ResourceId $PIPId
[ipaddress] $PIP = $PIPResource.Properties.ipAddress

Exit the script if the VM is not running and PublicIPAllocationMethod is Dynamic or public ip is not assigned…


# Exit the script if the VM is not running and PublicIPAllocationMethod is Dynamic or public ip is not assigned
[string] $PublicIPAllocationMethod = $PIPResource.Properties.publicIPAllocationMethod
if ([string]::IsNullOrEmpty($PIP.IPAddressToString) -and $ISVMRunning -eq $false -and $PublicIPAllocationMethod -eq 'Dynamic')
{
Write-Verbose -Message $("Since {0} VM is not running and 'Public IP Allocation Method is Dynamic', unable to determine the Public IP.`nRun the command with -StartIfVMIsNotRunning flag" -f $VMName)
break
}
elseif ([string]::IsNullOrEmpty($PIP.IPAddressToString) -and $ISVMRunning -eq $true)
{
Write-Verbose -Message $("No public ip id assigned to this {0} VM." -f $VMName)
break
}

If the ‘-ConnectRDP’ flag is enabled then the remote desktop connection will be established (only when the default port for RDP is allowed in the inbound security rules) otherwise it simply returns the public ip address…


# Connect the VM when -ConnectRDP flag is enabled and VM is running
if ($ConnetRDP -and $ISVMRunning)
{
Invoke-Expression "mstsc.exe /v $($PIP.IPAddressToString)"
break
}

# Just return the IP address when no flags are enabled
return, $PIP.IPAddressToString

And lets see some examples…


.EXAMPLE

C:\GitRepo> .\Get-ARMVMPIP.ps1 -ResourceGroupName lab-rg -Name Workstation
xxx.xxx.xxx.xxx

Returns the public ip address when the VM is running or the VM is deallocated but the publicIPAllocationMethod is set to 'Static'.

.EXAMPLE

C:\GitRepo> $VM = Get-AzureRmVM -ResourceGroupName lab-rg -Name Workstation
C:\GitRepo> $VM | .\Get-ARMVMPIP.ps1
xxx.xxx.xxx.xxx

Returns the public ip address when the VM is running or the VM is deallocated but the publicIPAllocationMethod is set to 'Static'.

.EXAMPLE

C:\GitRepo> .\Get-ARMVMPIP.ps1 -ResourceGroupName lab-rg -Name Workstation -StartIfVMIsNotRunning
xxx.xxx.xxx.xxx

Returns the public ip address when the VM is running or starts the VM if it is not running and returns the public ip.

.EXAMPLE

C:\GitRepo> .\Get-ARMVMPIP.ps1 -ResourceGroupName lab-rg -Name Workstation -ConnectRDP

# Doesn't return any output simply connects to RDP session

Connect to RDP session when the VM is running

.EXAMPLE

C:\GitRepo> .\Get-ARMVMPIP.ps1 -ResourceGroupName lab-rg -Name Workstation -ConnectRDP

# Doesn't return any output simply connects to RDP session

Connect to RDP session when the VM is running and if the VM is not running it will start and establish the RDP session.

The complete code is available in my git repository https://github.com/kpatnayakuni/PowerShell/blob/master/Get-ARMVMPIP.ps1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s