Auf Active Directory Start in Hyper-V VM warten

Den vollständigen Start des Active Directory in einer Hyper-V VM abwarten.

Das gestern vorgestellt Script „RebootAndWaitForServer“ wartet nur „stumpf“ bis die Hyper-V VM gebootet ist und der Prozess „winlogon.exe“ sowie der Dienst „LSM“ läuft. Stellt man jetzt eine Umgebung auf der grünen Wiese bzw. einen PoC oder eine Demoumgebung bereit, benötigt man unter Umständen einen Domänen Controller. Ein DC sollte nicht nur automatisch ausgerollt, sondern auch noch entsprechend konfiguriert werden. Die Konfiguration ist allerdings, logischerweise, erst möglich wenn die Active Directory Dienste gestartet und betriebsbereit sind. Auch hier gab es auf GitHub (WaitFor-ActiveDirectory) bereits eine Funktion, die in verschiedenen Tests nicht zuverlässig lief. In prduktiven Umgebungen sollte es diese Problem natürlich gar nicht erst, da immer mindestens zwei Domain Controller betrieben werden sollten, von denen einer immer erreichbar ist.

Das folgende Script liest die Uptime der Hyper-V VM aus, zieht diese vom aktuellen Datum ab und durchsucht dann die Ereignisanzeige „Active Directory Web Services“ in der VM auf die Instanz-Id „1073743024“.

# WaitForAD
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 WaitForAD {
    param (
        [Parameter(Mandatory=$true)]
        [String]
        $VMName,
 
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]
        $Credentials
 
    )
    $VM = Get-VM -Name $VMName
    $Uptime = $VM.Uptime.TotalSeconds
    $Date = $(Get-Date).AddSeconds(-($Uptime))
    Write-Host "[$($VMName)]:: Auf Active Directory warten" -ForegroundColor Yellow -NoNewline
    Invoke-Command -VMName $VMName -Credential $Credentials -ArgumentList $Date -ScriptBlock {
        param($Date)
        do {
            do {
                Write-Host "." -ForegroundColor Yellow -NoNewline
                Start-Sleep -Seconds 5
                $AD = get-service ADWS, DNS, KDC, NETLOGON, NTDS
            } until ($AD[0].Status -eq "running" -and $AD[1].Status -eq "running" -and $AD[2].Status -eq "running" -and $AD[3].Status -eq "running" -and $AD[4].Status -eq "running")
            Write-Host "." -ForegroundColor Yellow -NoNewline
            Start-Sleep -Seconds 5
            $Event = Get-EventLog -LogName "Active Directory Web Services" -Source ADWS -After $Date -InstanceId 1073743024 -Newest 1
        } until ($Event.Message -match "Die angegebene Verzeichnisinstanz wird nun von Active Directory-Webdiensten bedient" -or $Event.Message -match "Active Directory Web Services is now servicing the specified directory instance")
    }
    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))
 
WaitForAD $VMName $tempCred

Link zum Download: WaitForAD

Aint nobody got time for dat
Aint nobody got time for dat

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

VMware Virtual Guest Tagging unter Hyper-V umsetzen

Wie kann Virtual Guest Tagging unter Hyper-V umgesetzt werden?

Häufig wird Virtual Guest Tagging für Firewalls / Router oder andere Netzwerk-Appliances (Load Balancer, Application Delivery Controller, …) benötigt. Da es unsererseits erste konkrete Pläne zum Ablösen der VMware Umgebung durch Hyper-V gibt, brauchen wir Virtual Guest Tagging unter Hyper-V für unsere gehosteten Netscaler Appliances.

In einer VMware Umgebung lässt sich relativ simpel Virtual Switch Tagging (VST), External Switch Tagging (EST) und Virtual Guest Tagging (VGT) umsetzen. In den meisten Fällen wird es unter VMware auf VST hinauslaufen. Unter Hyper-V wird das VLAN üblicherweise direkt an der virtuellen Netzwerkkarte der VM getagged. In der GUI gibt es leider keine Möglichkeit, Virtual Guest Tagging unter Hyper-V umzusetzen. Hyper-V bringt dafür aber ein entsprechenden PowerShell CMDlet mit: Set-VMNetworkAdapterVlan.

Set-VMNetworkAdapterVlan -VMName <Name der VM> -Trunk -AllowedVlanIdList "1200-1299" -NativeVlanId 1200
Set-VMNetworkAdapterVlan -VMName <Name der VM> -Trunk -AllowedVlanIdList "1200,1300,1400" -NativeVlanId 1200
Set-VMNetworkAdapterVlan -VMName <Name der VM> -Trunk -AllowedVlanIdList "1200-1210,1300,1400" -NativeVlanId 1200

Sofern der Netzwerker keine VLANs auf dem Uplink Trunk vergessen hat, kann auch schon das Tagging in der Gast-VM erfolgen.

Hyper-V in Guest tagging / virtual Guest tagging
Hyper-V in Guest tagging / virtual Guest tagging