MSXFAQ MeetNow aktiv: Komm doch einfach dazu.

NET Framework Reparatur

Panik für mich als Administrator eines Exchange Server. Nichts geht mehr, weil der Server meint, er hätte kein .NET Framework 4.0.30319, obwohl ich grade erst von 4.8 auf 4.8.1 aktualisiert habe. Nach dem Neustart ist kein Dienst mehr gestartet, der auf NET aufsetzt.

Fehlerbilder

Da habe ich erst mal nicht schlecht geschwitzt, als mein Exchange Server nach einem Neustart nicht mehr hochgekommen ist. Alle Exchange Dienste waren beendet und ein Start meinte nur, dass "abhängige Dienste" nicht gestartet werden konnten. Da der "Microsoft Exchange Active Directory Topology"-Dienst so etwas wie der Koordinator aller anderen Dienste ist, habe ich mir hier die Abhängigkeiten angeschaut.

Die einzige Abhängigkeit ist der "Net.Tcp Port Sharing Service" und wenn ich den starten möchte, dann komme der folgende Fehler

"Windows could not start the Net.Tcp Port Sharing Service service on Local Computer"

Ich habe mir die Eigenschaften des Diensts, genauer den Pfad zur aufgerufenen EXE geholt und diese als Administrator einmal versucht manuell zu starten. Viele Dienste sind oft fast normale Programme, die auch interaktiv gestartet werden können

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SMSvcHost.exe

Allerdings hat der Start in einer Konsole hier keine Fehlermeldung ausgegeben, sondern das Programm konnte gar nicht initialisiert werde, da eine Abhängigkeit fehlt. Da fehlt angeblich das .NET Framework in der richtigen Version:

Das stimmt so natürlich nicht, denn natürlich ist das .NET Framework gerade vor dem Neustart installiert worden

Vorgeschichte

Nach dem Exchange 2019 CU15 habe ich noch schnell den Exchange "Health Checker" laufen lassen, der mir gesagt hat, dass ich noch .NET 4.8 nutze aber .NET 4.8.1 empfohlen wäre. Das Update geht eigentlich recht schnell, indem man einfach den Web-Installer startet und durchlaufen lässt.

.NET 4.8.1 Web Installer
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net481

Auch das .NET Repair Tool hat bei mir nichts geholfen. Es scheint wohl eher Fehler vor und bei der Installation zu korrigieren, indem es z.B. den Windows Installer neu startet

Microsoft .NET Framework Repair Tool
https://aka.ms/DotnetRepairTool 
https://support.microsoft.com/de-de/topic/das-microsoft-net-framework-reparaturtool-ist-verf%C3%BCgbar-942a01e3-5b8b-7abb-c166-c34a2f4b612a

Das war alles nicht wirklich hilfreich.

Deinstallation/Neuinstallation

Wenn Exchange eh schon nicht läuft, dann kann ich NET ja auch einfach mal aus den Rollen und Features deinstallieren und neu installieren. Das kann man per DISM, PowerShell oder auch per Servermanager machen. Beim Start des Servermangers habe ich aber die gleiche Fehlermeldung erhalten:

Damit war klar, dass es kein Exchange Problem ist, sondern das .NET Framework auf dem Server irgendwie durcheinander war.

Recherche

Nun ist es so, dass zum .NET Framework nicht nur die DLLs und andere Dateien in "C:\Windows\Microsoft.NET", die natürlich alle da waren. Ergänzend gibt es noch einige Einträge in der Registrierung und da hat ein Vergleich mit einem anderen funktionierenden Server doch interessante Unterschiede aufgezeigt. Hier die Bilder zu den beiden Pfaden:

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319

Hier einmal die beiden Schlüssel meines defekten Servers. (64bit und WOW6432)

Und hier die beiden Schlüssel bei einem anderen Server (64bit und WOW6432)

In den Schlüsseln steht auch gar nicht viel drin. Anscheinend sind das alle nur Hinweise für Windows, welches Framework installiert sind. Mit diesem Wissen habe ich etwas recherchiert und habe andere Fragen und Antworten verschiedener Seiten gefunden. Eine Seite hat mich neugierig gemacht:


Quelle: .net 4.8 kills Server 2019 https://www.bleepingcomputer.com/forums/t/758800/net-48-kills-server-2019/

Angeblich ist dort ein "New-Item"-Befehl drin, der durch das "-Force" einen Registrierungsschlüssel neu anlegt. 

New-Item 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319' -Force | Out-Null Which creates that path (if it doesn't exist). If it does exist (which it does by default on Server 2019) it empties it.

Das habe ich nun nicht mit meinem produktiven Server versucht, sondern erst einmal mit einem anderen Registrierungsschlüssel:

# Pfad anlegen
New-Item 'HKCU:\SOFTWARE\MSXFAQ\Test' -Force | Out-Null
# Schlüssel mit Wert anlegen
New-ItemProperty -Path 'HKCU:\SOFTWARE\MSXFAQ\Test' -Name 'Test' -Value '1' -PropertyType 
'DWord' -Force | Out-Null
# Schlüssel und Wert ausgeben
Get-Item 'HKCU:\SOFTWARE\MSXFAQ\Test'
# Pfad anlegen
New-Item 'HKCU:\SOFTWARE\MSXFAQ\Test' -Force | Out-Null
# Schlüssel und Wert erneut ausgeben
Get-Item 'HKCU:\SOFTWARE\MSXFAQ\Test'

Die Ausgabe ist eindeutig:

Das "New-Item <regkey> -force"  löscht alles unter einem bestehenden Eintrag und ist damit ein Bug. Damit ist noch nicht geklärt, wer das auf dem Server wann macht. Ich habe natürlich das NET 4.8.1. installiert aber wer oder was hat ein "New-Item" ausgeführt. Der Code von der Microsoft-Seite enthält mittlerweile ja eine Vorabprüfung, ob der Pfad schon da ist.

Ich befürchte aber, dass andere Autoren vielleicht den Code ohne die Prüfung in ihre Skripte übernommen haben.

Microsoft verwaltet seine Dokumentation mittlerweile in GitHub, so dass wir die Versionen der Datei anschauen können.

Andere Autoren hatten also fast 3 Jahre Zeit, den Code zu kopieren 

Quick Fix

Ich habe mir das Leben einfach gemacht und habe erst einmal  auf einem anderen vergleichbaren Server die entsprechenden Schlüssel als REG-Datei exportiert und auf dem Problemserver importiert.

Achtung: Importieren Sie nicht blind diese Datei auf ihrem Server. Sie muss zum Betriebssystem und den installierten .NET-Framework-Versionen passen. Diese ist ist ein Windows 2022 Server mit .NET 4.8.1-Framework.

Hier die REG-Datei.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"AspNetEnforceViewStateMac"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.1,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.2,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.3]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.3,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.3]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\Default]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.1,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.2,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.3]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.0.3,Profile=Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5.3]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.6.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.7.2]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8.1]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\Client]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs\Default]

Ganz ohne Neustart des Servers konnte ich damit sowohl den Servermanager als auch alle Dienste wieder starten.

Get-Service `
| where {$_.starttype -eq "automatic" -and $_.status -ne "running"} `
| Start-Service

Besserer Fix

Mein Exchange Server läuft wieder und eigentlich könnte ich mich wieder anderen Dingen zuwenden. Aber der Import einer REG-Datei kann nicht der Weisheit letzter Schluss sein.

Diese Tests habe ich auf einem Windows 2019 Server durchgeführt.

Dazu habe ich auf einem funktionierenden Server den Fehler nachgestellt, indem ich die beiden Registrierungsschlüssel umbenannt habe.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SKUs] 

NET Repair Tool

Zuerst habe ich das ".Net Repair Tool" ausprobiert.

Microsoft .NET Framework Repair Tool
https://www.microsoft.com/en-us/download/details.aspx?id=30135
https://aka.ms/DotnetRepairTool

Es hat zwar gescannt und angeblich einen Repair-Versuch erfolgreich durchgeführt aber die Registrierungsschlüssel wurden nicht wieder hergestellt. Das war dann wohl nichts.

Powershell Remote/Install-WindowsFeature

Da die .NET-Framework ja ein Windows Feature ist, habe ich es entfernt, den erforderlichen Neustart durchgeführt. Auf dem Windows 2019 Server war es NET 4.7.2, welches die älteren Versionen ja auch enthält.

Remove-WindowsFeature NET-Framework-4-5-Core 
Install-WindowsFeature NET-Framework-4-5-Core 

Das war aber eine dumme Idee, denn danach war nicht nur das Verzeichnis "C:\Windows\Microsoft.NET" ziemlich geleert. Auch die PowerShell startet nicht mehr (Fehler: "mscoree.dll missing") und auch der Servermanager konnte nicht mehr gestartet werden.

NET Download aus dem Internet

Ich bin dann den einfacheren Weg gegangen, indem ich mit das .NET 4.8 aus dem Internet installiert habe. Es hat zumindest einen Teil der Registrierungsschlüssel wieder eingerichtet.

 

Sie sehen darunter in Grün den alten Zweig, den ich einfach umbenannt hatte. Danach war natürlich wieder ein Neustart fällig. Allerdings konnte ich danach immer noch nicht weder PowerShell starten noch Servermanager starten. Im Startmenü ist der Servermanger sogar "ersetzt" worden.

SFC Scannow

Irgendwie wollte ich aber doch wieder an den Server kommen und habe dann folgenden Befehl versucht, in der Hoffnung, dass es mir den Servermanager wieder bringt.

REM Versuch einer Serverreparatur - ohne Erfolg
sfc.exe /scannow

SFC hat auch angeblich einige Korruptionen  entdeckt und gefixt. Im Logfile auf C:\Windows\Logs\CBS.log war aber kein Hinweis auf NET 4.5 o.ä.

OptionalFeatures.exe 

Dann habe ich gefunden, dass es ein Programm "OptionalFeatures.exe" gibt. Die Hoffnung, damit vielleicht das deinstallierte NET45-Framework installieren zu können, hat sich aber zerschlagen, das der Aufruf einfach nichts auf dem beschädigten Server tut.

Auch die Installation der PowerShell 7.5.0 hat zwar funktioniert und konnte gestartet werden, aber ein "Add-WindowsFeature" greift wohl doch wieder auf die alte Schnittstellen zu und endet mit einem "mscoree.dll" nicht gefunden.

Dateien manuell kopieren

Zuletzt habe ich einfach die Dateien aus dem NET.4.5-Installationspaket extrahiert und in das entsprechende Verzeichnisse (C:\Windows\MicrosoftNet\Framework64) des Server kopiert, was aber auch keine Lösung geschaffen hat.

DISM hat es dann gerettet

Damit bleibt wieder nur die alte CMD-Shell, welche ohne das NET-Framework funktioniert.

REM DISM hat das Framework wieder reaktiviert
dism /online /enable-feature /featurename:netfx4 /all

Ich hätte nicht gedacht, dass allein eine Deinstallation von NET45 auf einem Windows 2016 Server (1809) so desaströse Auswirkungen hat.

Ich kann nur sagen, dass es eine denkbar dumme Idee ist, das "NET-Framework-4-5-Core" zu deinstallieren. Allerdings hätte Microsoft hier vielleicht eine Schutzvorkehrung einbauen können, denn das danach die Systemprogramme "Servermanager" und "PowerShell 5" nicht mehr funktionieren, sollte nicht passieren.
Nur mit "DISM /Online" konnte ich die fehlenden Komponenten wieder installieren.

Ursache finden

Damit bleibt noch die Frage nach dem "Wer hat es gelöscht?". Vielleicht hat jemand ja wirklich das Codebeispiel von "https://github.com/MicrosoftDocs/entra-docs/commit/886bea58d1d8b411f173724001e9f06ac302a4b2" auch in seinen eigenen Code oder Skripte übernommen.

Ich habe verschiedene PS1-Dateien u.a. abgesucht aber bin letztlich nicht fündig geworden

Rein von den nacheinander durchlaufenden Schritte kann es eigentlich nur das NET 4.8.1 Updates gewesen sein, welches mit seinen Schlüsseln die vorher bestehenden Werte ersetzt hat. Vor dem Update lief der Server und nach dem Update und Neustart nicht mehr. Ich weiß natürlich nicht, welche Änderungen nach dem früheren Neustart und vor meinen Updates erfolgt ist. Kein Kollege hat die Hand gehoben und auf dem Server protokollieren wir nicht jeden einzelnen Programmstart. Vielleicht sollten wir das zukünftig doch tun.

Windows 2025

Dass ich mir mit meinem Test auf Windows 2019 den Server quasi geschrottet habe, hat mir keine Ruhe gelassen und ich habe den Test mit Windows 2025 wiederholt. Zuerst habe ich wieder .NET über den Servermanager deinstalliert:

Schon hier sehen sie, dass sowohl die davon abhängige PowerShell 5.1 aber auch die TCP-Portfreigabe mit entfernt werden, was auch in der Bestätigung zusammengefasst wird.

 

Nach dem Neustart haben mich gleich zwei Fehler begrüßt. Der normalerweise automatisch gestartete Servermanager startet nicht mehr. Mit dem Vorwissen habe ich das erwartet aber es ist natürlich schon ein überraschender Faktor für normale Administratoren.

Vielleicht hätte Microsoft hier einen Abhängigkeit des Features "Server-Gui-Mgmt" mit einbauen sollen, damit Administratoren bei der Deinstallation gewarnt werden.

Windows 2025 kann über Azure ARC verwaltet werden. Auch ist ist nicht mehr möglich

Auch eine PowerShell ist weder direkt noch über das Windows Terminal erreichbar. Das Feature "Server-Psh-Cmdlets" ist aber immer noch vorhanden. Auch hier fehlt eine Abhängigkeit.

Es ist eine dumme Idee, das .NET Framework zu deinstallieren und ich bin überrascht, dass Microsoft dies nicht verhindert oder zumindest deutlich warnt.

Da eine Reinstallation über den Servermanager nicht mehr möglich ist, habe ich zuerst versucht "OptionalFeatures.exe " zu starten. was aber einfach still untätig geblieben ist. Über DISM war es aber möglich.

dism /online /enable-Feature /Featurename:NetFx4 /All

Danach konnte ich ohne Neustart direkt wieder den Servermanger starten und weitere Rollen installieren und insbesondere die vorhandenen Rollen kontrollieren. So wurde die TCP-Portfreigabe schon mit installiert.

Die Powershell 5.1 kam so aber noch nicht mit. Sie musste per GUI oder DISM nachinstalliert werden

dism /online /enable-Feature /Featurename:MicrosoftWindowsPowerShell /All

Zumindest mit DISM kann ich über eine "alte" CMD-Shell wieder das NET-Framework auf Windows 2025 reaktivieren.

Zwischenstand

Ein ungutes Gefühl bleibt natürlich. Irgendeine Komponente hat Schlüssel in der Registrierung gelöscht und wenn es kein Kollege vorher was, dann kann es nur das .NET Framework 4.8.1 Update gewesen sein, was unter einer besonderen Konstellation sich so falsch verhalten hat. Dass ich dann noch meinen Windows 2019 Server durch das absichtliche Deinstallieren von NET45 so unbrauchbar gemacht habe. merke ich mir. Eine Deinstallation und Neuinstallation des .NET Framework ist keine gute Idee als Lösungsszenario.

Weitere Links