﻿#region JEA config
$JEAHost = 'HV16-01'
$JEAEndpoint = 'JEA-HV-VM-Admins'
#$JEACredential = Get-Credential -ErrorAction SilentlyContinue

#endregion


#region XAML window definition
# Right-click XAML and choose WPF/Edit... to edit WPF Design
# in your favorite WPF editing tool
$xaml = @'
<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   MinWidth="200"
   Width ="500"
   SizeToContent="WidthAndHeight"
   Title="VM State Management JEA Edition"
   Topmost="True">
   <Grid Margin="10,40,10,10">
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
        <TextBlock Grid.Column="1" Margin="10">Select VM:</TextBlock>

      <TextBlock Grid.Column="0" Grid.Row="1" Margin="5">Running VMs</TextBlock>
      <ComboBox Name="ComboVMRunning" Grid.Column="1" Grid.Row="1" Margin="5"></ComboBox>
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0" Grid.Row="1" Grid.Column="2">
      <Button Name="ButStopVMRunning" MinWidth="80" Height="22" Margin="5">Stop VM</Button>
      <Button Name="ButPauseVM" MinWidth="80" Height="22" Margin="5">Pause VM</Button>
      </StackPanel>
      
      <TextBlock Grid.Column="0" Grid.Row="2" Margin="5">Stopped VMs</TextBlock>
      <ComboBox Name="ComboVMStopped" Grid.Column="1" Grid.Row="2" Margin="5"></ComboBox>
      <Button Name="ButStartVM" Grid.Column="2" Grid.Row="2" MinWidth="80" Height="22" Margin="5">Start VM</Button>
      
      <TextBlock Grid.Column="0" Grid.Row="3" Margin="5">Paused VMs</TextBlock>
      <ComboBox Name="ComboVMPaused" Grid.Column="1" Grid.Row="3" Margin="5"></ComboBox>
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0" Grid.Row="3" Grid.Column="2">
      <Button Name="ButStopVMPaused" MinWidth="80" Height="22" Margin="5">Stop VM</Button>
      <Button Name="ButResumeVM" Grid.Column="2" Grid.Row="3" MinWidth="80" Height="22" Margin="5">Resume VM</Button>
      </StackPanel>
        
      <Button Name="ButCancel" Grid.Row="5" Grid.ColumnSpan="3" MinWidth="80" Height="22" Margin="5">Cancel</Button>
      
   </Grid>
</Window>
'@

function Convert-XAMLtoWindow
{
   param
   (
    [Parameter(Mandatory)]
    [string]
    $XAML,

    [string[]]
    $NamedElement=$null,

    [switch]
    $PassThru
   )

   Add-Type -AssemblyName PresentationFramework

   $reader = [XML.XMLReader]::Create([System.IO.StringReader]$XAML)
   $result = [Windows.Markup.XAMLReader]::Load($reader)
   foreach($Name in $NamedElement)
   {
    $result | Add-Member NoteProperty -Name $Name -Value $result.FindName($Name) -Force
   }

   if ($PassThru)
   {
    $result
   }
   else
   {
    $null = $window.Dispatcher.InvokeAsync{
      $result = $window.ShowDialog()
      Set-Variable -Name result -Value $result -Scope 1
    }.Wait()
    $result
   }
}


function Show-WPFWindow
{
   param
   (
    [Parameter(Mandatory)]
    [Windows.Window]
    $Window
   )

   $result = $null
   $null = $window.Dispatcher.InvokeAsync{
    $result = $window.ShowDialog()
    Set-Variable -Name result -Value $result -Scope 1
   }.Wait()
   #$result
}

function Set-VMCombos
{
   # get all VMs as this might take some time
   $VMs = (Get-JEAVM)
   # get the VMs of selected status, put them into an array explicitly (as there might only be one)
   $window.ComboVMRunning.ItemsSource = @($VMs | Where-Object State -eq 'Running' | Sort-Object -Property VMName)
   # tell the combobox to use the property "VMName" to display the object in its list
   $window.ComboVMRunning.DisplayMemberPath = 'VMName'
   # tell the combobox to preselect the first element
   $window.ComboVMRunning.SelectedIndex = 0

   $window.ComboVMStopped.ItemsSource = @($VMs | Where-Object State -eq 'Off' | Sort-Object -Property VMName)
   $window.ComboVMStopped.DisplayMemberPath = 'VMName'
   $window.ComboVMStopped.SelectedIndex = 0

   $window.ComboVMPaused.ItemsSource = @($VMs | Where-Object State -eq 'Paused' | Sort-Object -Property VMName)
   $window.ComboVMPaused.DisplayMemberPath = 'VMName'
   $window.ComboVMPaused.SelectedIndex = 0
}

# create JEA session and import JEA commands
$JEASession = New-PSSession -ComputerName $JEAHost -ConfigurationName $JEAEndpoint -Credential $JEACredential -ErrorAction SilentlyContinue
if ($JEASession -eq $null) {
  'Session setup failed. Exiting script.'
  Return
}
# Get a list of all the commands on the JEA endpoint
$commands = Invoke-Command -Session $jeasession -ScriptBlock { Get-Command }

# Filter out the default cmdlets
$jeaDefaultCmdlets = 'Clear-Host', 'Exit-PSSession', 'Get-Command', 'Get-FormatData', 'Get-Help', 'Measure-Object', 'Out-Default', 'Select-Object'
$filteredCommands = $commands.Name | Where-Object { $jeaDefaultCmdlets -notcontains $_ }

# Import only commands explicitly added in role capabilities and prefix each imported cmdlet with "JEA"
Import-PSSession -Session $jeasession -Prefix 'JEA' -CommandName $filteredCommands


$window = Convert-XAMLtoWindow -XAML $xaml -NamedElement 'ButCancel', 'ButPauseVM', 'ButResumeVM', 'ButStartVM', 'ButStopVMPaused', 'ButStopVMRunning', 'ComboVMPaused', 'ComboVMRunning', 'ComboVMStopped' -PassThru

# add click handlers
$window.ButStopVMRunning.add_Click{
   # when clicked, take the selected item from the combo box and stop the VM
   $window.ComboVMRunning.SelectedItem.VMName | Stop-JEAVM -Force
   # update the combo box 
   Set-VMCombos
}

$window.ButStopVMPaused.add_Click{
   # when clicked, take the selected item from the combo box and stop the VM
   $window.ComboVMPaused.SelectedItem.VMName | Stop-JEAVM -Force
   # update the combo box 
   Set-VMCombos
}

$window.ButPauseVM.add_Click{
   # when clicked, take the selected item from the combo box and suspend the VM
   $window.ComboVMRunning.SelectedItem.VMName | Suspend-JEAVM
   # update the combo box 
   Set-VMCombos
}

$window.ButResumeVM.add_Click{
   # when clicked, take the selected item from the combo box and resume the VM
   $window.ComboVMPaused.SelectedItem.VMName | Resume-JEAVM
   # update the combo box 
   Set-VMCombos
}

$window.ButStartVM.add_Click{
   # when clicked, take the selected item from the combo box and start the VM
   $window.ComboVMStopped.SelectedItem.VMName | Start-JEAVM
   # update the combo box 
   Set-VMCombos
}


$window.ButCancel.add_Click{
   # close window
   Remove-PSSession -Session $JEASession
   $window.DialogResult = $false
}

# do the initial filling of the combo boxes
Set-VMCombos
# build and display the window
Show-WPFWindow -Window $window
#endregion