Windows 10 Hyper-V: Netzwerkliste in VMs bereinigen mit PowerShell

Eigentlich ist der fest eingebaute Default vSwitch in Windows 10 Hyper-V eine super Erfindung, vor allem, wenn man ihn auf Notebooks benutzt: VMs haben immer Internet, egal, ob man über LAN, WLAN oder LTE verbunden ist, und behalten die Verbindung (bis auf eine kurze Unterbrechung) inklusive der beim Starten dynamisch bezogenen IP-Adresse bei, wenn man zwischen Verbindungsarten oder WLANs wechselt.

Seit der Version 1709 (IIRC) gibt es im Kontext des Default vSwitch aber ein großes Ärgernis: Hat man früher am Default vSwitch stets das gleiche IP-Subnetz vorgefunden (und konnte somit auch ein ganzes Lab mit fixen + dynamischen IP-Adressen an diesem Switch aufbauen), so wird jetzt bei jedem Booten das IP-Subnetz des Default vSwitch neu ausgewürfelt.

Für Labs mit Bedarf an Internet-Zugang ist es an und für sich kein wirkliches Problem:

  • privaten vSwitch anlegen und das Lab an diesem aufbauen
  • eine kleine Router-VM mit zwei Beinen (WAN=Default vSwitch, LAN=privater vSwitch) installieren (mein persönlicher Favorit hier ist seit Jahren pfSense)
  • glücklich sein.

Hat man aber eine Windows-VM direkt am Default vSwitch angeschlossen, so muss man sie einerseits auf DHCP belassen (damit sie eine gültige IP aus dem aktuellen Subnetz des vSwitch bekommt), andererseits wird jedes Mal ein neues Netzwerk-Profil erzeugt. Eine wirkliche Lösung gibt es hier nicht, man kann das Ganze aber immerhin in der Registry bereinigen. Als Startup-Script würde man natürlich versuchen, das jeweils aktuelle Profil nicht zu löschen:

function ConvertFrom-BinaryDate {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)][int[]]$BinaryDate
    )
    # Datum aus REG_BINARY in datetime konvertieren
    if ($BinaryDate.Count -ne 16) {
        Write-Warning "BinaryDate: Wrong octet count [$($BinaryDate.Count)]"
        return $null
    } else {
        $year = ($BinaryDate[1] * 256) + $BinaryDate[0]
        $month = ($BinaryDate[3] * 256) + $BinaryDate[2]
        # weekday brauchen wir eigentlich nicht, aber der Vollständigkeit halber...
        $weekday = ($BinaryDate[5] * 256) + $BinaryDate[4]
        $day = ($BinaryDate[7] * 256) + $BinaryDate[6]
        $hour = ($BinaryDate[9] * 256) + $BinaryDate[8]
        $min = ($BinaryDate[11] * 256) + $BinaryDate[10]
        $sec = ($BinaryDate[13] * 256) + $BinaryDate[12]
        return (Get-Date -Year $year -Month $month -Day $day -Hour $hour -Minute $min -Second $sec)
    }
}
$nlakey1 = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles"
$nlakey2 = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged"
$guids = @()
foreach ($subkey in (Get-ChildItem -Path $nlakey1)) {
    if ($subkey.GetValue("Managed") -eq 0) {
        $lc = ConvertFrom-BinaryDate -BinaryDate $subkey.GetValue("DateLastConnected")
        if ($lc -lt (Get-Date).AddDays(-1)) {
            $guids += $subkey.PSChildName
            $subkey | Remove-Item -Force
        }
    }
}
foreach ($subkey in (Get-ChildItem -Path $nlakey2)) {
    if ($subkey.GetValue("ProfileGuid") -in $guids) {
        $subkey | Remove-Item -Force
    }
}

Man kann das Ganze aber auch als Shutdown-Skript realisieren. Da muss man auf LastConnection dann nicht mehr achten, sondern nur darauf, dass man keine „Managed“-Profile entfernt:

$nlakey1 = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles"
$nlakey2 = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged"
foreach ($subkey in (Get-ChildItem -Path $nlakey1)) {
    if ($subkey.GetValue("Managed") -eq 0) {
        $subkey | Remove-Item -Force
    }
}
foreach ($subkey in (Get-ChildItem -Path $nlakey2)) {
    $subkey | Remove-Item -Force
}

Happy NLA Cleanup!

Ersten Kommentar schreiben

Antworten

Deine E-Mail-Adresse wird nicht veröffentlicht.


*


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