Warten bis Hyper-V VM neu gestartet ist

Neustart einer Hyper-V VM initiieren und abwarten bis das Windows Serverbetriebssystem geladen ist.

In einem größeren Projekt wird mittels eines leicht angepassten Image Factory Script per Task wöchentlich eine mit Updates versogte Windows Server 2016 VHDX erstellt und später in einem Deployment Prozess per PowerShell weiterverarbeitet. Beim Rollout diverse VMs wird natürlich auch diverses an Software bzw. Applikationen in den VMs benötigt. Die Installation der Applikationen benötigen hin und wieder leider auch Reboots. Gewisse Schritte müssen dann auch noch auf andere Applikation oder Dienste warten. Ebenfalls passiert es ab und zu, dass ein Reboot länger verzögert bis z.B. Dienste beendet sind. Der Bootvorgang kann durchaus auch schon abgeschlossen sein und direkt erneut booten, da noch weitere Updates oder Features konfiguriert werden müssen.

Für dieses Problem gab es bereits z.B. waitForPSDirect oder auch Invoke-CommandWithPSDirect. Bei beiden Scripts kann es passieren, dass die Hyper-V VM bereits per PowerShell Direct angesprochen werden kann, obwohl noch ein weiterer Reboot aussteht. Aus diesem Grund habe ich die beiden Scripte kombiniert und ein wenig erweitert. Im Groben fährt das Script die Hyper-V VM herunter, startet diese neu, überprüft den Status des Taktes (Heartbeat) Get-VMIntegrationService und wartet bis die „winlogon.exe“ und der „Lokaler Sitzungs-Manager (LSM)“ laufen.

Reboot And Wait For Server Ausgabe
Reboot And Wait For Server Ausgabe

Wichtig: Wenn während dem Deployment die Software / Applikation in der Hyper-V VM installiert wird, diese nicht über die Installationsroutinen neu starten. Zum kontrollierten Reboot nur die PowerShell Funktion „RebootAndWaitForServer“ nutzen.

# RebootAndWaitForServer
Beispiel für die Variablen:
    [string]$VMName = "SERVER-VM01"
    [System.Management.Automation.PSCredential] $tempCred = new-object -typename System.Management.Automation.PSCredential ("Domain\Admin", (ConvertTo-SecureString P@ssw0rd! -AsPlainText -Force))
 
Oder ggfs. die Variablen abfragen:
    $VMName = Read-Host "Bitte den Namen des virtuellen Computers eingeben"
    $tempCred = Get-Credential
#>
 
function RebootAndWaitForServer {
    param (
        [Parameter(Mandatory=$true)]
        [String]
        $VMName,
 
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]
        $Credentials
 
    )
    $VM = Get-VM -Name $VMName
    If ($Vm.State -eq "Running") {
        Write-Host "[$($VMName)]:: Fahre Computer herunter" -ForegroundColor Yellow -NoNewline
        Invoke-Command -VMName $VMName -Credential $Credentials -ScriptBlock {
            Stop-Computer -Force -Confirm:$false
        }
        do {
            Write-Host "." -ForegroundColor Yellow -NoNewline
            Sleep -Seconds 5
        } until ($VM.State -eq "Off")
        Write-Host " -> Ok!" -ForegroundColor Yellow
    }
    If ($Vm.State -eq "Off") {
        Write-Host "[$($VMName)]:: Starte Computer neu" -ForegroundColor Yellow -NoNewline
        Start-VM -VM $VM
        do {
            Write-Host "." -ForegroundColor Yellow -NoNewline
            Sleep -Seconds 5
            $VMStatus = Get-VMIntegrationService -VM $VM | ? Id -match "84EAAE65-2F2E-45F5-9BB5-0E857DC8EB47"
        } until($VMStatus.PrimaryStatusDescription.ToUpper() -eq "OK" -and $VMStatus.SecondaryStatusDescription.ToUpper() -eq "OK")
        Write-Host " -> Ok!" -ForegroundColor Yellow
        Write-Host "[$($VMName)]:: Warte auf Winlogon.exe und LSM Dienst" -ForegroundColor Yellow -NoNewline
        Invoke-Command -VMName $VMName -Credential $Credentials -ScriptBlock {
            do {
                Write-Host "." -ForegroundColor Yellow -NoNewline
                Sleep -Seconds 5
                $Process = Get-Process | ? ProcessName -eq "winlogon" -ErrorAction SilentlyContinue
                $LSM = Get-Service LSM -ErrorAction SilentlyContinue
                if ($Process.ProcessName -eq "winlogon" -and $LSM.Status -eq "Running") {
                    $Winlogon = 1
                }
                else {
                    $Winlogon = 0
                }
            } until ($winlogon -eq 1)
        }
    }
    Write-Host " -> Ok!" -ForegroundColor Yellow
}
 
[string]$VMName = "SERVER-VM01"
[System.Management.Automation.PSCredential] $tempCred = new-object -typename System.Management.Automation.PSCredential ("Domain\Administrator", (ConvertTo-SecureString P@ssw0rd! -AsPlainText -Force))
 
RebootAndWaitForServer $VMName $tempCred

Link zum Download: RebootAndWaitForServer

RebootAndWaitForServer
RebootAndWaitForServer

Die gesuchte Lösung noch nicht gefunden oder benötigen Sie Hilfe bei anderen Themen aus meinem Blog? Nehmen Sie gerne Kontakt mit mir bzw. meinem Unternehmen Jan Mischo IT auf. Ich freue mich auf Ihre Anfrage: https://janmischo.it/kontakt/


+49 2801 7004300

info@janmischo.it


Beitrag veröffentlicht

in

, ,

von

Kommentare

Eine Antwort zu „Warten bis Hyper-V VM neu gestartet ist“

  1. […] gestern vorgestellt Script „RebootAndWaitForServer“ wartet nur „stumpf“ bis die Hyper-V VM gebootet ist und der Prozess […]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.