Powershell: Hyper-V hosts mit ausstehenden Neustarts (pending Reboots) erkennen, evakuieren und automatisiert Neustarten

eingetragen in: Hyper-V, Powershell, Windows | 0

Versetzt Hyper-V hosts mit pending reboots in den Wartungsmodus, startet diese neu und deaktiviert anschließend den Wartungsmodus wieder
Damit einher geht die Evakuierung der VMs vor dem Reboot und eine abschließende Clusteroptimierung:

 

<#———————————————————————————
Reboot-PendingBootSCVMHosts Skript
Versetzt Hyper-V hosts mit pending reboots in den Wartungsmodus, startet diese neu und deaktiviert anschließend den Wartungsmodus wieder
Damit einher geht die Evakuierung der VMs vor dem Reboot und eine abschließende Clusteroptimierung
Ersteller:       Oliver Sommer
———————————————————————————#>

Clear-Host

$VMHostNoClusters = $null
 $VMHostNoClusters =@()

$VMHosts = $null
 $VMHosts =@()

<# ---- Start Auskommentieren bei Verwendung der automatischen Hostliste weiter unten.       -----
 ## ---- Bei Verwendung der auto Hostliste einfach das in der nächsten Zeile am Ende nach # folgende > entfernen! -----
 #

$VMHosts += "Host012"
$VMHosts += "Host023"

<# ---- Ende Auskommentieren bei Verwendung der Auto Hostliste weiter unten -----#>

<# ---- Start Auskommentieren bei Verwendung der manuellen Hostliste weiter oben.            -----
 ## ---- Bei Verwendung der manuellen Hostliste einfach das in der nächsten Zeile am Ende nach # folgende > entfernen! -----
 #>

# Automatisiertes Bestimmen welche Hosts 'Pending Reboots' haben:

Write-Host "Alle Host der Domäne auf pending Reboot prüfen:" -ForegroundColor Green

$AllVMHosts = Get-SCVMHost

foreach ($AllVMHost in $AllVMHosts)
 {
 Write-Host
 Write-Host "Bestimme pending Reboot für: " $AllVMHost
 $PendingHost = Invoke-WmiMethod -ComputerName $AllVMHost -Namespace "ROOT\ccm\ClientSDK" -Class CCM_ClientUtilities -Name DetermineIfRebootPending

If ($PendingHost.RebootPending -eq $true)
 {
 write-Host "Pending reboot: " $PendingHost.RebootPending -ForegroundColor Yellow
 $VMHosts += $PendingHost.__SERVER
 Write-Host "Füge" $PendingHost.__SERVER "der abzuarbeitenden Hyper-V Host Liste hinzu!"
 }
 Else
 {
 write-Host "Pending reboot: " $PendingHost.RebootPending -ForegroundColor Green
 }
 }

<# ---- Ende Auskommentieren bei Verwendung der manuellen Hostliste weiter oben -----
 #>

Write-Host
 Write-Host "Hyper-V Hosts mit Pending reboot:" -ForegroundColor Yellow

foreach ($VMHost in $VMHosts)
 {
 Write-Host $VMHost

# Hole Hostobjekt zu jedem Host mit Pending Reboot, der Clustermitglied ist
 $VMHostobject = Get-SCVMHost -ComputerName $VMHost
 if ($VMHostobject.HostCluster -eq $null)
 {
 $VMHostNoClusters += $VMHost
 }
 }

# Warnung ausgeben, falls nicht geclusterte Hosts erkannt wurden:
 If ($VMHostNoClusters -ne $null)
 {
 Write-Host
 Write-Host "Hosts die nicht Teil eines Hyper-V Clusters sind werden Fehler beim Wartungsmode Job erzeugen!" -ForegroundColor Red
 Write-Host "Die nicht geclusterten Server lauten:" -ForegroundColor Yellow
 Write-Host $VMHostNoClusters -ForegroundColor Yellow
 Write-Host
 }

# Cluster array variable init, für späteres ClusterOptimizing
 $VMHostClusters = $null
 $VMHostClusters =@()

#Write-Host ------------------------------------------------
 Write-Host
 Write-Host "Start der Abarbeitung:" -ForegroundColor Yellow

ForEach ($VMHost in $VMHosts)
 {
 $VMHostobject = Get-SCVMHost -ComputerName $VMHost
 Write-Host
 write-host Durchlauf für $VMHost : -ForegroundColor Green

$MModeHost = $false

Write-Host Bestimmen ob Host $VMHost bereits im MaintenanceMode ist...
 If ($VMHostobject.Overallstate -eq "MaintenanceMode")
 {
 $MModeHost = $true
 Write-Host $VMHost ist bereits im MaintenanceMode! -ForegroundColor Yellow
 }
 Else
 {
 Write-Host $VMHost bisher NICHT in MaintenanceMode!
 }

If ($VMHostobject.HostCluster.Name -ne $null)
 {
 Write-Host
 write-host $VMHost ist Node im Cluster $VMHostobject.HostCluster.Name
 $VMHostClusters += $VMHostobject.HostCluster.Name

<# Falls der Host durch Netbackup oder anderes VMs im (locked) mode haben sollte, hilft die folgende
 # Kill VMMs und start VMMs Routine ggf. dabei die VMs doch verschieben zu können
 #

# Kill Prozess Virtual Maschine Management Service
 Write-Host
 Write-Host Kill Prozess VMMs auf $VMHost
 Invoke-Command -ScriptBlock {Stop-Process -name vmms -Force} -ComputerName $VMHost

# Start Prozess VMMs
 Write-Host
 Write-Host Start Prozess VMMs auf $VMHost
 Invoke-Command -ScriptBlock {Start-Process vmms} -ComputerName $VMHost

Write-Host
 Write-Host 10 Sekunden Pause zum Start des VMMs Service und Erkennen in SCVMM
 Start-Sleep -Seconds 10
 #

# Refresh Host, damit die SCVMM Verbindung wieder hergestellt ist bevor
 # Maintenance Mode aktiviert wird

Write-Host
 Write-Host Führe Refresh-VMHost aus um die SCVMM Verbindung nach Kill VMMs sicherzustellen
 Read-SCVMHost -VMHost $VMHost >$null
 #>

# Maintenance Mode im Cluster
 Write-Host
 write-Host Evakuierung und Wartungsmode von $VMHost wird eingeleitet.... -ForegroundColor Yellow

If ($MModeHost -eq $false)
 {
 Disable-SCVMHost -VMHost $VMHost -MoveWithinCluster >$null
 }

If ($VMHostobject.Overallstate -eq "MaintenanceMode")
 {
 Write-Host
 write-Host Neustart von $VMHost wird eingeleitet.... -ForegroundColor Yellow
 Restart-SCVMHost -VMHost $VMHost -Confirm:$false >$null

# Härteres Herunterfahren via iRMC/iLO mit -UseOutOfBandChannel ggf. wie folgt:
 # Restart-SCVMHost -VMHost $VMHost -UseOutOfBandChannel -RunAsynchronously
 }

If ($MModeHost -eq $false)
 {
 # Maintenance Mode beenden
 Write-Host
 write-Host Wartungsmode von $VMHost wird beendet.... -ForegroundColor Yellow
 Write-Host
 Enable-SCVMHost -VMHost $VMHost -RunAsynchronously >$null
 }
 Else
 {
 Write-Host $VMHost "befand sich vor dem Skritplauf schon im Maintenancemode, daher wird dieser nicht beendet..." -ForegroundColor Yellow
 }
 }
 else
 {
 Write-Host
 write-host $VMHost ist nicht geclustered!! -ForegroundColor Red
 }

write-host ------------------------------

}

# Cluster array variable sortieren und mehrfache Einträge entfernen, für anschließendes ClusterOptimizing
 $Clusters2Optimize = $VMHostClusters | Sort-Object -Unique

Write-Host
 Write-Host "Alle Cluster der Hyper-V Hosts mit Pending Reboots:"
 Write-Host $Clusters2Optimize

ForEach ($VMHostcluster in $Clusters2Optimize)
 {
 Write-Host
 Write-Host Opimierung für $VMHostcluster starten... -ForegroundColor Yellow

$hostCluster = Get-SCVMHostCluster -Name $VMHostcluster
 Start-SCDynamicOptimization -VMHostCluster $hostCluster >$null
 }

#>

Powershell: Automatisiertes Eintragen aller Baseboard Management Controller (BMC) in VMM

eingetragen in: Allgemein, Powershell | 0

oder:
“Basispowermanagement und Grundlage für so vieles weiteres in System Center und VMM …”

Starte mal alle Hosts der xyz Umgebung nach geplanter Stromabschaltung am Wochenende wieder ein!

Supi, per Browser auf jeden der zig Hosts gehen, dort anmelden und dann “Einschalten” drücken… Trauriges Smiley
Besser als jeden einzelnen Server im RZ besuchen, aber bleibt trotzdem ein stupide, langweiliger Praktikantenjob:

pic03122

(Fujitsu hat da auch eine zentralisierte Lösung, werden einige jetzt sagen, aber die ist leider nicht im Einsatz)

Aber VMM kann hier ja sicher helfen, denn genauso wie man VMs einschalten kann, kann man ausgeschaltete Hosts über einen einfachen Rechtsklick auf den Host auch einschalten:

image

Zumindest in der Theorie, weil bei dem Kunden sah das in VMM wie folgt aus:

image

Trauriges Smiley

Also alles außer “Restart” ausgegraut…schade eigentlich, ist aber leicht erklärt:
Diese Funktionalität ist abhängig von einem konfigurieren Baseboard Management Controller (BMC) in VMM und/oder hardwareseitig von einem vorhandenen iRMC (z.B. bei Fujitsu) oder iLO (z.B. bei HP) oder anderen IPMI bzw. SMASH kompatiblen Management Boards in den Hosts/Hardwareservern.

Einzutragen ist die IP des jeweiligen BMC dafür in den Eigenschaften jedes Hosts unter Hardware –> Advanced –> BMC Settings:

pic10585

An der Stelle kann über “Browse” hinter dem RunAs Account Feld und “Create Run As Account” auch gleich, wenn nicht schon vorher in VMM unter “Settings” erledigt, der entsprechend auf dem BMC konfigurierte und berechtigte “RunAs Account” erstellt werden. Dabei muss “Username” und “Password” dem im BMC (iRMC/iLO) konfiguriertem entsprechen.

Leider habe ich die Erfahrung gemacht, dass VMM 2012 R2 hier anscheinend immer noch einen kleinen Bug hat, der verhindert, dass die BMC Einstellungen aus der GUI auch wirklich übernommen werden.
Ein Klick auf “OK” führt also zuverlässig zum Zurücksetzen der BMC Settings auf  den unkonfigurierten Zustand, was etwas nervig ist. Mir ist es zwar nach mehrmaligem Versuchen dann gelungen die BMC IP und den User über die GUI zu Konfigurieren, aber es geht mit Powershell auch relativ einfach und ist, nicht nur wenn man das für zig Systeme machen will, auch deutlich praktischer und hat immer funktioniert, sprich wurde auch wirklich übernommen!

Ok, also wie kommt man am einfachsten an den entsprechenden Befehl?

Suchmaschine?
Viel zu aufwändig, da muss man ja wissen, wonach man sucht! Smiley

Nein, über die VMM GUI, indem man die gewünschte Konfiguration einstellt, dann aber nicht, durch einen klick auf OK ausführen lässt, sondern sich über den kleinen oft übersehenen Button unten Links “View Skript” das Powershell Skript anzeigen lässt, welches die gewünschte Konfiguration umsetzen würde!
Weil die GUI übersetzt auch nur alles in Powershell und lässt dann ein entsprechendes, automatisch erstelltes Skript für die eigentliche Konfiguration ablaufen!
(ist in Exchange und Co übrigens genauso und auch dort sehr praktisch um sich Skripte für automatisierte Konfigurationen zu “Klauen”)

Aber da wir nur die BMC Eigenschaften ändern wollen, reduzieren wir alles andere und überflüssige IDs einfach mal raus:

$vmHost = “Computername-des-Hardware-Hosts”
$bmcRunAsAccount = Get-SCRunAsAccount -Name „iRMC Administrator“
Set-SCVMHost -VMHost $vmHost  -BMCProtocol „IPMI“ -BMCAddress „192.168.1.1“ -BMCPort „623“
-BMCRunAsAccount $bmcRunAsAccount

Im Wesentlichen also der Set-SCVMHost Befehl mit Variablen gefüttert und gut ist.

Darauf aufbauend habe ich das Skript etwas erweitert, da ich ja nicht nur einen, sondern alle Hosts einer Domäne eintragen will.
Dabei habe ich mir Zunutze gemacht, dass der Kunde ein Namenskonzept für die Hosts und deren BMC hat:
Alle Host fangen mit C an und gehen mit einer Nummer weiter, die zugehörigen BMC Adapter mit einem I und dahinter dieselbe Nummer.
Also musste ich “nur” das C durch ein I ersetzen und dazu dann die passende IP abfragen! Ok…

# Alle Hosts einer Domain abfragen und in $Hosts speichern
$Hosts = Get-SCVMHost | ForEach-Object {$_.Computername}

# Für jeden dieser $Server in $Hosts folgende Schleife durchlaufen
ForEach ($Server in $Hosts)
{
# Windows Hostnamen in iRMC Hostnamen umwandeln (führendes „C“/“c“ durch „I“ ersetzen:
$irmc = $Server.ToUpper().Replace(„C“,“I“)

# IP Adressen des iRMC Adapters auslesen und in $ipAddresses speichern
$ipAddresses = [System.Net.Dns]::GetHostAddresses($irmc)
}

Soweit so gut.
Dann noch den SCVMhost Befehl oben in die Schleife einsetzen und mit den entsprechenden Variablen bei jedem Durchlauf füttern, sowie generell etwas “hübsch” machen:

<#
———————————————————————————
Add-BMCSet Skript
Fügt in SC VMM die Einstellungen für den iRMC Adapter der Hosts hinzu

Oliver Sommer, TrinityComputer.de GmbH

———————————————————————————-
#>

Clear-Host

# Dienstekonto „iRMC Administrator“ muss in VMM vorhanden sein!
$bmcRunAsAccount = Get-SCRunAsAccount -Name „iRMCAdmin“

# Alle Hosts einer Domain abfragen und in $Hosts speichern
$Hosts = Get-SCVMHost | ForEach-Object {$_.Computername}

# nur ein spezifischer Host (z.B. zum Testen des Skripts)
# $Hosts = „serv01“

# Für jeden dieser $Server in $Hosts folgende Schleife durchlaufen
ForEach ($Server in $Hosts)
{
# Windows Hostnamen in iRMC Hostnamen umwandeln (führendes „C“/“c“ durch „I“ ersetzen:
$irmc = $Server.ToUpper().Replace(„C“,“I“)

# IP Adressen des iRMC Adapters auslesen und in $ipAddresses speichern
$ipAddresses = [System.Net.Dns]::GetHostAddresses($irmc)

Write-Host iRMC Adresse von $Server lautet $irmc mit der IP $ipAddresses… -ForegroundColor Yellow
Write-Host

#iRMC Adapter in SC VMM Konfig des jeweiligen Host/Servers eintragen
Write-Host Setze iRMC Adresse für $Server auf $ipAddresses[0].IPAddressToString :  -ForegroundColor Yellow
Set-SCVMHost -VMHost $Server -BMCProtocol „IPMI“ -BMCAddress $ipAddresses[0].IPAddressToString -BMCPort „623“ -BMCRunAsAccount $bmcRunAsAccount

}

Dann klappt es anschließend auch mit dem Powermanagement der Hosts über VMM:

image  image

Shutdown wäre sicher auch ohne iRMC technisch möglich, aber vermutlich ist das nicht verfügbar, weil man den Server sonst ja anschließend nicht wieder über VMM eingeschaltet bekommt! Smiley

Die Konfiguration eines BMC in VMM ist übrigens auch Voraussetzung für Bare Metal Deployment von Hosts und weiteren coolen Funktionalitäten die ein RZ erst richtig dynamisch und weitestgehend automatisierbar machen… aber dazu irgendwann später hoffentlich mal mehr an dieser Stelle! Smiley

CDC–Cloud & Datacenter Conference Germany 2017

eingetragen in: Hyper-V, Vorträge | 0

Am 4. und 5.Mai 2017 findet die zweite CDC Germany in München in den Räumen der Microsoft Deutschland statt:

https://www.cdc-germany.de/

image

Als erfahrender Besucher von community und kommerziell betriebenen technischen Veranstaltungen und Konferenzen sticht die CDC besonders positiv hervor!

Man hat nicht das Gefühl Marketing-Foliensätze von vertrieblich getriebenen, halbtechnischen Vortragenden, wie auf so mancher Herstellerveranstaltung, präsentiert zu bekommen, sondern es werden extrem tiefgehend technische Themen betrachtet und vor allem auch Grenzen und Probleme der Produkte offen angesprochen.

Direkt durch Hersteller gestellte Vortragende machen das in der klaren Art und Weise auf Veranstaltungen leider nur sehr selten.

Trotz der notwendigen Professionalität der Veranstaltung, welche auf anderen Community Events manchmal etwas zu untergeordnet ist, kommt auch das von mir sehr geschätzte sogenannte „Networking“ nicht zu Kurz und hat reichlich Raum. Der Veranstaltungsort hat dies durch seine offene aber auch zusammenhängende Gestaltung des Vortrags- und Partnerbereichs sehr gefördert. Ich hoffe das wird in 2017 am neuen Ort in München auch wieder so gut klappen.

Mein Ticket habe ich schon am ersten Tag der EarlyBird Phase gebucht und noch weitere Mitarbeiter unserer Firma für die Reise nach München begeistern können, so dass wir mit 400% der Personen teilnehmen werden wie zuletzt! Smile

Inplace Upgrade von TP5 auf die RTM Version von Windows Server 2016

eingetragen in: 2016, Hyper-V, Windows | 1

Zum Ende der Betaphase von Windows Server 2016 stellte sich die Frage, ob unsere produktiven Testsysteme Smile alle neu aufgesetzt werden mussten oder ob man ggf. ein Inplace Upgrade von der TP5 auf RTM machen kann.

Heute hatte ich Gelegenheit dies relativ gefahrlos an einem Backupserver einfach mal zu testen:
(kurz Form des Ergebnis –> Geht!)

image

image

image

image

imageimageimageimageimageimageimage

image

Also VMs heruntergefahren und Update dann fortgesetzt.image

imageimageimage

Zur Info:
Es handelte sich um Hyper-V Hosts mit wenigen VMs drauf.

Replikationseinstellungen und auch sowas wie die Windows Server Sicherungs Einstellungen blieben erhalten und weiterhin aktiv.

imageimage

image

Powershellskript von UNC Pfad wirft "not digitally signed" Fehler

eingetragen in: GPO, Powershell, Windows | 0

Von einer UNC/Freigabe geöffnete und ausgeführte PS Skripte führen zum o.g. Fehler. Lokale Kopien derselben Skripte funktionieren einwandfrei.

Dieses Problem könnte durch eine fehlerhafte GPO der „InternetExplorer“ Settings verursacht worden sein.

Man kann unter den IE „Internetoptionen“ auf der Registerkarte „Sicherheit“ unter „lokales Intranet“ sichere „Sites“ eintragen, dort könnten z.B. die lokalen Domänen mit den UNC Pfaden eingetragen werden.
Ist diese aber leer, so ist die entsprechende GPO evtl. nicht korrekt gescoped (ggf. auf „authenticated user“).

Im vorliegenden Fall wurde die GPO zur Überarbeitung auf einen einzelnen Rechner gescoped und beim Veröffentlichen dann nicht korrekt um-/eingestellt.

SCVMM 2012 R2: "Install Virtual Guest Services" does not install current version of VMGuest Additions

eingetragen in: 2016, Hyper-V, Powershell | 0

Durch Installation u.a. der für Hyper-V empfohlenen Hotfixes aus der Liste unter https://support.microsoft.com/en-us/kb/2974503 wurden die Hyper-V Virtual Maschine Additions (aka vmguest.iso, VMAdditions, Hyper-V Additions, etc.) auf den Hyper-V Hosts (hier Hyper-V 2012 R2) aktualisiert.
Dies erfolgt z.B. durch den Hotfix 3063283.

Im vorliegenden Fall auf Version 6.3.9600.17831 oder kurz 17831.

Da SCVMM (System Center Virtual Maschine Manager 2012 R2) eingesetzt wird, sollten die VMs (virtuellen Maschinen) über die Funktion “Install Virtual Guest Services” unter “VMs and Services” aktualisiert werden.

Leider stellte sich heraus, dass VMM diesen Job zwar angeblich erfolgreich ausführte, aber die Version der “VMAdditions” der VMs sich nicht änderte, sprich auf dem alten Stand vor 17831 verblieb.

„SCVMM 2012 R2 CU8 aktualisiert die virtuellen Maschinen nicht mit der auf den Hyper-V (Datacenter 2012 R2) Hosts aktualisierten VM Guest Services, sondern anscheinend mit der vorherigen (alten) Version.

oder auch

Set-SCVirtualMaschine -VM <VMname> -InstallVirtualizationGuestServices $True

Ist zwar erfolgreich, aber aktualisiert die Guest Services nicht, aka die Versionsnummer in SCVMM bleibt gleich, auch nach einem Reboot und SCVMM Refresh der VM.“

 

Auffällig scheint das evtl. 2012 (also nicht 2012 R2) VMs sehr wohl aktualisiert werden können, da wir aber nur eine kleine Anzahl 2012er VMs haben können wir das aktuell nicht so ohne weiteres bestätigen.

Das Issue scheint als Bug schon bei MS gelandet zu sein:

https://www.experts-exchange.com/questions/28896823/How-do-I-upgrade-the-version-of-Hyper-V-Integration-Services-that-SCVMM-2012-R2-offers-to-VMs.html

Erst ein Case beim Microsoft Support brachte aber die Gewissheit, das es sich wirklich um einen bereits bekannten Bug handelt:

Bug 6653803:[RFH] : VM addition upgrades fail after patching hosts with Hyper-V hotfix 3063283

https://microsoft.visualstudio.com/DefaultCollection/WSSC/_workitems?id=6653803&_a=edit

Repro Details

1.  Please detail the exact steps needed to repro this problem. This includes:

· Detailed repro steps

· Hardware configuration

· Network infrastructure / configuration

· Operating system version

· SC product version (including UR upgrades)

a. VMM 2012 R2 UR8 on Windows Server 2012 R2.

b. Hyper-V host running Windows Server 2012 R2.

c. Guest VM running Windows Server 2012 R2.

d. Apply hotfix 3063283 on the host.

e. Shut down the VM.

f. In VMM Console, select the VM and click Install Virtual Guest Services.

g. In job history, wait for the „Change properties of a virtual machine“ job to complete.

h. Start and refresh the VM.

Expected:  VM Additions show as 6.1.7601.17514

Actual:  VM Additions show as 6.1.7601.17514

Bis auf die, im vorliegenden Fall neueren Versionsnummern 17831 deckte sich das Verhalten mit der Problemstellung beim Kunden.

Als Workaround empfiehlt MS die alternative Verteilung der VMAddtions z.B. mittels SCCM oder auf dem manuellen Wege über das Anhängen der VMGuest.iso an jede VM und dann geskripted oder manuelles Einloggen in die VM und Installieren der Additions auf dem Wege. Letzteres erfordert leider Login und Adminrechte in den VMs, die wir bei dem Kunden nicht auf allen VMs haben, weshalb dieser Workaround nicht praktikabel erschien.

Letztes haben wir uns für folgenden Workaround entscheiden, welche die gewünschte Funktionalität unter SCVMM wieder herstellt:

Manually copy vmbus.sys from vmguest.iso to the %windir%\System32\drivers folder on the Hyper-V hosts.

Später, bzw. ggf. auf Anfrage, gerne das Powershell skript zum Kopieren der vmbus.sys auf alle Hyper-V Hosts einer SCVMM Umgebung.

Hier nur mal die entscheidende Zeile, welche die Datei kopiert:

Copy-Item -Path \\Server\freigabe\quelldatei\vmbus.sys -Destination \\$VMHost\C$\Windows\System32\Drivers

Migration aller VMs eines Hyper-V Hosts per Powershell

eingetragen in: Hyper-V, Powershell, VMM | 0

Mit dem folgenden Powershell snipplet werden alle VMs eines Hyper-V Hosts (hier eines Clusterknotens, –HighAvailablity $true) auf einen anderen Hyper-V Host migriert.
Mittels des –RunAsyncronously attributes kann festgelegt werden, ob eine VM nach der Anderen oder so viele wie die Migrationseinstellungen der Host gleichzeitig zulassen migriert werden:

$SourceHost = Get-SCVMHost | where { $_.Name -eq „<souceHost-FQDN>“ }

$TargetHost = Get-SCVMHost | where { $_.Name -eq „<TargetHost-FQDN>“ }

# alle VMs des Sourcehost bestimmen

$VMs = Get-SCVirtualMachine -VMHost $SourceHost

#Schleife um alle VMs (asynchron) zu migrieren

ForEach($VM in $VMs)

{

Move-SCVirtualMachine -VM $VM -VMHost $TargetHost -HighlyAvailable $true -RunAsynchronously

}

Windows 10: Maus Stottern/ Hänger/ Ruckeln/ springt/ zuckt/…

eingetragen in: 10, Hardware, Windows | 17

Ich hatte seit einiger Zeit das interessante Phänomen, dass immer wenn ich meinen Rechner neugestartet, aus dem Ruhezustand oder Energiesparmodus aufgeweckt habe (oder einfach auch quasi gefühlt immer wenn ich anfing den Rechner zu benutzen), der Mauszeiger sich nur stotternd und mit starken Verzögerungen über den Bildschirm bewegt hat. Dabei war es egal, ob ich die Funkmaus (Microsoft Arc Touch Bluetooth) oder das Touchpad oder den TrackPoint verwendet habe. Auch ein Ausschalten einzelner oder mehrerer Zeigegeräte (Maus, Pad, Point) zeigte keine Wirkung, das Stottern blieb.
Das Problem verschwand aber sobald ich den Taskmanager (taskmgr) aufrief, z.B. über STRG+ALT+ENTF oder rechtsklick auf die Taskleiste, und im Vordergrund, also als aktive Anwendung) laufen hatte.
Sobald der Taskmanager im Hintergrund war, fing die Maus umgehend wieder an zu stottern.

image

Symptome:

  • Mauszeiger bleibt im Takt von 0,3-0,5 Sekunden „hängen“ und springt dann weiter
  • Mauszeiger bleibt stehen und bewegt sich dann soweit weiter wie die Maus bewegt wurde
  • Mauszeiger bewegt sich verzögert immer noch weiter bis zur Endposition, obwohl das Zeigegerät schon lange in Ruhe ist (nicht mehr bewegt wurde)
  • sobald der Taskmanager aufgerufen wird und als aktive Anwendung fokussiert ist, verschwindet das Stottern kurzzeitig, kehrt aber zurück sobald der Fokus nicht mehr auf dem Taskmanager liegt

Erinnert gefühlt habe ich mich dabei an frühere Erfahrungen mit Remote KVM Lösungen wie iLO/IRMC/VNC/RDP/Teamviewer/etc., wenn eine sehr langsame bzw. mit hohen Latenzen behaftete Internetverbindung oder WAN Verbindung wie ISDN zu dem entfernten Rechner bestand.
Ein Arbeiten mit diesen Sprüngen und Verzögerungen der Maus war nahezu unmöglich bzw. erforderte sehr viel Geduld bei der Positionierung derselben.

Nachdem das Problem auch mit dem Windows 10 TH2 nicht verschwand, sondern eher (gefühlt) noch schlimmer wurde fand ich dann heute, nach einiger Recherche, die Lösung zu meinem Problem, welches wohl auch viele andere, unter anderem viele Besitzer von Acer PCs/AllinOne, HP und Lenovo Geräten haben, in diesem englisch sprachigen Forumsbeitrag:
http://www.tenforums.com/drivers-hardware/14107-windows-10-mouse-lagging.html

Kurz gesagt ist eine App des Soundkarten Treibers der Firma Realtek für das Problem verantwortlich, die FMAPP.exe unter c:\Program Files\Realtek\Audio\HDA\.

Diese fand ich im Taskmanager unter den Prozessen:

image

 

per Rechtsklick mit der, dort ja nicht stotternden, Maus kann man den Task beenden, was bei mir zu einer umgehenden Normalisierung der Mausbewegungen führte:

image

 

Damit die App nicht beim nächsten Windows Start automatisch wieder gestartet wurde, habe ich die ausführbare Datei im oben genannten Pfad (c:\Program Files\Realtek\Audio\HDA\) in FMAPP.exe.org, also um die Endung .org erweitert, umbenannt.

Ich habe, so wie viele Benutzer des Forums auch berichteten, bisher keine Nachteile festgestellt, insbesondere die Soundausgabe funktioniert bisher weiterhin wie gewünscht und erwartet.

DNS Konfiguration aller Active Directory Directory Services (AD DS) Computer ändern

eingetragen in: Core, Powershell, Windows | 0

Die Aufgabe hier war letztlich verhältnismäßig simpel:

Ändere (ersetze) die bisherige DNS Server Konfiguration aller VMs einer Umgebung in vorgegebene neue DNS Server.

Eine tolle Aufgabe für ein kleines PowerShell-Skript (oder einen Praktikanten 🙂 ) dachte ich mir und schrieb das folgende PS Script zusammen:
(inline Kommentare sollten zur Erläuterung ausreichend sein)

Clear-Host
# AD Computer Suchkriterien definieren, damit nicht alle geändert werden, nach Bedarf anzupassen
# Get—ADComputer -FiIter {OperatingSystem —Like ‚*Server*‘ -and Name -like „VM*“‚} select —Expand DNSHostName
$ServerVMs = Get—ADComputer -Filter {OperatingSystem —Like ‚*Server*‘ -and Name -like ‚VM*‘} | select —Expand DNSHostName

# neue DNS Server in Array SDNS schreiben
# weitere DNS Server durch weitere +=  Zeilen hinzufügen falls nötig!

$DNS =@()
$DNS += „DNS-Server1-IP-Adresse“
$DNS += „DNS-Server2-IP-Adresse“

ForEach ($ServerVM in $ServerVMs)
{
Write-Host Alle NICs in $ServerVM abfragen
Get-WmiObject Win32_NetworkAdapterCOnfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $false}
$NICs = Get-WmiObject Win32_NetworkAdapterCOnfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $false}

Write-Host DNS Servereinträge in allen NICs von $ServerVM ändern

ForEach ($NIC in $NICs)
{
Write-Host Bisherige DNS Server:
$NIC.DNSServerSearchOrder

# neue DNS Server in Netzwerkkarten Konfiguration eintragen
$NIC.SetDNSServerSearchorder($DNS)
}
}

Servermanager in Windows Server 2016 TP3 Core installieren

eingetragen in: 2016, Core, Powershell, Windows | 0

In der aktuellen TP3 von Windows Server 2016 gibt es (leider) die MinimalGUI Setupoption nicht mehr, sondern nur noch “Core” oder “Full GUI”, wobei letzteres alles mögliche installiert, also z.B. auch Handschrifterkennung und Mediageschichten, die für eine RemoteDesktop (Terminalserver) Installation sinnvoll sein mögen, aber nicht für die meisten anderen Server:

image

image

Bei Core gibt es den Servermanager nicht, der in der MinimalGUI Variante vorheriger Betaversionen autoamtisch installiert wurde.
ich habe die MinimalGUI Variante zu schätzen gelernt, da man damit eigentlich alles administrative machen konnte was ich bisher benötigt habe, ohne viel Ballast in der Installation zu haben.

Also habe ich mit dem aktuellen TP3 Build 10514 einfach wieder die Variante ohne GUI (Core) installiert und mit folgendem Befehl die Servermanager GUI nachinstalliert:

Install-WindowsFeature -Name RSAT -Source wim:D:\sources\install.wim:4

clip_image001

Dann z.B. mittels “shutdown –r –t 0” neustarten und nach dem Anmelden erscheint nicht nur die administrative CMD.exe, sondern auch der ServerManager:

image

Von hier ausgehend kann man dann wie bisher gewohnt (MinimalGUI) den lokalen und remote Server administrieren.

HowTo clean your disk from previous “Windows” folders like $Windows.~BT and Windows.old

eingetragen in: 10, Windows | 0

Open Start menu and type (search) for “Free up”, which should return the “Free up disk space by deleting unnecessary files” control panel item:

image

 

Start and let it scan your disk for files that might be deleted without harming the functionality of your system.

It will return a list like this:

clip_image001

If you also want to remove the windows.old and .bt folder you need to also scan for “Systemfiles” using the button that requires administrative rights.

It will return a list of potentially unneeded files and folders and lets you pick and choose which ones you want to keep or remove from your installation.

One of these should be “Previous Windows installation(s)” which has had a size of 17.7GB and eventually even 31.3GB on my disk as you can see here:

image

 

image

 

Also the “temporary Windows installation files” might be safely deleted and seem to correspondent with the $Windows.~BT folder:

image

Clicking ok, let’s you think about it again by asking the “are u sure” question:

image

 

image

 

image

image

It might not totally remove the Windows.old folder, but almost. (it left some files with a total of 1.4MB behind on my computer, which I moved to a TEMP folder to get them out of sight on the root of C till I have time to take over ownership and than be able to delete those leftovers, too.

How to ReOpen the command prompt on a core server (including nested RDP session scenario)

eingetragen in: Allgemein, Core | 0

Solution for nested RDP session, as discribed below, right here:
Type <CRTL> + <ALT> + <END> on the On-Screen Keyboard inside the first RDP session, Windows Security will open in the core servers RDP session and you can open the core servers Task Manager from there.

 

the initial and only GUI interface on a Windows Server installed as core server (server without a GUI) is an administrative command prompt.

If one accidentily closed that command prompt, there is no GUI element left that you might use to reopen that command prompt. At least on first sight it looks like it…

Well if you are sitting right upfront that server it’s quite easy to bring back that command prompt, by simply pressing <CRTL> + <ALT> + <DELETE>, from there click the link to run “task manager” and from there go to “file” and “run new task”.
Now t
ype “cmd” in the “Create new task” window and you’d get your admin cmd.exe back on screen instandly! Smiley

 

Well all that is a little more complicated if you’re in an RDP session!
…ok, not really Smiley … in  a simple RDP session to a core server all you need to change in the above procedure is that you want to press <CRTL> + <ALT> + <END> to get to that Windows Security screen to run Task Manager and from there on it’s the same ballgame again.

 

Ok, but what if you’re using a cascaded RDP session aka you’re using an admin hop server aka bastion host, Bastion RDP server?

You’d have to deal with the RDP Session in an RDP session (nested RDP session) issue that doesn’t send <CRTL> + <ALT> + <DELETE> nor <CRTL> + <ALT> + <END> to the most inside RDP session (your core server) but to the admin hop or your personal workstation.

I just found one little hint on how to get the CMD up and running again quite easily.

First:
One easy way to get this done is to force a logoff of your session on the core server and relogin.
This is easily done by another user account loging into the core server and “signing off” your users session using Task manager (type “taskmgr” in command prompt).

Second:
If you don’t  have another account or another collegue to signoff your account from that server, you can use this option:

 

In the admin hop RDP session open the start menu and search for “on” which should bring up the “on-Screen Keyboard” right away as result.

 

 

pic22779

 

run the OSK

 

pic08951

 

and maximise the core servers RDP session behind it. 

now type <CRTL> + <ALT> + <END> on the OSK and Windows Security will open in the core servers RDP session and you can open the core servers Task Manager from there. 

Then again:
Use “File” and “Run new task” to start CMD.exe again.

 

pic13782

 

and there you go with a fresh administrative command prompt.

 

Powershell: Uninstall a software/program

eingetragen in: Powershell, VMM | 3

to uninstall a software, from for example a core server, using powershell you may use these script snipplets I found today having the need to uninstall a program rom a non GUI server.

At first you may want to list all installed programs:

Get-WmiObject -Class Win32_Product

Look for the software to uninstall in that list and copy a significant part of the “Name” to clipboard.

(i was looking to uninstall the “MS VMM DHCP Server (x64)” stuff, so I entered the following line to filter just for that:

Get-WmiObject -Class Win32_Product -Filter „Name like ‚%DHCP Server%'“

and then added the uninstall routine to the command to finallize the removal of the software:

Get-WmiObject -Class Win32_Product -Filter „Name like ‚%Microsoft System Center Virtual Machine Manager DHCP Server (x64)%'“ | ForEach-Object { $_.Uninstall()}

Finally you may want to check that the software is really not listed anymore using:

Get-WmiObject -Class Win32_Product

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

eingetragen in: Allgemein, Powershell, VMM | 0

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

eingetragen in: Allgemein, Powershell, VMM | 0

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

eingetragen in: Clustering, Core, Powershell | 0

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
     }

}