Functions/Public/Invoke-AzureRemoteDesktop.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
function Invoke-AzureRemoteDesktop {
    <#
    .Author
    Trevor Sullivan <pcgeek86@gmail.com>

    .Description
    Invoke a RDP session to an Azure Virtual Machine, without having to type the
    Cloud Service name or Virtual Machine name. Instead, simply select it from the
    WPF window that pops open. This command is intended to work with the Azure
    Service Management (ASM) PowerShell module, not Azure Resource Manager (ARM).

    .Outputs
    None

    .Links
    http://trevorsullivan.net
    http://twitter.com/pcgeek86
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false, ParameterSetName = 'SpecifiedName')]
        [switch] $PromptSubscription
      , [Parameter(Position = 0, Mandatory = $false, ParameterSetName = 'SpecifiedName')]
        [Alias('svc')]
        [string] $ServiceName
      , [Parameter(Position = 1, Mandatory = $false, ParameterSetName = 'SpecifiedName')]
        [string] $Name
      , [Parameter(Position = 2, Mandatory = $false, ParameterSetName = 'SpecifiedName')]
        [Alias('sn')]
        [string] $SubscriptionName
    )

    function Wait-AzureVM {
        param (
            [Parameter(Mandatory = $true)]
            [string] $ServiceName
          , [Parameter(Mandatory = $true)]
            [string] $Name
          , [int] $WaitInSeconds = 10
          , [string] $State = 'ReadyRole'
        )
        
        while (($VM = Get-AzureVM -ServiceName $ServiceName -Name $Name).Status -ne $State) {
            Start-Sleep -Seconds $WaitInSeconds;
            Write-Verbose -Message ('Virtual machine state {0}/{1} is {2}' -f $ServiceName, $Name, $VM.Status);
            $UserResult = $null;
            $UserResult = @('Yes', 'No') | Out-GridView -Title ('Keep waiting for {0} seconds?' -f $WaitInSeconds) -OutputMode Single;
            if (!$UserResult -or $UserResult -eq 'No') {
                throw 'User canceled waiting for VM to start up.';
                return $false;
            }
        }
        Write-Verbose -Message ('Virtual machine {0}/{1} is up and running' -f $ServiceName, $Name);
        return $true;
    }

    function PromptSubscription {
        Write-Verbose -Message 'Prompting for Azure subscription.';
        $SubscriptionList = Get-AzureSubscription;
        if (!$SubscriptionList) {
            & $AzureReauthenticate;
        }

        $Subscription = $SubscriptionList | Select-Object -Property SubscriptionName,SubscriptionId | Out-GridView -PassThru -Title 'Select your Azure Subscription';
        if (!$Subscription) {
            Write-Warning -Message 'No Azure subscription was selected.';
            return; 
        }
        Select-AzureSubscription -SubscriptionName $Subscription.SubscriptionName;
    }

    $AzureReauthenticate = {
        $AuthResult = Add-AzureAccount 3>&1;

        if ($AuthResult -match 'User canceled authentication') {
            Write-Error -Message 'User canceled authentication, exiting function.';
            return;
        }

        # Re-invoke the azrdp function using the same arguments that the user passed in originally
        $Parameters = (Get-PSCallStack)[1].InvocationInfo.BoundParameters;
        & $PSCmdlet.MyInvocation.MyCommand.Name @Parameters;
    }

    try {
        if ($PromptSubscription) {
            PromptSubscription;
        }

        $VM = Get-AzureVM -ErrorAction Stop | Out-GridView -PassThru -Title 'Select your Azure Virtual Machine';

        if (!$VM) { 
            Write-Warning -Message 'No virtual machines exist in this subscription, or no virtual machine was selected. Please create a virtual machine or select a different Azure subscription';
            return; 
        }
        if ($VM.Status -ne 'ReadyRole') {
            Write-Warning -Message 'The selected Azure virtual machine is not in the ReadyRole state.';
            $OperationList = @(
                [PSCustomObject]@{ Name = 'Start'; Description = 'Start the Microsoft Azure Virtual Machine'; };
                [PSCustomObject]@{ Name = 'Select New'; Description = 'Select a new Microsoft Azure Virtual Machine'; };
                [PSCustomObject]@{ Name = 'Exit'; Description = 'Quit / exit this function'; };
                );
            $Operation = $OperationList | Out-GridView -OutputMode Single;
            if ($Operation.Name -eq 'Start') {
                ### Start the VM using Azure Resource Manager (ARM) instead of Service Management,
                ### if the VM is an IaaSv2 VM.
                if ($VM.ResourceGroupName -and $VM.Name) {
                    Start-AzureVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name; } 
                elseif ($VM.ServiceName -and $VM.Name) {
                    Start-AzureVM -ServiceName $VM.ServiceName -Name $VM.Name; }


                if (Wait-AzureVM -ServiceName $VM.ServiceName -Name $VM.Name) {
                    Get-AzureRemoteDesktopFile -ServiceName $VM.ServiceName -Name $VM.Name -Launch;
                }
                return;
            }
            elseif ($Operation.Name -eq 'Exit') {
                Write-Warning -Message 'User elected to quit the function.';
                return;
            }
            elseif ($Operation.Name -eq 'Select New') {
                & $PSCmdlet.MyInvocation.MyCommand.Name @PSBoundParameters;
                return;
            }
        }

        Write-Verbose -Message ('Invoking Remote Desktop session to {0}\{1}' -f $VM.ServiceName, $VM.Name);
        Get-AzureRemoteDesktopFile -ServiceName $VM.ServiceName -Name $VM.Name -Launch;
    }
    catch [System.ArgumentException] {
        if ($PSItem.Exception.Message -match 'Add-AzureAccount') {
            & $AzureReauthenticate;
        }
    }
    catch [System.ApplicationException] {
        if ($PSItem.Exception.Message -match 'No default subscription') {
            & $AzureReauthenticate;
        }
    }
}