– Jan's Cloud – online Gedankenstütze ;)

7. Juli 2018

Warten bis Hyper-V VM neu gestartet ist

Filed under: Hyper-V,PowerShell,Windows Server — Schlagwörter: , , , , , , — Jan Mischo @ 17:38

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

Und jetzt:

RebootAndWaitForServer

RebootAndWaitForServer



	

1 Kommentar »

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

    Pingback by Auf Active Directory Start in Hyper-V VM warten - Jan's Cloud - — 8. Juli 2018 @ 11:10

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress