Welcome to my first Azure Stack blog.
Recently I have been exploring the Azure Stack POC TP1 which is available for everyone at https://azure.microsoft.com/en-us/overview/azure-stack/
So far I am very impressed, of cause always bear in mind that this is the first technical preview POC.
Today I made a small tool for helping me to have a good overview of my Azure Stack tenant VMs.
In Azure Stack the VMs are named by their GUID in Hyper-V.
This makes perfect sense, since multiple tenants could easily name their VMs the same name.
But when administrating your hyper-v host, It can be a bit hard to recognize which machine is which.
Therefore I have create a small GUI tool in PowerShell to help list the machines on a host, and to be able to trigger some basic actions.
This is the first beta and the following actions have been added:
- Connect to Console
- Stop VMs
- Start VMs
You can download the PowerShell based tool here:
https://gallery.technet.microsoft.com/Azure-Stack-VM-GUI-Beta-1-9e55aa80
Here is the current script content (the gallery item might be updated since this blog post was published):
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# //********************************************************************************************* # // Solution: # // Author: Jakob Gottlieb Svendsen, Coretech A/S. https://blog.ctglobalservices.com / www.runbook.guru # // Purpose: List Azure Stack VMs from hyper-v host in a friendly layout. # // Trigger actions on a number of VMs # // Connects to localhost by default. Please send suggestions to jgs@coretech.dk # // # // Usage: MAS-VM-Admin.ps1 # // MAS-VM-Admin.ps1 -Computer <hyper-v host" # // # // History: # // 1.0.0 JGS 02/22/2016 Created initial version. # // # //******************************************************************************************** # //---------------------------------------------------------------------------- #// #// Global constant and variable declarations #/ #//---------------------------------------------------------------------------- param($ComputerName = "localhost") #//---------------------------------------------------------------------------- #// Procedures #//---------------------------------------------------------------------------- Function UpdateVMList($ComputerName) { $VMInfos = @() $VMs = get-vm -ComputerName $ComputerName foreach ($VM in $VMs) { if(!$vm.Notes.StartsWith("Region:")) { continue } #Skip non MAS VMs $VMInfo = New-Object -TypeName PSObject $VMInfo | Add-Member -MemberType NoteProperty -Name Name -Value $VM.Name #MAS Attributes $NotesSplit = $VM.Notes.Split(",") foreach ($pair in $NotesSplit) { $pairsplit = $pair.Split(":") $VMInfo | Add-Member -MemberType NoteProperty -Name $pairsplit[0].Trim() -Value $pairsplit[1].Trim() } $VMInfo | Add-Member -MemberType NoteProperty -Name VM -Value $VM $VMInfos += $VMInfo } $ListViewMain.ItemsSource= $VMInfos } #//---------------------------------------------------------------------------- #// Main routines #//---------------------------------------------------------------------------- #Check hyper-v module installed if(!(get-module -ListAvailable -Name "hyper-v")) { throw "Hyper-V module not found. Please run this tool on a server that has the Hyper-V management tools installed" } Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationCore [XML]$MainWindow = @' <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Runbook.Guru - Azure Stack VM Manager" Height="700" Width="1000"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="1000*"></ColumnDefinition> <ColumnDefinition Width="150"></ColumnDefinition> </Grid.ColumnDefinitions> <ListView x:Name="ListViewMain" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > <ListView.View> <GridView > <GridViewColumn Header="VMName" DisplayMemberBinding="{Binding VMName}" /> <GridViewColumn Header="State" DisplayMemberBinding="{Binding VM.State}" /> <GridViewColumn Header="CPU Usage" DisplayMemberBinding="{Binding VM.CPUUsage}" /> <GridViewColumn Header="Assigned Memory" DisplayMemberBinding="{Binding VM.MemoryAssigned}" /> <GridViewColumn Header="Uptime" DisplayMemberBinding="{Binding VM.Uptime}" /> <GridViewColumn Header="ResourceGroup" DisplayMemberBinding="{Binding ResourceGroup}" /> <GridViewColumn Header="Subscription" DisplayMemberBinding="{Binding Subscription}" /> <GridViewColumn Header="Region" DisplayMemberBinding="{Binding Region}" /> <GridViewColumn Header="Hyper-V VM Name" DisplayMemberBinding="{Binding Name}" /> <!--<GridViewColumn Header="VM" DisplayMemberBinding="{Binding VM}" />--> </GridView> </ListView.View> </ListView> <StackPanel Grid.Column="1"> <Label Name="LabelAction" Content="Action" /> <ComboBox Name="ComboBoxAction" /> <Button Name="ButtonGo" Content="Go" /> <Button Name="ButtonRefresh" Content="Refresh VMs" /> </StackPanel> </Grid> </Window> '@ $Reader = (New-Object System.XML.XMLNodeReader $MainWindow) $Window = [Windows.Markup.XAMLReader]::Load($Reader) $ButtonGo = $Window.FindName('ButtonGo') #$ButtonAdd = $Window.FindName('ButtonAdd') $ButtonRefresh = $Window.FindName('ButtonRefresh') $ComboBoxAction = $Window.FindName('ComboBoxAction') $ListViewMain = $Window.FindName('ListViewMain') #Set sorting events UpdateVMList -ComputerName $ComputerName $Actions = @("Connect to Console","Stop VMs", "Start VMs") $ComboBoxAction.ItemsSource = $Actions $ComboBoxAction.SelectedIndex = 0 #Event Handlers $Window.Add_Loaded({ }) #Sort event handler $Window.Add_SourceInitialized({ [System.Windows.RoutedEventHandler]$ColumnSortHandler = { If ($_.OriginalSource -is [System.Windows.Controls.GridViewColumnHeader]) { If ($_.OriginalSource -AND $_.OriginalSource.Role -ne 'Padding') { $Column = $_.Originalsource.Column.DisplayMemberBinding.Path.Path # And now we actually apply the sort to the View $ListViewMain_DefaultView = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ListViewMain.ItemsSource) # Change the sort direction each time they sort Switch($ListViewMain_DefaultView.SortDescriptions[0].Direction) { "Decending" { $Direction = "Ascending" } "Ascending" { $Direction = "Descending" } Default { $Direction = "Ascending" } } $ListViewMain_DefaultView.SortDescriptions.Clear() $ListViewMain_DefaultView.SortDescriptions.Add((New-Object System.ComponentModel.SortDescription $Column, $Direction)) $ListViewMain_DefaultView.Refresh() } } } #Attach the Event Handler $ListViewMain.AddHandler([System.Windows.Controls.GridViewColumnHeader]::ClickEvent, $ColumnSortHandler) }) $ButtonGo.Add_Click({ switch ($ComboBoxAction.SelectedValue) { "Stop VMs" { Stop-VMs -VM $ListViewMain.SelectedItems } "Start VMs" { Start-VMs -VM $ListViewMain.SelectedItems } "Connect to Console" { #. "$env:windir\system32\vmconnect.exe" "$computername $($ListViewMain.SelectedItem.Name)" Start-Process -FilePath "$env:windir\system32\vmconnect.exe" -ArgumentList $computername,$ListViewMain.SelectedItem.Name } } }) $ButtonRefresh.Add_Click({ UpdateVMList }) #Actions function Stop-VMs { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [Object] $VM ) Process { write-warning "Shutting down VM: $($VM.VMName) ($($VM.Name))" Stop-VM -Name $VM.Name } } function Start-VMs { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [Object] $VM ) Process { write-warning "Starting VM: $($VM.VMName) ($($VM.Name))" Start-VM -Name $VM.Name } } $Window.ShowDialog() #//---------------------------------------------------------------------------- #// End Script #//---------------------------------------------------------------------------- |
Leave A Comment