Es ist überraschend umständlich, die Größe eines Ordners an der PowerShell herauszufinden. Man muss dazu GCI filtern, nur einen Ordner angeben (oder eine zsätzliche Schleife bauen), -recursive durch Unterordner laufen und erhält dann fiese Fehlermeldungen wenn man Symlinks oder NTFS-Streams verwendet.
Ich bin bei einer solchen Aufgabe über das PowerShell Modul PSFoldersize gestolpert. Nach der Installation des Moduls aus der PowerShell Gallery mit:
Löscht man in Microsoft 365 einen Benutzer mit persönlicher Sharepoint-Site, erhält man in Veeam Backup for Office 365 beim sichern diese Fehlermeldung:
Failed to process site: https://<TENANT>-my.sharepoint.com/personal/<USER>. Cannot contact site at the specified URL https://<TENANT>-my.sharepoint.com/personal/<USER>. Access to this Web site has been blocked. Please contact the administrator to resolve this problem.
Der „System Administrator“ kann den gelöschten Nutzer aber nicht mehr sehen, auch in der Veeam-Objektliste nicht.
Das liegt daran, das Microsoft die Site und deren Daten noch 90 Tage lang aufbewahrt, die Site aber den Status „locked“ bekommt. Die Fehlermeldung ist also technisch korrekt, aber wenig hilfreich.
Löschen der Sharepoint-Site
Man kann die Site, sofern nicht mehr benötigt (ist ja gesichert …), einfach „richtig“ löschen, dann verschwindet auch der Fehler sofort.
PowerShell „Als Administrator“ öffnen und das SharePoint Online (SPO) Module installieren: Install-Module -Name Microsoft.Online.SharePoint.PowerShell
Im Tenant als Global Admin bei SPO-Admin anmelden: Connect-SPOService -Url "https://TENANT-admin.sharepoint.com"
Prüfen ob der SPO Nutzer noch vorhanden ist: Get-SPOUser -site "https://TENANT-my.sharepoint.com"
Wenn der Benutzer noch da ist, diesen löschen Remove-SPOUser -Site "https://TENANT-my.sharepoint.com" -LoginName <UPN>
Jetzt kann man nachsehen, ob die persönliche SharePoint Site von diesem Nutzer noch da ist (was vermutlich der Fall ist). Die genaue URL zur Benutzer-Site kann man aus der Veeam-Fehlermeldung kopieren Get-SPOSite "https://TENANT-my.sharepoint.com/personal/USER" | select *
Wenn der Befehl einen Eintrag zurückgibt, auf den „LockState“ schauen. Dieser sollte „Unlock“ sein. Wenn das nicht der Fall ist, Lockstate zurücksetzen: Set-SPOSite "https://<TENANT>-my.sharepoint.com/personal/<USER>" -LockState Unlock
Dann kann man die verweiste Site einfach entfernen: Remove-SPOSite "https://TENANT-my.sharepoint.com/personal/USER"
Wir würden uns wünschen, das Veeam hier eingreift. v5.0.1.252 fixt den Fehler leider nicht nicht, Backup-Jobs aus vorhergehenden Versionen stoppen bei diesem Fehler einfach. Wenn der Standard „Ignore this Object“ wäre, wäre das alles halb so schlimm …
Manchmal muss der Admin genau ein einziges Objekt, oder nur wenige ganz bestimmte Objekte von der Synchronisation vom lokalen AD in das Microsoft 365 Azure AD ausschließen.
Das geht überraschend einfach, mann kann exclude-Regeln einfach im „Synchronization Rule Editor“ hinzufügen.
Schritt für Schritt Anleitung um ein Objekt nicht mehr zu synchroniseren
Zeitplan für die Synchronisation abschalten, damit keine automatischen Aufgaben die Änderungen durcheinander bringen:
Set-ADSyncScheduler -SyncCycleEnabled $False
Der Status des ADSyncSchedulers lässt sich jeder überprüfen mittels:
2. „Synchronization Rules Editor“ starten (als Administrator)
3. In der „View and manage …“ Liste die „Direction“ auf „Inbound“ stellen und eine freie Nummer unterhalb der bestehenden „Precedence“ Regeln finden (und merken). In der Regel ist das irgendetwas <100.
4. Oben rechts „Add New rule“
5. Den „Create inbound synchronization rule“ Assistenten nun ausfüllen:
Name: Ein beschreibender Name, z.B. „In from AD – Bernd auslassen“
Connected System: Der lokale AD Forest
Connected System Object Type: user
Metaverse Object Type: Person
Link Type: join
Precedence: Die gemerkte Nummer von oben (z.B. „90“)
„Tag“, „Enable Password Sync“ oder „Disabled“ nicht verändern
Next > …
6. „Add group“ > dann > „Add clause“
7. Als „Attribut“ ein zu filterned Attribut wählen, zum Beispiel den „name“ oder ein anderes Attribut. Bei größeren Mengen an Objekten nutzen wir hier gerne die „Extended Attributes“, die normalerweise solange ungenutzt und leer sind. Der Operator ist im Beispiel „equal“, der „Value“ der zu matchende Inhalt.
8. „Next >“, an den nun angezeigten „Add join Rules“ nichts ändern > „Next >“
9. Bei den „Add join rules“ eine Transformation hinzufügen:
Da es in Microsoft Office 365 leider keine „Generierungsrichtlinie“ gibt, oder zumindest keine auf die man schreibenden Zugriff hat, muss man für neue Alias-Domains jeden Benutzer einzeln anfassen. Jedem Postfach müssen die neuen E-Mailadressen einzeln hinzugefügt werden. Bei vielen Postfächern (oder Domains) ein sehr ermüdender Job.
Das ist auch erst einmal so, denn Microsoft scheint der Meinung, das eine E-Mail Domain für immer genug sei. Oder zumindest Änderungen daran selten.
Natürlich kommen Namens- oder Domainänderungen in der Realität aber ständig vor, auch für (neue) Alias-Domains. Der findige Admin macht das natürlich nicht mehr manuell im ECP, sondern an der PowerShell.
Neuen Domain E-Mail Alias mit der PowerShell hinzufügen
Ich nutze ein kleines „AddEMailAliasDomain“ Script. Die Domain example.com ist die „alte“ und richtige Absende-Adresse, beispiel.de ist die neue hinzuzufügende. Es wird nach der „alten“ Domain gefiltert, damit keine anderslautenden Postfächer verändert werden.
Ich musste grade eine ganze Menge deaktivierter ActiveDirectory Benutzer aus allen Gruppen entfernen. Andernfalls hätten diese im AADConnect Synchronisationsfehler ausgelöst, da hier deaktivierte Benutzer-Objekte nicht synchronisiert werden.
Mein PowerShell Script das das sehr erfolgreich übernommen hat sieht so aus:
# Durch die OU laufen und deaktivierte User einsammeln ...
foreach ($username in (Get-ADUser -Filter {enabled -eq $false} -SearchBase "OU=<HIER SUCHEN>,DC=<DOMAIN>,DC=<TLD>")) {
# ... deren Group-Memberships holen ...
$groups = Get-ADPrincipalGroupMembership $username;
# ... durch die Gruppen laufen ...
foreach ($group in $groups) {
# ... wenn Gruppenname stimmt (z.B. "VPN*") ...
if ($group.name -Like "<NAME>") {
# ... User entfernen
Remove-ADGroupMember -Identity $group.name -Member $username.SamAccountName -Confirm:$false;
# Ausgabe
write-host "Habe" $username "von" $group.name "entfernt";
}
}
}
Das funktioniert natürlich nicht nur mit Sicherheitsgruppen, sondern auch mit Verteilerlisten.
Die Suche nach dem/den Gruppennamen kann man in der Zeile $group.name -Like "Domänen-*" anpassen; hier tun es natürlich auch die anderen Operatoren wie -eq oder -neq.