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!

Synology Directory Server | Hyper-V Replica schlägt fehl–Kerberos Fehler

Ich arbeite bei kleinen Projekten gerne mit dem Synology Directory Server als Ersatz für das Microsoft Active Directory (AD). Bei wenigen Benutzern lassen sich damit einige Kosten sparen. Gelegentlich besteht jedoch auch hier die Anforderung, eine virtuelle Maschine (VM) hochverfügbar bereitzustellen. Dafür habe ich bisher immer den Microsoft Hyper-V Server (2019) in Verbindung mit der Hyper-V Replica verwendet.

Das klassische Setup funktionierte bis zur Aktivierung der Hyper-V-Replikation problemlos:

  • Join der beiden Hyper-V-Hosts in die Domäne des Synology Directory Servers
  • Öffnen der Firewall auf den Hyper-V-Hosts, um über Port 80 oder 443 zu replizieren
  • Verwendung der Kerberos-Authentifizierung (HTTP) für die Replikation
  • Einrichten der Hyper-V Replica für eine oder zwei VMs

Allerdings wurde ich am Ende der Konfiguration mit folgender Fehlermeldung konfrontiert – und konnte zunächst nichts damit anfangen:

image

Ja klar, es gibt ein Problem mit Kerberos … aber warum?

Die Namensauflösung funktionierte, und auch die ServicePrincipalNames waren registriert.

image

Auch die Ports 80 und 443 waren über die Firewall geöffnet und antworteten wie erwartet.

Mein Verdacht fiel nach einiger Zeit auf den Synology Directory Server. Dieser stellt eine Domäne mit folgendem Functional Level bereit:

  • Domain Functional Level: Equal to Windows Server 2008 R2

Die Hyper-V Replica wurde mit Windows Server 2012 eingeführt – was aber nicht zwingend bedeutet, dass die Domäne ebenfalls auf diesem Level sein muss. Ich vermute jedoch, dass hier – möglicherweise in Verbindung mit der Tatsache, dass intern Samba 4.10 läuft – das Problem liegt.

Als Alternative wollte ich nun die Authentifizierung per Zertifikat verwenden.

image

Dabei bin ich über eine Reihe von Herausforderungen gestolpert, die sich aber letztendlich lösen ließen. Als Grundlage habe ich diese Anleitung verwendet, die aber nur mit kleineren Modifikationen funktionierte.

Ein wichtiger Unterschied ist auf jeden Fall, dass meine beiden Hyper-V Hosts in der Domain verbleiben sollen, also nicht in einer Workgroup betrieben werden.

  • Insgesamt werden n+1 (N = Anzahl der Hyper-V Hosts die an der Replikation teilnehmen) Zertifikate erstellt. Für jeden Hyper-V Host eines (das Server-Zertifikat) und das Root-Zertifikat. Bei zwei Hosts, haben wir damit drei Zertifikate
  • Während das Root-Zertifikat auf jedem der Hyper-V Hosts installiert wird, bekommt jeder Host ein eigenes Server-Zertifikat

Auf dem ersten Knoten wird eine PowerShell-Sitzung als Administrator gestartet und dazu die folgenden Variabel angelegt.

Dabei bin ich auf einige Herausforderungen gestoßen, die ich aber lösen konnte. Als Grundlage diente mir eine Anleitung, die jedoch nur mit kleineren Anpassungen funktionierte.

Ein wichtiger Unterschied: Meine beiden Hyper-V-Hosts sollen in der Domäne verbleiben und nicht in einer Workgroup betrieben werden.

  • Insgesamt werden n+1 Zertifikate benötigt (n = Anzahl der Hyper-V-Hosts, die an der Replikation teilnehmen). Für jeden Host ein Server-Zertifikat sowie ein Root-Zertifikat. Bei zwei Hosts ergibt das drei Zertifikate.
  • Das Root-Zertifikat wird auf jedem Hyper-V-Host installiert, jeder Host erhält zusätzlich ein eigenes Server-Zertifikat.

Auf dem ersten Host wird eine PowerShell-Sitzung als Administrator gestartet und die folgenden Variablen gesetzt:

image

Dann wird das Root-Zertifikat erstellt. Dafür habe ich die folgenden Änderungen vorgenommen (Zeile 26).

  • KeyUsage CertSign  in KeyUsage CertSign, CRLSign, DigitalSignature

In Zeile 27

  • KeyLength 2056 in KeyLength 4096

image

Der Server, auf dem das Root-Zertifikat wurde, muss diesem ebenfalls vertrauen. Darum wird das Zertifikat von Personal nach Trusted Root Certification Authorities kopiert.

image

Nun werden auf demselben Knoten sowohl das Root-Zertifikat exportiert als auch die Server-Zertifikate erstellt.

image

Auch bei der Erstellung der Server-Zertifikaten habe ich Änderungen vorgenommen:

  • Hinzufügen eines weiteren Parameters (Zeile 64), wobei zuvor (Zeile 60) der FQDN erstellt wird:
    DnsName $fqdn, $name
  • KeyLength 4096

image

Auf allen Hyper-V Hosts muss nun die Prüfung der Zertifikate deaktiviert werden.

image

Nun werden die Zertifikate auf die anderen Knoten (hier nur einer) verteilt.

image

Tipp: Der “\” am Ende des Pfads erstellt das Verzeichnis automatisch.

Nun wird auf dem zweiten Knoten sowohl das Root- als auch der Server-Zertifikat importiert

image

Das sieht dann auf jedem Hyper-V Host wie folgt aus.

image

image

Damit sollte die Hyper-V Replikation eigentlich funktionieren – tat sie aber nicht. Zusätzlich zur certificate-based Authentification (HTTPS), musste ich auch noch die Verwendung von Kerberos (HTTP) aktivieren! Warum, kann ich nicht genau sagen und muss hier nochmals mit einem Netzwerk-Trace, der Sache auf den Grund gehen.

image

Mit dieser Konfiguration funktioniert nun die Hyper-V Replikation auch mit Hyper-V Hosts, die Mitglied in einer Samba-Domain und dem Synology Directory Server sind.

Enjoy it, b!