Windows 11 | Verbindungsspezifisches DNS-Suffix mit PowerShell entfernen

Wer in gemischten Umgebungen oder beim Testen von Routern und DHCP-Servern unterwegs ist, kennt das Phänomen: In der Ausgabe von ipconfig /all taucht plötzlich ein verbindungsspezifisches DNS-Suffix wie home.local oder fritz.box auf.

Das Problem dabei: Selbst wenn man in den erweiterten TCP/IP-Einstellungen des Netzwerkadapters das Feld “DNS-Suffix für diese Verbindung” manuell leert, bleibt der Eintrag stur bestehen. Auch ein gewöhnliches Set-DnsClient -ConnectionSpecificSuffix "" bringt oft keine Abhilfe.

Die Ursache: DHCP Option 119 und die Registry

Der Grund für diese Renitenz liegt tiefer im System. Viele Router übermitteln DNS-Suchlisten über die DHCP Option 119 (oder Option 15). Windows legt diese Werte nicht nur in den Standard-Eigenschaften der Netzwerkschnittstelle ab, sondern schreibt sie als REG_MULTI_SZ-Wert namens DhcpDomainSearchList direkt in die Registry unterhalb der jeweiligen Adapter-GUID.

Da es sich hierbei um ein Multi-String-Array handelt, greifen die Standard-Befehle zum Leeren gewöhnlicher Zeichenfolgen ins Leere. Bei jedem Lease-Renew holt sich Windows die Suchliste wieder ab.

Die Lösung: PowerShell-Skript zur Bereinigung

Um das Suffix endgültig loszuwerden, müssen die entsprechenden Schlüssel in den Interfaces sowie die globalen Suchlisten unter Tcpip\Parameters gezielt abgeräumt werden.

Folgendes PowerShell-Skript (mit Administratorrechten ausführen) erledigt den Hausputz auf allen Netzwerkschnittstellen:


#Requires -RunAsAdministrator

# Target path for network interfaces in the registry
$InterfacesPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"

# 1. Clear and remove DhcpDomainSearchList and related suffix entries on all interfaces
Get-ChildItem -Path $InterfacesPath | ForEach-Object {
    $path = $_.PSPath
    
    # Explicitly remove and clear DhcpDomainSearchList
    Remove-ItemProperty -Path $path -Name "DhcpDomainSearchList" -ErrorAction SilentlyContinue
    Set-ItemProperty -Path $path -Name "DhcpDomainSearchList" -Value ([string[]]@()) -ErrorAction SilentlyContinue

    # Clean up secondary domain suffix properties
    Remove-ItemProperty -Path $path -Name "DhcpDomain" -ErrorAction SilentlyContinue
    Remove-ItemProperty -Path $path -Name "Domain" -ErrorAction SilentlyContinue
    Set-ItemProperty -Path $path -Name "DhcpDomain" -Value "" -ErrorAction SilentlyContinue
    Set-ItemProperty -Path $path -Name "Domain" -Value "" -ErrorAction SilentlyContinue
}

# 2. Clean up global SearchList entries under Tcpip\Parameters
$ParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
Remove-ItemProperty -Path $ParamsPath -Name "DhcpDomainSearchList" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $ParamsPath -Name "SearchList" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $ParamsPath -Name "Domain" -ErrorAction SilentlyContinue

# 3. Flush local DNS client cache
Clear-DnsClientCache

Write-Host "DhcpDomainSearchList successfully cleaned up!" -ForegroundColor Green

Den Wiedergang nach DHCP-Renew verhindern

Falls der lokale DHCP-Server im Netz weiterhin penetrant Option 119 verteilt und Windows das Suffix beim nächsten Re-Lease wieder einspeist, lässt sich Windows per Gruppenrichtlinie / Registry anweisen, die vom DHCP gelieferten Suchlisten schlicht zu ignorieren:

# Enforce policy to ignore DHCP Option 119 (DhcpDomainSearchList) globally
$policyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
if (-not (Test-Path $policyPath)) {
    New-Item -Path $policyPath -Force | Out-Null
}
Set-ItemProperty -Path $policyPath -Name "UseDomainNameDevolution" -Value 0 -Type DWord

Kontrolle

Ob die Bereinigung erfolgreich war, lässt sich mit einem kurzen Einzeiler prüfen:

# Verify that DhcpDomainSearchList is empty across all interfaces
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\*" | Select-Object PSChildName, DhcpDomainSearchList

Nach einem anschließenden ipconfig /flushdns zeigt ipconfig /all wieder eine saubere Suchliste ohne unerwünschte Suffix-Leichen an.

Das Skript zum Löschen des Eintrags steht hier zum Download bereit.

Enjoy it, b!

M365 | Aufbewahrung von Mails in freigegebenen Postfächern

In M365 können freigegebene Postfächer gelöschte Mails eine Zeitlang im Ordner „Gelöschte Objekte” aufbewahren. Die Aufbewahrungsdauer generell sowie die maximale Zeitspanne von 30 Tagen sind über PowerShell konfigurierbar.

# Aufbewahrung von gelöschten Mails in einem freigegebenen Postfach "Service"
Set-Mailbox -Identity "Service" -RetainDeletedItemsFor 30.00:00:00

# Abfrage des Aufbewahrungszeitraums für das Postfach "Service"
Get-Mailbox -Identity "Service" | Select RetainDeletedItemsFor

image

Die Konfiguration erfolgt Über das Exchange-Online PowerShell-Modul, dass natürlich eine Anmeldung benötigt.

Hier noch die Befehle wie das Exchange-Online PowerShell-Modul installiert wird und wie die Anmeldung erfolgt (die Installation als Admin in der PowerShell durchführen):

# Ausführungsrichtlinie setzen
Set-ExecutionPolicy RemoteSigned -Force

# PowerShellGet aktualisieren (falls nötig)
Install-ModuleInstall-Module PowerShellGet -Force -AllowClobber

# Exchange Online Management Modul installieren
Install-Module -Name ExchangeOnlineManagement

Und hier die Anmeldung an M365 / Exchange Online:

# Verbindung zu Exchange Online herstellen
Connect-ExchangeOnline -UserPrincipalName admin

Enjoy it, b!

M365 | Outlook und ein ehemals freigegebenes Postfach

Innerhalb von M365 besteht die Möglichkeit ein freigegebenen Postfach in ein Benutzerpostfach und umgekehrt zu konvertieren.

Infos zu freigegeben Postfächern gibt es direkt bei Microsoft und auch der Prozess der Konvertierung ist dort sehr gut beschrieben.

Als Erinnerung oder Überbleibsel bleibt dabei der Name des ehemals freigegebenen Postfachs stehen und kann über Outlook (Classic) selbst auch nicht entfernt werden. Ein einfaches “schließen des Ordners” wird mit einem Fehler quittiert.

Sehr elegant kann das nun nicht mehr vorhandene Postfach über eine Deaktivierung des Auto-Mappings mit PowerShell entfernt werden. Sinnvoll aber nicht notwendig ist es, davor Outlook zu schließen.

# Remove Auto-Mapping via PowerShell (Admin Required)
Remove-MailboxPermission -Identity "ConvertedMailbox@domain.com" -User "AffectedUser@domain.com" -AccessRights FullAccess -InheritanceType All

Nach dem Start ist der alte Ordner verschwunden und Outlook sieht aus, wie es soll. Sinnvoll macht das der M365 Admin von einem System aus, auf dem die Exchange PowerShell-Module vorhanden sind.

https://learn.microsoft.com/en-us/powershell/module/exchangepowershell/?view=exchange-ps

Enjoy it, b!

Windows Server 2016 | Update NuGet fails

Ein paar Tage hat er ja noch, der Windows Server 2016 und falls mit PowerShell neue Module geladen werden sollen kann eine Aktualisierung des NuGet-Paketproviders erforderlich sein.

Sollte diese fehlschlagen und die folgende Fehlermeldung erscheinen, kann das an einer nicht ausreichenden Transportverschlüsselung liegen.

Hier die Fehler beim Versuch ein PowerShell-Modul zu installieren, was wiederum eine Aktualisierung von NuGet notwendig machte.

image

Bei dem Versuch die Aktualisierung manuell durchzuführen.

image

Die Lösung lag in der Verwendung von TLS1.2 für .Net.

# Forcing .Net to use TLS1.2 instead of SSL3 or lower TLS versions
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

image

Danach hat auch die Installation des PowerShell Windows Update Modules ohne Probleme funktioniert.

Enjoy it, b!

Hyper-V | Windows Server 2022 DHCP Result code 83

Wird unter Microsoft Hyper-V (Windows Server mit der Hyper-V Rolle) eine virtuelle Maschine mit Windows Server 2022 als Gastbetriebssystem installiert, kommt es häufig vor, dass die IP-Konfiguration nicht von DHCP auf eine statische IP umgestellt werden kann.

Der folgende Screenshot zeigt einen Microsoft Hyper-V Network Adapter in der Server Core Configuration (sconfig).

Unbenannt-1

Die Änderung der IP von DHCP auf eine fest zugewiesene, statische Adresse wird mit folgender Fehlermeldung quittiert und der Adapter verbleibt in der dynamischen Konfiguration.

Unbenannt-2

Lösen läßt sich das Problem über die PowerShell und folgende Befehle.

# Ermitteln des Interface-Indexes des Netzwerk-Adapters
Get-NetAdapter
# Entfernen der IP-Adresse
Remove-NetIPAddress -ifIndex 6 -Confirm:$false
# Vergabe einer neuen, statischen IP-Adresse
New-NetIPAddress -ifIndex 6 -IPAddress 192.168.11.141 '
-PrefixLength 24 - DefaultGateway 192.168.11.1

Sieht dann im Screenshot wie folgt aus.

Unbenannt-3

Enjoy it, b!

UAC | Skripte unter Windows

Einleitung

Die Benutzerkontensteuerung (User Account Control, UAC) ist ein wichtiger Bestandteil der Windows-Sicherheit. UAC reduziert das Risiko von Malware, indem es die Fähigkeit von bösartigem Code einschränkt, mit Administratorrechten ausgeführt zu werden.

Mit UAC muss jede Anwendung, die das Administrator-Zugriffstoken benötigt, die Zustimmung des Endbenutzers einholen. Die einzige Ausnahme ist die Beziehung zwischen übergeordneten und untergeordneten Prozessen. Untergeordnete Prozesse erben das Zugriffstoken des Benutzers vom übergeordneten Prozess. Der übergeordnete und der untergeordnete Prozess müssen jedoch die gleiche Integritätsstufe haben.

UAC in Skripten unter Windows

Gelegentlich, aber dann wirklich problematisch, wird während der Ausführung eines Skripts eine Bestätigung für die Ausführung eines Befehls oder einer Anwendung angefordert. Als Beispiele seien hier cmd.exe, diskpart.exe und regedit.exe genannt.

Befindet man sich im interaktiven Modus, bestätigt man den Dialog und die Verarbeitung wird fortgesetzt.

cmd-uac

Will man das Skript aber ohne Interaktionen (zum Beispiel remote) ausführen, muss man irgendwie um diese Dialog herumkommen.

PowerShell und die Eingabeaufforderung

Wenn wir über Skripting unter Windows reden, gibt es hauptsächlich Powershell und die Eingabeaufforderung, da beide in neueren Windows Versionen vorhanden sind und nicht zusätzlich installiert werden müssen.

Es gibt eine Reihe von meist freien Utilities und auch Workarounds um mit dem Problem umzugehen, soweit ich das aber vermeiden kann will ich keine 3rd-Party Utilities einsetzen (zumal diese dann im Netzwerk verteilt und auch gewartet werden müssen) und eine Deaktivierung der UAC kommt für mich nicht in Frage.

Microsoft hat hier in Windows selbst eine Lösung eingebaut, die bei mir sowohl in der Eingabeaufforderung (cmd.exe) als auch in der PowerShell sehr gut funktioniert.

Es gibt nämlich die Möglichkeit über eine Umgebungsvariable einen RunAsInvoker zu konfigurieren.

Um beispielsweise regedit.exe ohne UAC-Abfrage zu starten, verwendet man in der PowerShell folgenden Code:

:: Setzen des RunAsInvoker in PowerShell
[Environment]::SetEnvironmentVariable("__COMPAT_LAYER", "RunAsInvoker")

image

In der Eingabeaufforderung kann dagegen dieser Code verwendet werden.

:: Setzen des RunAsInvoker in der Eingabeaufforderung
set __COMPAT_LAYER=RunAsInvoker

image

Happy Skripting und Enjoy it, b!

DxO PureRaw4 Windows Shell-Erweiterungen

DxO PureRaw4 ist ein RAW-Konverter, den ich sehr schätze. Was mir an der Version 4 weniger gefällt, ist die tiefe Integration von PureRaw in das Betriebssystem. Ich brauche keine Erweiterungen im Windows Explorer, keinen ständig im Hintergrund laufenden PureRaw-Prozess und auch keinen automatischen Start von PureRaw zusammen mit Windows.

Streetphotography

(FUJIFILM, X-E4 mit Carl Zeiss Touit 1.8/32 @32.0mm, 1/180s, f/2.8 und ISO250)

Irgendwie konnte ich in den Einstellungen von PureRaw keine Möglichkeit finden, die obigen Punkte zu konfigurieren.

image

Der Autostart von PureRaw bedeutet nicht nur, dass sich dort ein Icon in der Taskleiste von Windows logiert, sondern auch, dass Kapazitäten meines Rechners unnötig belegt werden.

image

Also musste mal wieder die PowerShell für eine Lösung herhalten.

image

Das Skript muss in einer PowerShell-Sitzung mit erweiterten Rechten (elevated) ausgeführt werden und kann hier heruntergeladen werden.

Eine Prüfung ob PowerShell wirklich mit erweiterten Rechten läuft, erfolgt gleich zu Beginn des Skriptes.

#Requires -RunAsAdministrator
Darüber hinaus will ich noch auf die Verwendung von -LiteralPath hinweisen.
 
[string]$RegPath = 'HKLM:\SOFTWARE\Classes\*\shellex\ContextMenuHandlers\{7E6AAE52-1F6D-4BCA-A844-CD8273F428CE}'
Remove-Item -LiteralPath $RegPath -Force
Das ist nötig, da in der Variable $RegPath ein * vorhanden ist und die Befehle Get-ChildItem und Remove-Item mehr oder weniger „hängen“ bleibt und mit CTRL+C abgebrochen werden müssen.
 

Löschen eines Hyper-V Checkpoint mit PowerShell …

… da der Hyper-V Manager die Option zum Löschen nicht anbietet.

Nachdem erfolgreichen Upgrade einer VM von Windows Server 2012 R2 auf Windows Server 2022 konnte ich hinterher die erstellten Checkpoints (Snapshots nicht löschen). Der Hyper-V Manager wollte mir diese Möglichkeiten nicht anzeigen.

image

Da ich über ein ähnliches Problem schon in Verbindung mit dem Synology Active Backup for Business gestolpert war, dachte ich mir es wieder mit PowerShell zu probieren.

# Zuerst lassen wir uns die vorhandenen SnapShots / Checkpoints anzeigen
Get-VMSnapshot -VMName 'Name der VM'

image

# Löschen eines dedizierten Checkpoints
Get-VMCheckpoint –VMName 'Name der VM' -Name "SonosGT …" | Remove-VMCheckpoint

Ich wollte gleich alle Checkpoints loswerden und habe dazu analog den Befehle wie schon bei Active Backup for Business verwendet.

# Löschen des Active Backup Snapshots
Get-VMSnapshot -VMName 'Name der VM' | Remove-VMSnapshot

Enjoy it, b!

The file name is too long – Löschen langer Pfade mit der Windows API

Lange Dateinamen und Pfade sind unter Windows eigentlich kein Thema mehr. Dennoch tauchen sie wie ein schlechter Traum, immer wieder auf und stellen einen vor das Problem, wie kann ich diesen langen Dateinamen oder Pfad nun löschen?

:: der normale Ansatz mit rd und dem Verzeichnis
E:\Shares\Projekte-2018> rd 20-old /s /q

Lieferte wie zu erwarten das folgende Ergebnis, mit einer Menge von nicht gelöschten Verzeichnissen und Dateien.

image

“The file name is too long.”

In diesem Beitrag aus dem Jahr 2011 hatte ich schon mal ein Skript mit Robocopy vorgestellt, welches das Problem bei mir zumindest, immer lösen konnte. Allerdings gab es auch einen Kommentar, der die Funktion des Skriptes nicht bestätigen konnte, zumindest nicht für sein Problem mit NetBeans. Eine genaue Validierung des Problems blieb aber aus.

Nun, knapp 12 Jahre danach habe ich mir, aufgrund einer aktuellen Aufgabenstellung darüber wieder Gedanken gemacht und dazu die Windows API verwendet.

:: der Ansatz mit rd über die Windows API
rd \\?\e:\Shares\Projekte-2018\20-old /s /q

Was wiederum nicht funktioniert hat, und mit dem gleichen Ergebnis “The file name is too long.” endete.

Nun besteht seit Windows 10 Version 1607 (und damit auch für den Windows Server 2016) die Möglichkeit “Enable Long Paths” in der Registry oder per GPO zu aktivieren.

image

Maximum Path Length Limitation – Win32 apps | Microsoft Learn

Die Einstellung hatte ich per GPO und einem entsprechendem gpupdate schon auf den Servern bereitgestellt.

Den Artikel sollte man sorgfältig lesen, denn dort werden Dateiverwaltungsfunktionen aufgelistet, welche nach dem Setzen des Registrierungsschlüssel NICHT mehr der MAX_PATH-Einschränkung unterliegen. Was mich wiederum auf die Idee gebracht hat die Sache mit PowerShell und .Net (Directory Class) zu versuchen.

# PowerShell mit .Net Directory Class
[System.IO.Directory]::Delete("E:\Shares\Projekte-2018\20-old", $true)

Damit der Aufruf funktioniert, muss man zwei Dinge beachten.

  1. Der Verzeichnisname muss vollständig übergeben werden, also nicht 20-old sondern E:\Shares\Projekte-2018\20-old
  2. Die Verzeichnisse sind nicht leer und darum benötigen wir noch ein $true um diese ohne Nachfrage zu löschen

Und den dritten Punkt hätte ich beinahe vergessen, Geduld! Das Löschen von ~500GB hat mehrere Stunden gedauert und kam mit der folgenden Meldung zu einem Ende.image

Es war am Ende eine Datei, die das vollständige Löschen verhindert hat. Auf dieser waren, aus welchem Grund auch immer, die ACL verbogen. Also nochmals icacls, wie in diesem Beitrag beschrieben drüber laufen lassen und der erneute Aufruf von [System.IO …] konnte alle restlichen Artefakte entfernen.

So, eigentlich wollte ich nur ein Verzeichnis löschen …

Enjoy it, b!

Unblock-File | Blockierung von Downloads unter Windws

Ein Download aus dem Internet, bekommt unter Windows häufig ein “Blocking”. Das ist auch gut so, schützt es doch vor einer versehentlichen Ausführung unbekannten Codes.

Das Blocking lässt sich mit dem Haken (Unblock) in den Eigenschaften der Datei entfernen.

image

Alternativ kann man hier auch PowerShell verwenden, entweder weil man ohnehin lieber in der PowerShell unterwegs oder weil ein Bedarf für etwaige Automatisierungen / Skripte besteht.

# Unblock der Datei mit PowerShell 
Unblock-File -Path .\wsefix-1903v5.zip

Sollen gleich mehrere Dateien mit der gleichen Endung bearbeitet werden, ist die Verwendung von Get-ChildItem sinnvoll

# Unblock mehrerer Dateien mit PowerShell 
Get-ChildItem -Path *.zip | Unblock-File -Verbose

Enjoy it, b!