PowerShell: Umstellung von dynamischer (per DHCP vergebener) auf statische IP Konfiguration

Veröffentlicht in: Allgemein, Powershell, VMM

Mit dem folgenden, nicht invasivem, also nur lesendem Skript kann man alle “Computername*” Systeme auf dynamische IP Konfiguration überprüfen:

Clear-Host

# ggf. für Vorarbeiten: Alle Clusternodes der Domain bestimmen
get-cluster -Domain QS | get-clusternode

# da Cluster auf eine IP Änderung evtl. mit einem Clusterdown aufgrund von Heartbeatverlust reagieren,
# wenn die Änderungen bei zwei Knoten des Cluster kurz hintereinander durchgeführt werden
# daher sollten Knoten mit dynamischer IP Konfiguration ggf. manuell, bzw.durch Ändern des
# „Name -like“ Suchparameters weiter unten, einzeln umgestellt werden

# Array $ServerVMs mit zu prüfenden VMs füllen, hier alle mit Server* OS und Computernamen die mit Computername* anfangen
$ServerVMs = Get-ADComputer -Filter {OperatingSystem -Like ‚*Server*‘ -and Name -like ‚Computername*‘} | select -Expand DNSHostName

#Schleife die jede der VMs des Arrays durchgeht
foreach ($ServerVM in $ServerVMs)
{
Write-Host Teste auf DHCP NICs in $ServerVM …

# Listet alle Systeme in $ServerVMs mit dynamischer IP Konfiguration
Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $true}

}

 

Weiterhin kann das erweiterte Skript dann Systeme mit dynamischer auf statische IP Konfiguration umstellen und behält dabei die ehemals dynamischen Werte bei:

Clear-Host

# ggf. für Vorarbeiten: Alle Clusternodes der Domain bestimmen
get-cluster -Domain QS | get-clusternode

# da Cluster auf eine IP Änderung evtl. mit einem Clusterdown aufgrund von Heartbeatverlust reagieren,
# wenn die Änderungen bei zwei Knoten des Cluster kurz hintereinander durchgeführt werden
# daher sollten Knoten mit dynamischer IP Konfiguration ggf. manuell, bzw.durch Ändern des
# „Name -like“ Suchparameters weiter unten, einzeln umgestellt werden

# Array $ServerVMs mit zu prüfenden VMs füllen, hier alle mit Server* OS und Computernamen die mit ‚Computername*‘ anfangen
$ServerVMs = Get-ADComputer -Filter {OperatingSystem -Like ‚*Server*‘ -and Name -like ‚Computername*‘} | select -Expand DNSHostName

#Schleife die jede der VMs des Arrays durchgeht
foreach ($ServerVM in $ServerVMs)
{
Write-Host Teste auf DHCP NICs in $ServerVM …

# Array mit allen Netzwerkkarten mit dynamischer IP der spezifischen VM aufbauen
# durch weglassen von „$NICs =“ an anfagng, bekommt man die betroffenen Systeme (mit dynamischer IP) aufgelistet
# dann sollte aber auch die (äußere) ForEach Schleife mit <# #> auskommentiert werden
$NICs = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $true}

# Für jede dieser Netzwerkkarten die  Umstellung auf statische IP Konfiguration
# unter Beibehaltung der Daten der dynamischen Konfiguration (IP, Subnetz, Gateway, DNS Server)
ForEach ($NIC in $NICs)
{
# bisherige IP Daten in $ip, $subnet, $gateway, $dns schreiben
$ip = ($NIC.IPAddress[0])
$subnet = $NIC.IPSubnet[0] $gateway = $NIC.DefaultIPGateway
$dns = $NIC.DNSServerSearchOrder

# statische Konfiguration aktivieren, mit den Daten aus der dynamischen Konfiguration
$NIC.EnableStatic($ip,$subnet)
$NIC.SetGateways($gateway,1)
$NIC.SetDNSServerSearchOrder($dns)
$NIC.SetDynamicDNSRegistration(„FALSE“)
}
}

Powershell: Processor Combatibility mode für Hyper-V VMs

Veröffentlicht in: Allgemein, Powershell, VMM

Die CPU Kompatibilität für virtuelle Hyper-V Maschinen kann zur Live Migration der VMs auf einen Host mit einer anderen Prozessor Generation notwendig sein.
Daher empfehle ich immer diesen Modus auf allen VMs zu aktiveren, die nicht explizit auf die erweiterten Features angewiesen sind.

 

image

 

Im aktuellen Projekt hatten wir die Herausforderung dies bei allen VMs einer Domain umzustellen, natürlich dann nicht mehr per Hand/GUI, sondern natürlich mal wieder per PowerShell! Smiley

 

Ich habe also mal schnell ein kleine Skript gebaut, welches das für alle VMs einer Domain mit integriertem System Center Virtual Maschine Manager (VMM) umsetzt:

Voraussetzung ist, das alle VMs ausgeschaltet/heruntergefahren sein müssen!

 

Clear-Host

$VMs = Get-SCVirtualMachine

ForEach ($VM in $VMs)

{

Write-Host

Write-Host „Setze LimitCPUForMigration auf ‚true‘ für VM “ $VM -ForegroundColor Yellow

# ohne Setzen von GuestOS Shutdown:

Set-SCVirtualMachine -VM $VM  -CPULimitForMigration $true

# mit Setzen von GuestOS Shutdown:

# Set-SCVirtualMachine -VM $VM -CPULimitForMigration $true -StopAction ShutdownGuestOS

}

 

Der zweite (auskommentierte Teil) der Schleife würde auf der VM auch gleich das automatische Herunterfahren der VM (standard ist hier “speichern/safe state”) bei der “Automatic Stop Action” eintragen.
Dies haben wir hier beim Kunden auch direkt mit umgesetzt.

Powershell: Cluster-Test Automatisierung und Anlage einer Clustertest-Bericht-Historie auf SMB Share

Veröffentlicht in: Clustering, Core, Powershell

Problemstellung: automatisierte Clustertests für alle Cluster in allen Domänen durchführen und die Reports auf einem Fileserver ablegen, um diese Berichte im Falle eines Supportcase direkt zugänglich zu haben und auch eine Historie der Berichte jedes Clusters einsehen zu können.

Eine Aufgabe für PowerShell:

test-cluster

Ist in der Lage den resultierenden Bericht mittels des Attributes –ReportName im Namen anzupassen

test-cluster –cluster Cluster10 –ReportName meinReport

z.B. erzeugt eine meinReport.mht Datei des Berichtes über den Cluster10.

Gut, aber kann test-cluster auch den Pfad des Berichtes verändern?
Jap, kein Problem:

test-cluster –cluster Cluster10 –ReportName c:\Temp\Reports\meinReport

Erzeugt eine meinReport.mht Datei im Verzeichnis C:\Temp\Reports.
Ok, dieser Pfad muss dafür existieren…das Prüfen und Korrigieren wir später mittels:

if( -not (Test-Path C:\Temp\Reports) )
{
    New-Item C:\Temp\Reports -type directory
}

den Bericht an einen anderen lokalen Pfad Umleiten geht also…aber evtl. ist das ja kein Laufwerksbuchstabe, auf dem die Reports abgelegt werden sollen, sondern ein UNC/SMB Pfad…
Aber, auch das geht mit test-cluster:

test-cluster –cluster Cluster10 –ReportName \\VMM\c$\Temp\Reports\meinReport

erstellt eine meinReport.mht auf dem VMM Server unter C:\Temp\Reports… fein fein 🙂

Da ja eine Historie, also ein Archiv mit Berichten aller Cluster vorgehalten werden soll, macht es Sinn, die Dateien nicht alle meinReport.mht zu nennen, sondern mit dem Clusternamen und Datum sowie u.U. auch dem Domainnamen zu versehen. Auf letzteres könnte ich hier bei dem Kunden verzichten, da ein Ablageort/Fileserver je Domain vorgesehen wurde, habe es aber trotzdem mit eingebaut, schadet ja nicht:

Dazu ersetzen wir zuerst die –cluster und –Reportname Attribute unseres PowerShell commandlets test-Cluster durch Variablen, die wir im Folgenden dann mit “Leben” füllen:

test-cluster -cluster $cluster -ReportName $reportname

Also brauchen wir aktuell $cluster und $reportname als Eingangsvariable für unser Skript.

Um die Berichte auf dem Fileserver später zuerst nach Clusternamen und dann nach Erstellungsdatum/Zeit sortiert zu bekommen, kann man den Reportnamen wie folgt u.A. mit der Datumfunktion anpassen:

$domain = $env:USERDOMAIN
$reportpath =
\\vmm\c$\Temp\Reports\
$date = get-date -Format yyyy.MM.dd.HH.mm.ss
$reportname = $reportpath+$domain+“_“+$cluster+“_“+$date

get-date liefert ohne weitere Parameter einen Wert, der nicht für Dateipfade verwendbar ist, da er ggf. / und : enthält. Auch der –Format s Parameter den ich zuerst verwendete weil er einen “sortierbare” Ausgabe erstellt, wurde aufgrund der Doppelpunkte nicht brauchbar.

Man kann die Rückgabe von get-date aber glücklicherweise sehr individuell anpassen und bekommt mit dem von mir verwendeten –Format yyyy.MM.dd.HH.mm.ss das Format Jahr.Monat.Tag.Stunde.Minute.Sekunde jeweils als Zahl und min. zweistellig zurück, so dass nachher Berichte schon aufgrund des Dateinamens auch chronologisch sortiert werden.

Um alle Cluster einer Domain zu verarbeiten, erstelle ich zuerst eine Liste aller Cluster in die Variable $clusters:

$clusters = get-cluster -Domain $domain

Diese wird dann einfach über eine ForEach Schleife unter jeweiligem Setzen des entsprechenden $reportname abgearbeitet:

ForEach ($cluster in $clusters)
     {
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
     }

Um (optionale) Parameterübergaben für die Domäne, den Reportpfad, sowie den Cluster erweitert sieht das vollständige Skript aktuell wie folgt aus:
(wird immer wieder mal erweitert/angepasst)

#########################################################################################
#### Cluster Validation Test Script for scheduled Testing of Clusters ####

#### Author: Oliver Sommer, TrinityComputer.de GmbH

#########################################################################################

param(
[string]$domain = $env:USERDOMAIN,
[string]$reportpath,
[string]$cluster
)

# Prüfung, ob $reportpath übergeben wurde (leer ist) und falls nicht:
# Entscheidung welcher domänenspezifische $reportpath (Fileshare) zu verwenden ist
If (!$reportpath)
{
     If ($domain –eq „Dom1“)
     {
         $reportpath = „\\fileserver1\Reportspfad\“
     }

    If ($domain -eq „Dom2“)
     {
         $reportpath = „\\Fileserver2\Reportspfad\“
     }

    If ($domain -eq „Dom3“)
     {
         $reportpath = „\\Fileserver3\Reportspfad\“
     }
     If ($domain -eq „3CAN“)
     {
         $reportpath = „\\vmm\c$\Temp\Reports\“
     }
}

Clear-Host

# Prüfung ob $reportpath existiert und ggf. Erstellen des Pfades
if( -not (Test-Path $reportpath) )
{
    New-Item $reportpath -type directory
    Write-Host
    Write-Host Verzeichnis $reportpath erstellt!
    Write-Host
}

#Alle Cluster der Domäne in $clusters schreiben:
$clusters = get-cluster -Domain $domain
Write-Host In der AD DS Domäne $domain sind folgende Cluster vorhanden:
Write-Host $clusters
Write-Host

#sortierbares Datum in $date schreiben
$date = get-date -Format yyyy.MM.dd/_HH.mm.ss

# Falls ein spezifischer Cluster beim Skriptaufruf übergeben wurde:
If ($cluster)
{
     Write-Host Starte Validationtest für Cluster $cluster…
     Write-Host
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
}

# Prüfen ob $cluster als Attribut beim Skriptaufruf übergeben wurde, also ob es leer ist oder nicht:
If (!$cluster)
{
Write-Host Starte Validationtests für alle Cluster der Domäne $domain…
Write-Host
# Clusterbericht für jeden Cluster der Domain ausführen und individuellen Report ablegen:
ForEach ($cluster in $clusters)
     {
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
     }

}

 

1 2