Mir ist kürzlich bei einem Server das Sicherungsziel der täglichen Windows Serversicherung gestorben, da dieser (sehr einfache) Hyper-V-Server nur auf eine USB-Disk sichert, deren Speicherplatz per iSCSI an die VMs durchgereicht wird. Dies hat zur Folge, dass die Windows Serversicherung die dort abgelegten Sicherungen für alle Ewigkeit weiterhin anzeigt und mitzählt. Bei dem Versuch einer Wiederherstellung von Daten auf der gestorbenen Platte würde angezeigt werden, dass das Sicherungsziel offline ist und man hätte die – praktisch nicht mehr umsetzbare – Möglichkeit, die Daten verfügbar zu machen.
Wenn man jetzt die Infos über die nicht mehr vorhandenen Sicherungen löschen will, um eine saubere “Statistik” zu haben, kann man sich eines PowerShell-Cmdlets bedienen: Remove-WBBackupSet.
Der Parameter –KeepVersions gibg dabei an, wieviele der letzten Sicherungen man behalten möchte. Alternativ kann man mit –DeleteOldest die X ältesten Sicherungen entfernen.
Bei dem Aufruf wird es aber sehr wahrscheinlich zu vielen Fehlern kommen, wie man im Screenshot sieht. Da die Sicherungen nicht mehr erreichbar sind, das Cmdlet aber eigentlich die Files dazu löschen würde, muss man sich hier zusätzlich des –Force Parameters bedienen:
Dabei wird die Tatsache, dass die Sicherungen auf der ausgefallenen Platte nicht mehr erreichbar sind, ignoriert und nur der Verweis auf diese Sicherungen entfernt.
Mit dem Aufruf Get-WBBackupSet kann man sich nochmal ausgeben lassen, wieviele Sicherungen Windows Server Backup “kennt”:
Wenn man auf einem Hyper-V Server (gemeint ist der kostenlose Server, der ohne GUI, also vergleichbar einer Server Core Installation, und nur mit Hyper-V as Rolle betrieben werden kann) den SNMP-Dienst installiert hat, muss diese noch konfiguriert werden.
Die Installation selber kann remote über den Servermanager oder lokal über PowerShell erfolgen:
Nach der Installation würde man auf einem grafischen Server jetzt einfach die Dienste-Konsole oder die Computerverwaltung öffnen und den Dienst dort entsprechend konfigurieren. Die grafischen Werkzeuge stehen aber lokal nicht zur Verfügung. Verwendet man jetzt bspw. die Computerverwaltung von einem grafischen Server aus und verbindet sich von dort mit dem Hyper-V Server bzw. dem als Server Core installierten Server, wird man leider feststellen, dass dort einige Optionen im SNMP-Dienst fehlen:
Abhilfe schafft hier die Installation des SNMP-Features auch auf der Maschine, von der aus man mit dem grafischen Werkzeug arbeiten möchte. Danach kann man auch remote die passenden Einstellungen vornehmen:
Wer einen Windows Server 2012 R2 als Core-Server oder den kostenfreien Hyper-V-Server 2012 R2 einsetzt, dem könnte folgendes Problem begegnen: Auf dem Server selber gibt es bekanntlich keine GUI und demnach auch keinen Gerätemanager. Und seit 2012 R2 lässt sich dieser auch nicht remote von einem grafischen Server aus ansprechen!
Was nun also tun, wenn man Treiber installieren/aktualisieren/entfernen will? Dazu möchte ich hier einige Kommandos als Hilfestellung zusammentragen:
Installation aller Treiber des aktuellen Verzeichnisses in das Treiber-Repository:
In einem weiteren YouTube-Video zeige ich euch, wie ihr einen Hyper-V Cluster mit dem Windows Server 2012 R2 oder 2016 aufbauen könnt. Das ist leichter als man denkt! Viel Spaß beim Anschauen.
Mit Hilfe des System Center Configuration Manager 2012 / 2012 R2 ist es sehr einfach möglich, Windows- und Microsoft-Updates an die Clients und Server des eigenen Netzwerkes zu verteilen. Im Hintergrund arbeitet hierzu der bekannte WSUS-Dienst, welcher wiederum mit Microsoft kommuniziert, um die Updates von dort zu beziehen.
Wäre es nicht auch gut, wenn man auf ähnliche Weise auch Anwendungen von anderen Herstellern patchen könnte? JA! Und man kann!
Das einzige was man neben WSUS und dem SCCM braucht, ist der System Center Update Publisher, kurz SCUP. Mit diesem kann man Updates anderer Hersteller aus “externen Katalogen” beziehen. Und das beste: SCUP ist kostenlos!
Im Folgenden möchte ich die Installation und Einrichtung von SCUP zeigen. Ausgangslage ist ein installierter SCCM mit einer einzigen Primary Site (stand-alone), einem installierten WSUS und einem darauf laufenden Software Update Point (SUP).
Installation SCUP
Als erstes muss SCUP heruntergeladen werden. Dies geht über diese Quellen:
Nach dem Download kann die Installation durchgeführt werden, welche jedoch Admin-Rechte benötigt:
Wenn es sich bei dem WSUS-Server um einen Windows Server 2008 R2 oder älter handelt, dan ist die Installation eines Patches nötig, der während des SCUP-Setup angeboten wird:
Auf einem Windows Server 2012 / 2012 R2 ist dieses Patch nicht nötig – hier läuft WSUS 4.0!
Konfiguration WSUS-Berechtigungen
Um nun überhaupt Updates via SCUP auf dem WSUS veröffentlichen zu können, ist noch etwas Vorarbeit nötig. Diese Vorgänge sind etwas genauer hier dokumentiert (dies betrifft idR nur den Windows Server 2012 / 2012 R2):
Regedit.exe, dort bis HKEY_CLASSES_ROOT\AppID\{8F5D3447-9CCE-455C-BAEF-55D42420143B} durchhangeln und dann den Eigentümer von diesem Pfad ändern sowie für “SYSTEM” und die “Administratoren” den Vollzugriff vergeben (Durch einen Klick auf die Bilder werden diese in größerer Auflösung gezeigt):
Einrichtung SCUP
Nun kann der “System Center Update Publisher” über das Startmenü gestartet werden – dies sollte aber “Als Administrator” geschehen, da es sonst später zu einem Fehler kommt / kommen kann.
Dieser Fehler tritt später auf, wenn man die SCUP-Konsole ohne die nötigen Rechte startet:
Als erstes sind die Optionen zu öffnen:
Dort muss nun die Verbindung zum WSUS-Server konfiguriert werden (dabei Port beachten – WSUS 4.0 läuft auf 8530 (non-SSL) bzw. 8531 (SSL)):
Nun fehlt noch ein Zertifikat zum signieren der Updates. Hier kann auch ein selbstsigniertes Zertifikat erzeugt und verwendet werden. Dies geschieht über den “Create”-Button:
Dieses Zertifikat muss später noch weiter “behandelt” werden. Als nächster Step wird im SCUP die Verbindung zum SCCM definiert:
Zertifikat passend einbinden
Das WSUS-/SCUP-Zertifikat muss nun in die “Trusted Publishers” (Vertrauenswürdige Herausgeber) und die “Trusted Root Certificates” (Vertrauenswürdige Stammzertifizierungsstellen) des Computer-Kontos (WSUS/SCUP-Server) importiert werden, vorher muss es natürlich exportiert werden:
Updates über SCUP an den WSUS veröffentlichen
Nun können die ersten Updates über den SCUP veröffentlicht werden. Dazu muss zunächst ein Katalog hinzugefügt werden:
Beispielhaft verwende ich hier den “Adobe Reader X” Katalog:
Danach können die Updates aus diesem Katalog in den SCUP importiert werden:
Nun können die neuen Updates zu einer neuen Veröffentlichung hinzugefügt werden:
Diese neue Veröffentlichung (Bei mir heißt sie “März 2015”) kann nun veröffentlicht werden. Dazu wird sie unter “Publications” ausgewählt, die jeweiligen Updates markiert und dann auf “Publish” geklickt.
Dabei sollten die Updates vom SCUP signiert werden:
Updates über SCCM verteilen
Nun kann im SCCM eine erste Synchronisierung durchgeführt werden. Diese ist nötig, damit der SUP (SCCM) “erfährt”, dass es nun auch Adobe als neuen Hersteller und Adobe Reader als Produkt gibt:
Um den Vorgang zu beobachten bietet der SCCM ein eigenes Werkzeug, alternativ würde auch CMTrace gegen die WSyncMgr.log funktionieren:
Die letzte Meldung zeigt an, dass die Synchronisierung abgeschlossen ist. Nun kann das neue Produkt (in meinem Fall der Adobe Reader) für die Verteilung durch den SUP aktiviert werden:
Dabei ist auch der Reiter “Klassifizierungen” zu beachten – wenn das gewünschte Update ein “Sicherheitsupdate” ist, SUP aber nur “Wichtige Updates” synchronisiert, dann wird man nicht zu einem positiven Ergebnis kommen.
Nun ist noch einmal eine Synchronisierung des SUP nötig, damit dieser die bekannten Updates vom WSUS “kennenlernt”.
Danach stehen die Updates, in meinem Fall für den Adobe Reader, im SCCM wie ein reguläres Windows Update zur Verfügung und können verteilt und bereitgestellt werden:
In den Windows Bereitstellungsdiensten gibt es die Möglichkeit, ein “Aufzeichnungsabbild” aus einem regulären “Startabbild” zu erzeugen. So natürlich auch beim aktuellen Windows Server 2012 R2:
Häufig kommt es dann aber bei dieser Server-Version später beim Booten der aufzuzeichnenden Maschine zu einem Fehler:
Dieser Fehler tritt dann auf, wenn man:
auf einem Windows Server 2012 R2 (mit oder ohne Update1) im WDS ein Startabbild (Boot Image) auf Basis eines Windows Server 2012 R2 MIT Update1 oder Windows 8.1 MIT Update1 hinzufügt (dabei ist es dann später egal, auf welchem Startabbild das Aufzeichnungsabbild basiert)
auf einem Windows Server 2012 (“R1”) im WDS ein Startabbild auf Basis eines Windows Server 2012 R2 mit Update1 oder Windows 8.1 mit Update1 erzeugt
Der Fehler würde NICHT auftreten, wenn man vor dem Erzeugen des Aufzeichnungsabbildes noch nie ein Startabbild von Windows 8.1 Update1 oder Windows Server 2012 R2 Update1 importiert hatte.
Natürlich kann man den Fehler aber auch anderweitig umgehen bzw. beheben:
Dazu hinterlegt man zunächst das gewünschte Startabbild (dabei spielt es keine Rolle, ob bisher ein Update-1-Startabbild hinterlegt wurde oder nicht, das zu hinterlegende Abbild selbst darf auch von einer Update-1-Version stammen):
Danach erzeugt man aus diesem ein Aufzeichnungsabbild:
Dabei sollte man dass entstehende Abbild nicht direkt dem WDS Server hinzugefügt wird:
Anschließend muss das entstandene WIM-File (in meinem Beispiel “C:\aufz.wim”) mittels DISM gemountet werden:
Für das Mounten verwendet man einen Aufruf in dieser Form:
(Achtung: Keine Leerzeichen nach den Doppelpunkten!)
Im Anschluss kann die Datei direkt wieder “unmounted” werden (ohne dass sie dabei inhaltlich wirklich verändert wurde):
Hierzu wird folgender Aufruf verwendet:
dism /Unmount-Wim /MountDir:C:\mount /commit
Das nun neu erzeugte WIM-File kann jetzt als funktionsfähiges Aufzeichnunge-/Startabbild auf dem WDS-Server hinterlegt werden:
Nun kann eine (Test-)Maschine per PXE gebootet werden, es sollte nun, da es mehrere Startabbilder gibt, eine Auswahl möglich sein:
Wenn man das Aufzeichnungsabbild gewählt und die Maschine komplett gebootet hat sollte in etwa folgendes Menü zu sehen sein:
Nun kann die Festplatte der (Test-)Maschine aufgezeichnet werden. Wichtig ist dabei allerdings, dass dies nur funktioniert, wenn man das dort laufende Betriebssystem vorher mit sysprep vorbereitet hat.
Wenn man einen DHCP-Server betreibt, dann sollte dies bevorzugter Weise in einer Domäne geschehen – also mit dem DHCP-Server als Mitglied des Active Directory. Dort benötigt dieser eine Autorisierung, welche dafür sorgt, dass dieser Server dann auf eingehende Anfragen (DHCP Request) reagiert. Solange er nicht autorisiert ist, vergibt er auch keine Adressen. Soweit so gut.
Wenn man einen DHCP-Server NICHT in Active Directory integriert, kann man ihn auch nicht autorisieren, er verrichtet dennoch seine Dienste – bis er auf einen autorisierten Server trifft!
Dann nämlich wird der nicht autorisierte Server (der nicht Mitglied der Domäne ist) seinen Dienst einstellen und selbst wenn man ihn wieder manuell aktiviert sich sofort wieder abschalten.
Damit ist es also nicht so ohne Weiteres möglich, zwei DHCP-Server im selben Netz zu betreiben. Nun kann es aber sein, dass genau das gewünscht ist – weil die Server z.B. Adressen für unterschiedliche MAC-Adressen verteilen. Hier muss man also eingreifen und den nicht-autorisierten DHCP Server daran hindern, sich abzuschalten.
Das “Zauberwort” hier heißt “Rogue Detection” – und genau die muss deaktiviert werden.
Dies geht nicht über eine GUI, sondern muss über eine Registrierungswert geändert werden. Dieser heisst
Wenn man mit einem Webserver zu einem anderen Provider wechselt oder aus sonstigen Gründen neue (öffentliche) IP Adressen zugewiesen bekommt, dann müssen natürlich auch die entsprechenden DNS-Einträge geändert werden. Wenn es sich hierbei nur um eine Hand voll handelt, könnte man dies auch manuell machen. Ab einer gewissen Menge ist das einfach nicht mehr praktikabel, da es a) zu lange dauert und b) auch sehr fehleranfällig wäre.
Als sinnvolle Lösung bietet sich hier die PowerShell an – vorausgesetzt, man hat einen Microsoft Windows Server als DNS-Server und auf diesem das entsprechende DNSServer Modul für die PowerShell verfügbar.
Das Skript, welches am Ende des Beitrages zum Download angeboten wird, sieht so aus:
<#
.Synopsis
This script changes DNS A Records according to a CSV file - use at your own risk!
.DESCRIPTION
This script changes DNS A Records according to a CSV file.
The csv file should look like this:
"OldIP","NewIP"
"1.2.3.4","5.6.7.8"
"2.4.6.8","1.3.5.7"
to change all DNS records with "1.2.3.4" as value for "5.6.7.8" and "2.4.6.8" for "1.3.5.7"
.EXAMPLE
Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt
Replaces the DNS A records on the localhost DNS server according to the CSV-File H:\OldAndNewIps.txt
.EXAMPLE
Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt -DNSServer mydns.domain.local -Verbose
Replaces the DNS A records on the DNS server "mydns.domain.local" according to the CSV-File H:\OldAndNewIps.txt and writes verbose output
#>Param([Parameter(Mandatory=$True)][ValidateScript({Test-Path$_-PathType'Leaf'})][string]$CSVFile,[string]$DNSServer="localhost")Write-Warning"This script will possibly change a lot of DNS records. If you wish to cancel, press [CTRL]+[C], otherwise press [Enter]!"Read-Host# just in case of old PowerShell
Import-Module DNSServer
$CSVData=Import-CSV$CSVFile$OldDNSRecordData=$CSVData.OldIP
$NewDNSRecordData=$CSVData.NewIP
$AllDNSZones=(Get-DnsServerZone -ComputerName$DNSServer|Where-Object IsReverseLookupZone -eq$False).ZoneName
$TotalChanges=0ForEach($CurrentDNSZonein$AllDNSZones){Write-Verbose"Processing current zone $CurrentDNSZone..."$AllDNSARecordsInZone= Get-DnsServerResourceRecord -ZoneName $CurrentDNSZone-RRType A -ComputerName$DNSServerWrite-Verbose"Found $(($AllDNSARecordsInZone | Measure-Object).Count) DNS Records in current Zone"ForEach($CurrentRecordin$AllDNSARecordsInZone){for($i=0; $i-lt$OldDNSRecordData.Length; $i++){If($CurrentRecord.RecordData.IPv4Address -eq$OldDNSRecordData[$i]){Write-Verbose"Found an old DNS Record:"Write-Verbose"$($CurrentRecord.HostName) with $($CurrentRecord.RecordData.IPv4Address) in Zone $CurrentDNSZone"$NewRecord=$CurrentRecord.Clone()$NewRecord.RecordData.IPv4Address =$NewDNSRecordData[$i]
Set-DnsServerResourceRecord -OldInputObject $CurrentRecord `
-NewInputObject $NewRecord `
-ZoneName $CurrentDNSZone `
-ComputerName$DNSServer$TotalChanges++}}}}Write-Host"Changed Records: $TotalChanges"
<#
.Synopsis
This script changes DNS A Records according to a CSV file - use at your own risk!
.DESCRIPTION
This script changes DNS A Records according to a CSV file.
The csv file should look like this:
"OldIP","NewIP"
"1.2.3.4","5.6.7.8"
"2.4.6.8","1.3.5.7"
to change all DNS records with "1.2.3.4" as value for "5.6.7.8" and "2.4.6.8" for "1.3.5.7"
.EXAMPLE
Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt
Replaces the DNS A records on the localhost DNS server according to the CSV-File H:\OldAndNewIps.txt
.EXAMPLE
Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt -DNSServer mydns.domain.local -Verbose
Replaces the DNS A records on the DNS server "mydns.domain.local" according to the CSV-File H:\OldAndNewIps.txt and writes verbose output
#>
Param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_ -PathType 'Leaf'})]
[string]$CSVFile,
[string]$DNSServer = "localhost"
)
Write-Warning "This script will possibly change a lot of DNS records. If you wish to cancel, press [CTRL]+[C], otherwise press [Enter]!"
Read-Host
# just in case of old PowerShell
Import-Module DNSServer
$CSVData = Import-CSV $CSVFile
$OldDNSRecordData = $CSVData.OldIP
$NewDNSRecordData = $CSVData.NewIP
$AllDNSZones = (Get-DnsServerZone -ComputerName $DNSServer | Where-Object IsReverseLookupZone -eq $False).ZoneName
$TotalChanges = 0
ForEach($CurrentDNSZone in $AllDNSZones)
{
Write-Verbose "Processing current zone $CurrentDNSZone..."
$AllDNSARecordsInZone = Get-DnsServerResourceRecord -ZoneName $CurrentDNSZone -RRType A -ComputerName $DNSServer
Write-Verbose "Found $(($AllDNSARecordsInZone | Measure-Object).Count) DNS Records in current Zone"
ForEach ($CurrentRecord in $AllDNSARecordsInZone) {
for($i=0; $i -lt $OldDNSRecordData.Length; $i++){
If($CurrentRecord.RecordData.IPv4Address -eq $OldDNSRecordData[$i]) {
Write-Verbose "Found an old DNS Record:"
Write-Verbose "$($CurrentRecord.HostName) with $($CurrentRecord.RecordData.IPv4Address) in Zone $CurrentDNSZone"
$NewRecord = $CurrentRecord.Clone()
$NewRecord.RecordData.IPv4Address = $NewDNSRecordData[$i]
Set-DnsServerResourceRecord -OldInputObject $CurrentRecord `
-NewInputObject $NewRecord `
-ZoneName $CurrentDNSZone `
-ComputerName $DNSServer
$TotalChanges++
}
}
}
}
Write-Host "Changed Records: $TotalChanges"
Das Skript durchläuft alle Forward-DNS-Zonen und prüft dabei nacheinander alle vorhandene A-Records gegen die Liste der zu ändernden Einträge. Wenn ein entsprechender Eintrag gefunden wird, wird für diesen die IP-Adresse gegen die neue ausgetauscht. Am Ende gibt das Skript aus, wieviele Einträge insgesamt geändert wurden. Aus Sicherheitsgründen ist nach dem Start noch einmal zu bestätigen, dass das Skript seine Arbeit verrichten soll.
Das fertige Skript kann hier heruntergeladen werden:
Wenn man in einer Hyper-V VM einen Blick auf den belegten bzw. freien RAM wirft, dann wird man häufig feststellen, dass nicht mehr viel übrig ist – und zwar dann, wenn man “Dynamic Memory”, den “Dynamischen Arbeitsspeicher” aktiviert hat. Dieser sorgt dafür, dass eine VM die Menge an Arbeitsspeicher bekommt, die sie aktuell benötigt – zumindest, solange noch Speicher frei ist und sich die VM in den vom Admin gesteckten Grenzen bewegt. So kann man seit dem Windows Server 2012 bzw. seit Hyper-V 3.0 drei verschiedene Werte konfigurieren:
Es lässt sich neben dem Startwert (Wieviel RAM bekommt die VM, wenn sie eingeschaltet wird?) weiterhin festlegen, wieviel die VM mindestens haben muss (Sie kann nie weniger haben, als hier festgelegt ist) und welche Menge ihr maximal zur Verfügung stehen könnte (Vorausgesetzt, es ist genügend RAM vorhanden; hier lässt sich auch ein Wert festlegen, der über dem insgesamt vorhandenen RAM liegt).
Bei Bedarf kann der “Minimale RAM” auch unter dem “Startwert” liegen – dies ist vor allem dann sinnvoll, wenn die VM während des Starts und der Anfangszeit nach dem Boot viel Speicher benötigt, um z.B. Dienste und Anwendungen zu starten, dann im Alltagsbetrieb aber mit weniger auskommt.
Nehmen wir nun an, eine VM hat folgende Konfiguration:
Start: 2GB
Min: 512MB
Max: 3GB
Nun wird sie also beim Einschalten zunächst 2GB bekommen, nach dem erfolgreichen Start ihres Betriebssystems den tatsächlichen RAM-Bedarf an Hyper-V melden und Hyper-V weist der VM dann diesen Bedarf plus einen Sicherheitsaufschlag (den “Arbeitsspeicherpuffer”) zu. Dieser ist nötig, damit die VM nicht jedes weitere benötigte Megabyte speicher einzeln anfordern muss, sondern dies immer “paketweise” tun kann.
Benötigt die VM nun mehr, dann bekommt sie mehr – solange, bis entweder das Maximum der VM-Konfiguration erreicht oder der RAM des Host-Systems voll ist. Einem System im laufenden Betrieb mehr RAM zuzuweisen ist nicht so kompliziert und ging bereits lange vor dem Virtualisierungszeitalter (ja, da musste man dann noch echte Speicherriegel in den Server stecken!).
Spannender wird der Vorgang, einer VM Speicher wegzunehmen, z.B. wenn sie eben nach dem Starten weniger Speicher benötigt, als im Startwert festgelegt. Wirklich Speicher “wegnehmen” kann man nicht. Dies wird durch eine Technik namens “Balooning” gelöst. Wenn der VM nun z.B. 512MB RAM weggenommen werden sollen, dann wird stattdessen in der VM (bzw. in deren Speicherbereich) eine “Ballon aufgeblasen”, der diese 512MB RAM belegt – die VM glaubt also, der Speicher wäre weiterhin vorhanden, aber aktuell belegt. Der Hypervisor “weiss” nun, dass er diesen RAM anderweitig vergeben kann, da er ja nicht wirklich belegt ist. Soll die VM wieder mehr Speicher bekommen, wird der Ballon stückweise kleiner gemacht, bis er verschwindet.
(In der Abbildung sehen wir eine VM, die nach dem Start, der mit 2GB RAM durchgeführt wurde, nur noch 661MB benötigt und inkl. Aufschlag 788MB RAM zugewiesen bekommen hat)
Soweit die Technik, die in der Praxis sehr gut funktioniert. Jedoch hat sie einen Haken: Die VM im obigen Beispiel, welche nach dem erfolgreichen Start einen RAM-Bedarf von bspw. 661MB an Hyper-V meldet und 20% “Aufschlag” bekommt, soll nun 788MB RAM zugewiesen bekommen (Also 1260MB weniger als beim Start). In der Realisierung sieht sie weiterhin ihre 2GB – davon aber einmal die 1260MB Differenz (den “Ballon”) plus den tatsächlichen RAM-Bedarf (also 661MB) belegt. In der Konsequenz sind als (z.B. im TaskManager) 1921MB (1,87GB) belegt – von 2048MB insgesamt – also nur noch ca. 6% frei!
Der Taskmanager innerhalb der VM zeigt etwa zur selben Zeit, zu der der vorherige Screenshot erzeugt wurde, einen RAM-Verbrauch von 1,8GB und freien Speicher in Höhe von 204MB. Das hier etwas mehr RAM frei ist als bei der Rechnung oben liegt daran, dass die VM etwas mehr Speicherbedarf an Hyper-V meldet als tatsächlich bereits belegt sind.
Eine entsprechende Serverüberwachung, die es nicht besser weiss, meldet nun also, dass der RAM zu Neige geht. Das Fatale dabei ist aber, dass wenn man dieser VM z.B. einen größeren Startwert gibt, bspw. 3GB, dann wird die Rechnung noch schlimmer:
3072MB beim Start
Nach dem Start 661MB belegt, 788MB zugewiesen
Ballon iHv 2284MB
Als belegt zu sehender Speicher: 2945MB (Ballon + 661MB tatsächlicher Bedarf)
Übrig bleiben dann 127MB (Der Puffer) – was hier nur noch etwa 4% (statt 6% bei 2GB Start-RAM) entspricht!
Dies geschieht, obwohl die VM augenscheinlich mehr RAM hat (oder zumindest haben KÖNNTE) und immer noch den selben Bedarf (von 661MB) hat! Hier darf man sich also nicht täuschen lassen.
Als Lösung könnte man den RAM-Verbrauch der VMs mittels PowerShell analysieren und dann bspw. bei Unterschreitung eines Schwellwertes bzgl. des freien RAMs alamieren. Ein solcher Aufruf, der den freien RAM aller VMs in Prozenten zeigt, könnte dabei so aussehen:
Zum Kopieren:
1
2
3
4
5
6
Get-VM |Where DynamicMemoryEnabled |Where State -eq"Running"Format-Table Name,@{n='Benötigt(GB)';e={$_.MemoryDemand/1GB};FormatString='N3'},@{n='Zugewiesen(GB)';e={$_.MemoryAssigned/1GB};FormatString='N3'},@{n='Frei/Aktuell (%)';e={100-($_.MemoryDemand/$_.MemoryAssigned*100)};FormatString='N2'},@{n='Frei/Max (%)';e={100-($_.MemoryDemand/$_.MemoryMaximum*100)};FormatString='N2'}-AutoSize
Get-VM | Where DynamicMemoryEnabled | Where State -eq "Running"
Format-Table Name,
@{n='Benötigt(GB)';e={$_.MemoryDemand/1GB};FormatString='N3'},
@{n='Zugewiesen(GB)';e={$_.MemoryAssigned/1GB};FormatString='N3'},
@{n='Frei/Aktuell (%)';e={100-($_.MemoryDemand/$_.MemoryAssigned*100)};FormatString='N2'},
@{n='Frei/Max (%)';e={100-($_.MemoryDemand/$_.MemoryMaximum*100)};FormatString='N2'} -AutoSize
Die Spalte “Frei/Aktuell” liefert einen Wert, wieviel Speicher bezogen auf den aktuell zugewiesenen Wert frei ist (dieser Wert sollte sich in etwa in der Größe des Speicherpuffers bewegen, solange genügend RAM verfügbar ist und die VM mehr RAM als das Minimum benötigt).
Die letzte Spalte “Frei/Max” zeigt, wieviel Speicher bezogen auf den maximal möglichen RAM der VM noch frei ist. Erst wenn dieser Wert zu niedrig wird (bspw. unter 20% fällt) besteht Bedarf, der VM mehr RAM zuzuweisen.
Insgesamt sehen dann die Werte in der PowerShell, dem Taskmanager der VM und dem Hyper-V Manager so aus:
Manchmal besteht der Wunsch, auf einem Windows-System eine automatische Anmeldung nach dem (Neu)Start durchzuführen. Dies ist mit sehr einfachen Mitteln möglich und funktioniert sowohl bei Client- als auch Server-Betriebssystemen, auch bei älteren. Nötig ist dazu nur der Zugriff auf die Registry und ein passendes Benutzerkonto.
Als erstes wird der Registrierungseditor mittels “regedit.exe” geöffnet:
Dort muss zu dem Schlüssel unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon navigiert werden.
Abschließend sind folgende Schlüssel nötig (alle als Zeichenfolge, REG_SZ)
AutoAdminLogon = “1”
DefaultUserName = BENUTZER
DefaultPassword = PASSWORT
DefaultDomainName = DOMÄNE
So etwa wie im Screenshot…
Das war es schon gewesen. Beim nächsten Neustart ist die automatische Anmeldung aktiv…