Category Archives: Office 365

DriftMaester 1.3.0

With Maester 2.2, we now finally have Sharepoint support and tests! And of course much more, but that’s what stood out most to me. (legacy active directory just makes me feel dirty).

So, DriftMaester also needs to handle these new permissions and has the new pnp module dependency! Time to update 🙂

DriftMaester auto updates, but it doesn’t have permissions to increase its own permissions. So, for whoever wants to leverage the new tests, run this quick oneliner in Azure Shell!

iex ((Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/jflieben/DriftMaester/main/Update-DriftMaesterPermissions.ps1').Content)

You can also run the full GUI again as it is a fully idempotent install (overwrite without delete):

iex ((Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/jflieben/DriftMaester/main/Install-DriftMaester.ps1').Content)

The full changelog of 1.2.0 to 1.3.0 is:

  • SharePoint Online support: the installer grants the managed identity the SharePoint Sites.FullControl.All application role, and the invoke runbook connects PnP.PowerShell to the tenant admin endpoint with that managed identity so the Maester SharePoint Online tests run unattended.
  • Reports now lead with the number of passed tests instead of the score percentage as this is more valueable when new tests are added
  • Fixed the ORCA tests failing with “Cannot find type [PolicyInfo]”. Maester is now imported at script scope in the invoke runbook, because its manifest loads the ORCA class definitions through ScriptsToProcess, which only defines them in the scope that called Import-Module.
  • The installer now reuses the Azure sign-in for Microsoft Graph by passing an Az-issued Graph token to Connect-MgGraph, so the admin signs in once instead of twice.
  • Centralized permissions and added a permissions reconciliation script (Update-DriftMaesterPermissions.ps1) that automatically adds new permissions and can be executed lightweight in Azure Shell

M365AutoRevocate

Offboarding has always been an interesting case, and one I rarely see customers do 100% right. The will is there, often focused on keeping access to data or reclaiming licenses.

But execution is a whole different world. Automation for onboarding often exists, offboarding rarely, and if it exists, it is usually still triggered manually, and more often than not only for managed accounts (admins, guests, service accounts etc are totally forgotten), and then what is actually done upon offboarding?

Microsoft Graph has an option to subscribe to changes, specifically for user objects. This means we can listen to deactivation, idle (x days inactive) or deletion events and act accordingly. E.g. unshare onedrive, notify a manager of flows and powerapps or teams the user still owns, reclaim licenses, disable upon inactve, etc etc.

So I co-wrote a little PowerShell solution, of course perfectly based on best practises around MI auth, least privileges and assume breach.

It lets you configure WHAT (loads of things, expandable) to do WHEN (inactive, delete, deactivate), and runs at almost no cost in your own azure subscription, as usual, open source and a oneliner to install: https://github.com/jflieben/M365AutoRevocate

THOROUGH reporting of a fileshare before migration to Sharepoint and Teams

I’ve been doing a migration project these past months to Sharepoint / Teams.

And boy does the tooling provided suck, I mean…Sharegate / AvePoint are supposed to be a market leaders right? Well, I can tell you it looks more like a cashcow to me, one that’s as good as ready for slaughter.

We wanted to know what cleanup needs to be done by individual teams, we wanted to show reports to them with actionable details, give them a good overview of WHERE in their folder structure to act, and we wanted to see how they were doing over time.

Lots of users also have macro’s….what happens to those? Do they survive a migration, or break? This tool actually tells you by DETECTING the macro’s, then READING them to see if they have external references
(e.g. other files or databases) and flagging them in the report.

It also tells you where inheritance was broken, so you may need to account for that in where to migrate a folder.

And last but not least, it detects duplicate files…helping you save $$$$$

So, here’s a super fast (multi threading) PowerShell solution you can use to generate the type of reporting shown below! Use this, your users / staff will thank you 🙂

https://github.com/jflieben/assortedFunctionsV2/blob/main/FileServerToSPO/PreMigrationReport.ps1

M365AutoLink v1.3

Today brings quite the update to M365AutoLink! Big improvements to central management and performance! Read below for all changes.

Or just get it here: https://github.com/jflieben/M365AutoLink

Security & authentication

  • PKCE + state added to the browser authorization-code flow. Any callback whose state does not match is ignored, so another local process can no longer inject an authorization code.
  • v2 (v2.0) Entra endpoints are now used for both the authorization and token requests (scope= instead of the legacy resource=), aligning with the OAuth 2.1 public-client baseline.
  • Loopback listener hardened: switched from a raw TcpListener on a fixed port to System.Net.HttpListener on an ephemeral port (fixes collisions on multi-session RDS/AVD hosts and races between instances). All reflected error text is HTML-encoded, and a small branded landing page is shown after sign-in.
  • TLS 1.2/1.3 is enforced at startup on Windows PowerShell 5.1.
  • Uninstall now deletes the refresh-token cache and log (RefreshToken.xml is a usable credential and must never survive an uninstall).
  • Consent/sign-in failures no longer call Exit from deep in the request path (which silently killed the tray). They surface as an error balloon with the admin-consent URL and keep the tray alive for a retry.

Reliability

  • Access-token caching fixed: a valid cached access token is now reused instead of performing a full refresh-token exchange (+ DPAPI encrypt + disk write) on every API call. Token lifetime comes from expires_in with a 5-minute renewal margin; the refresh token is written to disk only when Entra rotates it.
  • Deletion circuit breaker: the delete phase is skipped (with a warning + balloon) when SharePoint Search returns incomplete results or the desired set shrank by more than $DeletionSafetyRatio. A tombstone model requires a target to be absent on $DeletionTombstoneRuns consecutive runs before deletion. $ForceReconcile overrides both.
  • Single-instance guard: a session mutex prevents two tray icons / token-rotation races / log contention. A second launch signals the running instance to run and exits.
  • Metadata lookup no longer aborts the whole run on one transient error; failed items are skipped with a warning.
  • Unified retry pipelineInvoke-GraphRaw (config load/save) now retries transient 429/5xx/network errors, with correct Retry-After handling on both PowerShell 5.1 and 7.
  • Logging is written directly to lastRun.log (no longer dependent on Start-Transcript) and rotated (run-<timestamp>.log, keeping $LogHistoryCount).
  • Pre-flight checks warn (in one balloon) when OneDrive is not set up for a work account or the identity provider is unreachable.

Performance

  • Existing-shortcut metadata is fetched in a single RenderListDataAsStream call (with an automatic per-item fallback) instead of one call per shortcut.
  • The fixed Start-Sleep -Milliseconds 500 after every create/rename/delete was removed; throttling is handled by the shared retry/back-off.

UX

  • High-DPI: the process declares per-monitor-v2 DPI awareness and the floating progress bar scales with the display, so the UI is crisp at 125–200% scaling.
  • Manage shortcuts dialog: text filter, click-to-sort columns, Exclude-all/Include-all, and the window is resizable and remembers its size.
  • Periodic auto-refresh ($AutoRefreshHours, default off) re-runs on an interval while resident in the tray and shortly after the device resumes from sleep.
  • First-run onboarding balloon explains where the shortcuts are and points at Manage shortcuts.
  • Reduced the logon console flash on Windows 11 by launching through conhost.exe --headless.

Compatibility & correctness

  • PowerShell 7: large SharePoint JSON payloads use ConvertFrom-Json -AsHashtable instead of the .NET-Framework-only JavaScriptSerializerAdd-Type -AssemblyName replaces the deprecated LoadWithPartialName.
  • Wildcard exclusion/inclusion now uses PowerShell -like (correct anchor semantics). Note: exclusions tighten slightly — a trailing * is required for prefix matches (e.g. */sites/HR*).
  • Window-drag handler resolves the form at event time (dragging borderless dialogs works reliably).
  • Dead-code sweep (unused launch-mode set, per-page blocking GC, stale unique-name state).

Phone number used too many times

Recently ran into a new one when setting up MFA for Microsoft 365:

{"Type":6,"VerificationState":0,"Data":null,"VerificationContext":null,"ErrorCode":29,"ErrorType":null}

I can’t prove, but strongly suggest this means the phone number you’re trying to register is in use for too many accounts and/or tenants.