Artikel-Schlagworte: „Scripting“

postheadericon perl SDK – Mac Adressen aller virtuellen Maschinen auslesen

Wem ist es nicht schon einmal untergekommen. Die interne Technik läuft säuerlich durch die Stockwerke, gibt kryptische Hexblöcke von sich, redet von Konflikten und meint damit nicht die aktuelle Weltpolitik? Gemeint ist natürlich ein Mac- bzw. IP-Adressen-Konflikt innerhalb eines IP-Netzwerks. Einem ESX-Admin stellt sich nun die Aufgabe, über alle ESX-Hosts zu gehen und z.B. mit grep die .vmx-Dateien zu durchsuchen. Alternativ bauen wir uns einfach ein kleines Perl Skript, was nicht nur eleganter, sondern vor allem zeitsparender ist.

Anbei die Rohfassung eines solchen Skriptes, es bleibt wie immer dem Leser überlassen, kosmetische Verbesserungen vorzunehmen. Voraussetzung ist eine lauffähige Perl-SDK-Installation.

#!/usr/bin/perl
#
# Search VirtualCenter Server for all assigned VM Nic mac adresses.
#

use strict;
use warnings;
use VMware::VIRuntime;

Opts::parse();
Opts::validate();
Util::connect();

# Get the service content reference, root to most of the API features
my $sc = Vim::get_service_content();

unless ($sc->about->apiType() eq “VirtualCenter”) {
die “This script needs to be run against a virtual center.\n”;
}

sub getVmName {
my $vm = shift;
if (ref($vm) ne “VirtualMachine”) {

die(“Invalid VirtualMachine reference”);
}
return $vm->{summary}->{config}->{name};
}

sub getVmMac {
my $vm = shift;
if (ref($vm) ne “VirtualMachine”) {
die(“Invalid VirtualMachine reference”);
}

my @mac;
foreach my $dev_ref (@{ $vm->{config}->{hardware}->{device} }) {
if(defined($dev_ref->{macAddress})) {
# assume nic

push @mac, $dev_ref->{macAddress};
}
}
return @mac;
}
# Fetch all VMs
my $vms = Vim::find_entity_views(view_type => ‘VirtualMachine’);
foreach my $vm_view (@{$vms}) {
my $vm_name = getVmName($vm_view);
my @mac = getVmMac($vm_view);
print “Name: $vm_name\n”;
print “Mac: “. join(“, “, @mac) .”\n”;
}

END {
Util::disconnect();
}

Viel Spaß damit!

postheadericon perl SDK – Host Alarme in vCenter bestätigen

Manchmal ist es einfacher, vCenter Alarme über die Kommandozeile zu bestätigen (acknowledge), als das Ganze via VI Client zu erledigen.

Hier ein kleines Beispiel, wie das mittels Perl SDK und vSphere 4.0 API funktioniert:

#!/usr/bin/perl
use strict;
use warnings;
use VMware::VIRuntime;

# validate options, and connect to the server
Opts::parse();
Opts::validate();
Util::connect();

# This is where most features starts … get service content reference
my $sc = Vim::get_service_content();
# fetch alarmManager
my $alarmManager = Vim::get_view( mo_ref => $sc->alarmManager );
unless (defined $alarmManager) {
print “ERROR Could not connect to alarmManager. Exiting.\n”;
print “Remember: you need to connect to a vCenter installation.\n”;
Util::disconnect();
exit 1
}

# our ESX Hosts
my $esx_hosts = Vim::find_entity_views( view_type => ‘HostSystem’ );
foreach my $esx (@{$esx_hosts}) {
printf “Working at Host: %s\n”, $esx->{summary}->{config}->{name};
if($esx->{summary}->{host}->{type} ne “HostSystem”) {
printf “Skipping for non HostSystem ‘%s’”, $esx->{summary}->{host}->{type};
next;
}
foreach my $alarm_me (@{$esx->{triggeredAlarmState}}) {
my $alarm = Vim::get_view( mo_ref => $alarm_me->{alarm} );
printf “%s “, $alarm->{info}->{lastModifiedTime};
printf “%s\n”, $alarm->{info}->{name};
# Ack the alarm
$alarmManager->AcknowledgeAlarm( alarm => $alarm_me->{alarm},
entity => $alarm_me->{entity} );
printf “Alarm acknowledged\n”;
}
}
Util::disconnect();

Viel Spaß damit!

postheadericon IP-Adresse einer Guest-VM mit vimsh ermitteln

VMware bietet eine Reihe von Möglichkeiten, Aktionen skript-gesteuert auszuführen. Bei der Suche nach einer Möglichkeit, sich die IP-Adresse einer VM anzeigen zu lassen, bin ich auf das Tool vimsh gestoßen. Diese Kommando-Zeilen-Alternative liefert die ESX-Installation mit.
In zahlreichen Foren werden damit Lösungen aufgezeigt. Scheinbar handelt es sich hierbei um eine nur für den VMware-internen Gebrauch gedachte Möglichkeit. Auf den VMware-Seiten ist wenig Dokumentation darüber zu finden. Ein gutes Wiki habe ich hier gefunden.

Damit lies sich ein kleines Skript erstellen, das einfach mittels vimsh-Kommandos IP-Adressen zu einzelnen VMs ermittelt:

#!/bin/sh

if [ $# -ne 1 ]; then
echo "Usage: getGuestIP.sh <VM Name>" 1>&2
exit 1;
fi

vimsh -n -e "vmsvc/getallvms" 2>/dev/null | grep "$1.*vmx" | while read vm; do
echo -ne `echo $vm | sed -e 's/.*\///' -e 's/\.vmx.*//'`": "
id=`echo $vm | cut -d\ -f1`
ip=`vimsh -n -e "vmsvc/get.config $id" 2>/dev/null | \
sed -ne '/guestinfo.guestIP/,/}/p'`
echo $ip | sed -e 's/.*value = "//' -e 's/",.*//'
done

Diese Methode kann leicht variiert werden, um andere Informationen auszulesen.

postheadericon VMware: Scripting with Powershell CLI: Tipps

Hier noch eine Sammlung einiger Kleinigkeiten, die das Arbeiten mit Powershell-Skripten erleichtern

  1. Bestätigungsrückfrage abschalten: Bei vielen Kommandos wird bei der Ausführung eine mehr oder weniger lästige Bestätigung abgefragt:[vSphere PowerCLI] C:\> Disconnect-VIServer
    Confirm
    Are you sure you want to perform this action?
    Performing operation “Disconnect VIServer” on Target “Server
    vcenter1.vmlab.roc.consol.de”.
    [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
    (default is “Y”):

    Dies lässt sich mit dem Parameter “-Confirm$false” beim Aufruf der entsprechenden Funktion abschalten.

  2. Auf SDK-Methoden zugreifenPowershell CLI bietet auch die Möglichkeit, Methoden der API direkt aufzurufen. So dient die Methode RegisterVM_Task() dazu, eine VM über den absoluten Pfad ihrer .vmx Datei auf einem ESX-Server zu registrieren. Bei den cmdlets der Powershell konnte ich keine geeigneten Methoden dazu finden.
    Eine guter Einstieg in die Dokumentation der unterschiedlichen Skript-Schnittstellen von VMware findet sich im Dokument DOC-7270.
  3. Task innerhalb von Powershell starten und Ergebnis abrufen$task = Get-View $taskMoRef
    while ($task.info.state -eq “running” -or $task.info.state -eq “queued”){
    $task = Get-View $taskMoRef
    }

    if ($task.info.error -eq $null){
    Write-Output “Task successfully completed”
    } else {
    Write-Output “Task NOT successfully completed”
    }

    Diese Sequenz prüft den Status einer zuvor erzeugten Task und wartet solange, bis sich diese beendet hat. Anschließend kann über $task.info.error festgestellt werden, ob bei der Ausführung ein Fehler auftrat.

postheadericon VMware: Skripte mit Powershell CLI

Mit diesem Eintrag beginnt eine neue Phase in meinem IT-Leben, das erste Mal betrete ich das Neuland der Blog-Szene. Es soll hier um die Erfahrungen im Zusammenhang mit der Umsetzung von Virtualisierungs-Projekten gehen.

Als Teil eines Kundenprojekts betreuen wir im Endausbau eine Installation von über 6000 virtuellen Desktops bei über 5000 Benutzern gleichzeitig, verteilt auf über 50 ESX-Instanzen. Besondere Herausforderung bei dieser Installation ist die Verwendung von SunVDI, da hier auch Sun Rays als Thin Clients verwendet werden sollen.

Bei ca. 100VMs pro ESX ist der Einsatz von VMware HA nicht mehr möglich. VMware HA unterstützt maximal bis zu 40 VMs pro ESX (Version 3.5). Um das Problem eines ESX-Ausfalls abzufangen, wurde nach einer eigenen HA-Lösung gesucht.

Als guter Ausgang hat sich dabei die Verwendung von Powershell-Snapins, VMware vSphere PowerCLI herausgestellt. Damit lassen sich mit wenigen Statements komplexe Aufgaben automatisieren.

Erste Schritte:

Die cmdlet-Snapins sind beim interaktiven Aufruf der Shell geladen, wird ein Skript über cmd.exe oder durch Doppelklick gestartet, sind die Snapins noch nicht geladen. Folgende Sequenz prüft das und lädt ggf. die Snapins nach, sollten sie nicht bereits verfügbar sein.

& {
$ErrorActionPreference = “silentlycontinue”
$vmwareSnap = get-pssnapin -name “VMware.VimAutomation.Core”
if (! $?) { add-pssnapin “VMware.VimAutomation.Core” }
}

Komplexe Anforderungen einfach umsetzen

Danach lassen sich recht einfach auch komplexe Aufgaben erledigen:

$povms = Get-VM -Server $vCenter -Location (Get-VMHost -Server $vCenter -State NotResponding) | Where-Object {$_.PowerState -eq “PoweredOn”}


Diese Sequenz liefert alle VMs, die auf einem ESX, der nicht mehr antwortet (State “NotResponding”) eingeschaltet ($_.PowerState -eq “PoweredOn”) waren.

$folder = Get-View (Get-Datacenter -Server $esxFailover -Name “ROC_VDI” | Get-Folder -Server $esxFailover -Name “SUN VDI”).ID
$respool = Get-View (Get-ResourcePool -Server $esxFailover -Location (Get-VMHost -Server $esxFailover)).ID

$destesx = Get-VMHost -Server $esxFailover -Name “esx2.vmlab.roc.consol.de”

Damit sollten eigentlich alle Informationen verfügbar sein, um eine VM, die auf einem Shared Storage abgelegt ist, auf einem anderen ESX-Server, der darauf ebenfalls Zugriff hat, zu starten.