Sie haben bereits einen Azure Tenant mit diversen Ressourcengruppen und virtuellen Maschinen, sodass man manchmal den Überblick verliert? Stört es Sie auch, VMs über das Azure Portal zu starten bzw. zu stoppen? Wenn ja, wie sieht es mit einem PowerShell-Skript aus, welches eine Übersicht Ihrer VMs generiert und die ausgewählten Maschinen parallel stoppt bzw. startet? 


Motivation

In diesem kurzen Blogpost möchte ich ein, von mir sehr oft verwendetes, PowerShell-Skript zur Verfügung stellen, welches mir sehr viel Zeit bei der Verwaltung von Microsoft Azure ARM VMs erspart. Neben der klassischen Administration über das Azure Portal gibt es unter anderem die Option seinen Azure Tenant über die PowerShell zu verwalten und zu steuern. Hierdurch können wir diverse Prozesse automatisieren und vor allem parallelisieren. Durch simultanes Ausführen von PowerShell-Jobs können wir somit enorm viel Zeit einsparen. Der Anwendungszweck kann hierbei sehr unterschiedlich sein, z.B.: Die Erstellung von 100 Speicherkonten oder virtuellen Maschinen aus einem Master-Image. Oder aber, wie dieser Blogpost beschreibt, auch das synchrone Starten bzw. Stoppen mehrerer VMs.

Voraussetzungen

Um das Skript nutzen zu können, benötigst man lediglich einen Azure Mandant mit erforderlichen Berechtigung zu einer Subscription. Weiterhin ist die aktuelle Azure PowerShell erforderlich. Es gibt verschiedene Vorgehensweisen und Arten diese zu installieren. Die einfachste Art und Weise die Azure PowerShell Module zu installieren, erfolgt, wer hätte es gedacht, über die PowerShell selbst. Öffnen Sie dazu eine PowerShell-Sitzung als Administrator mit einer aktiven Internetverbindung und führen Sie folgenden Befehl aus:
[code lang=“powershell“]# Install the Azure Resource Manager modules from the PowerShell Gallery
Install-Module AzureRM
# Install the Azure Service Management module from the PowerShell Gallery
Install-Module Azure[/code]

Darüber hinaus wird für die Anmeldung an Ihrer Azure Subscription eine Profildatei benötigt. Eine gespeicherte Azure Profildatei enthält unter anderem die erforderlichen Anmeldedaten zu Ihrem Azure Mandant. Weiterhin besteht die Möglichkeit die gewünschte Azure Subscription und ein Standard-Speicherkonto in diesem Profil zu hinterlegen. Zunächst müssen Sie sich einmal manuell auf Ihre Azure Subscription verbinden und wenn erforderlich eine Subscription auswählen.
[code lang=“powershell“]Login-AzureRmAccount
Get-AzureRmSubscription
Select-AzureRmSubscription -SubscriptionId „ID“
[/code]

Nachdem die Subscription und evtl. auch ein Standard-Speicherkonto definiert wurde, können Sie diese Einstellungen in einer *.JSON Profildatei speichern und diese zur automatisierten Anmeldung an der konfigurierten Azure Subscription verwenden.
[code lang=“powershell“]Save-AzureRmProfile -Path „C:users$env:usernamedesktopazureprofile.json“
[/code]

Und nun zum eigentlichen Skript [Azure ARM VMs]

Beim Ausführen des Skripts werden Sie zunächst aufgefordert, die zuvor erzeugte und gespeicherte Profildatei auszuwählen:

Azure Profil öffnen
Azure Profil öffnen

Nachdem das Profil geladen und eine erfolgreiche Verbindung zur Azure Subscription aufgebaut wurde, erscheint eine Grid-View mit allen virtuellen Maschinen, welche sich zur Laufzeit im ausgeschalteten Zustand befinden. In der Grid-View besteht die Möglichkeit eine, mehrere oder gar alle VMs zu markieren und mit Bestätigen zu starten bzw. zu stoppen:

Virtuelle Maschinen auswählen
Virtuelle Maschinen auswählen

Mit Bestätigen der Auswahl, werden alle selektierten VMs parallel gestartet. Zur Überwachung der einzelnen PowerShell-Jobs wird in kurzen Abständen eine Job-Übersicht über die PowerShell-Konsole ausgegeben:

Azure Jobs überwachen
Azure Jobs überwachen

Nun müssen Sie nur noch abwarten bis alle PowerShell-Jobs fertiggestellt sind und die VMs gestartet / gestoppt sind. Den gesamten Code zum Skript finden Sie im Anhang. Dieser beinhaltet nur das Starten der VMs. Dieser lässt sich jedoch mit Austausch von zwei Befehlszeilen zu einem VM-Stopp-Skript umbauen. Einfach die entsprechenden Stellen im Skript suchen und mit den folgenden Zeilen ersetzten.
[code lang=“powershell“]
#Get VM-List
$VMs = Get-AzureRMVM -Status | where {$_.PowerState -eq „VM running“} | select Name, ResourceGroupName, Location, PowerState | Out-GridView -Title „Select Azure RM virtual Machine“ -PassThru

Stop-AzureRmVM -ResourceGroupName $rgName -Name $vmName -Force[/code]

 

 

Anhang: Azure ARM VMs Code

Nachfolgend stelle ich gerne den gesamten PowerShell-Code zur Verfügung:
[code lang=“powershell“]#Open Azure RM Profile-file
Add-Type -AssemblyName system.Windows.Forms
$AzureRmProfile = New-Object System.Windows.Forms.OpenFileDialog
$AzureRmProfile.Filter = „All files (*.JSON)|*.json“
$AzureRmProfile.FilterIndex = 2
$AzureRmProfile.ShowDialog();
$AzureRmProfileFile = $AzureRmProfile.FileName;

#Login to Azure with Profile-file
Select-AzureRmProfile -Path $AzureRmProfileFile

#Get VM-List
$VMs = Get-AzureRMVM -Status | where {$_.PowerState -eq „VM deallocated“} | select Name, ResourceGroupName, Location, PowerState | Out-GridView -Title „Select Azure RM virtual Machine“ -PassThru

foreach($vm in $VMs){
$rgName = $vm.ResourceGroupName;
$vmName = $vm.Name;
$jobName = „Start-VM: “ + $vmName

Start-Job -Name $jobName -ScriptBlock {
param(
[string]$rgName,
[string]$vmName,
[string]$AzureRmProfileFile
)

Select-AzureRmProfile -Path $AzureRmProfileFile
Start-AzureRmVM -ResourceGroupName $rgName -Name $vmName

} -ArgumentList ($rgName,$vmName,$AzureRmProfileFile)
}

#Monitor jobs
while($job = get-job | where {($_.State -eq „Running“) -and ($_.Name -like „Start-VM*“)} | ft Name, State, PSBeginTime -AutoSize) {
cls
Write-Host „Running jobs: “ -ForegroundColor Yellow
$job
Write-Host „Summary: “ -ForegroundColor Cyan -NoNewline
Write-host ($VMs.Count – (Get-Job -State ‚Running‘).Count) -ForegroundColor Yellow -NoNewline
Write-Host “ VMs of “ -ForegroundColor Cyan -NoNewline
Write-Host $VMs.Count -ForegroundColor Yellow -NoNewline
Write-Host “ started“ -ForegroundColor Cyan -NoNewline
Wait-Event -Timeout 5
}[/code]

Weiteres