# Office365 and a PowerShell script collection for Microsoft 365 administration

> This repository is a working collection of PowerShell scripts for Microsoft 365 administration and security operations, wired around the Graph API, Defender, Intune and Sentinel, with a set of interactive simulators for sign-in and mail flow. The interesting part is the SharePoint connection script, which authenticates with a certificate on Linux through PnP.PowerShell, and the interesting constraint is that the whole surface is unlicensed scripts rather than a maintained product.

**directorcia/Office365** — Office 365 scripts and information

- Repository: https://github.com/directorcia/Office365
- Stars: 553 · Forks: 246
- Language: PowerShell
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/directorcia-office365

## What this repository actually is

The title is Office 365 Security and Admin Scripts, and the description is practical scripts, tools and simulation assets for Microsoft 365 administration, security operations and troubleshooting. The primary language is PowerShell.

This is not a library and not a module. It is a directory of individual scripts, and the naming convention tells you how it is organised. There is a graph- family covering Microsoft Graph reads and writes, with files like graph-connect.ps1, graph-signins-get.ps1, graph-users-get.ps1, graph-globaladmins-get.ps1, graph-licenses-get.ps1, graph-diraudit-get.ps1, graph-idauthpolicy-get.ps1, graph-summary-get.exe and graph-mbx-rules.exe. There is an asd- family for Advanced Security Defender style data pulls, including asd-ca-get.ps1 for Conditional Access, asd-ioscomp-get.ps1, asd-mailflow-get.ps1, asd-owamail-get.ps1, asd-remotedomain-get.ps1 and asd-wincomp-get.ps1. There is an m365- family for tenant-wide reporting, with m365-inactiveusers-get.ps1, m365-senslabel-get.ps1 and m365-ir.ps1. There is an az- family for Azure, including az-connect.ps1, az-connect-si.ps1, az-connect-si-cert-linux.ps1 and az-keyvault-saveto.exe, and an eid- family for Entra ID app registration changes, with eid-resetapp-set.ps1 and eid-resetapp-set-direct.ps1. There are also a handful of one-off scripts with descriptive names: Intune-connect.ps1, O365-connect-aad.ps1, Cleanup AzureAD device registration.ps1, email-header-report.ps1, enable-location-services.ps1, ipget.ps1 and ipinf.ps1.

The last two are worth a second look. ipget.ps1 and ipinf.ps1 are named after the IP address APIs rather than after a Graph resource, which tells you the collection also reaches outside Microsoft 365 to third-party lookups.

The audience is a Microsoft 365 administrator, a security analyst or a consultant who needs a working script for one task today rather than a product to build on. The repository is not archived and the last push was on 2026-10-22, so the scripts are being touched, but there are no GitHub releases, which means there is no version to pin and no compatibility statement.

The licence is one GitHub cannot classify, and the README does not summarise it. That is the first thing to check before you run any of this in a tenant you care about.

## The SharePoint certificate connection on Linux

One script in the collection is documented in enough detail to be worth reading closely, because it solves a problem that is genuinely awkward: connecting to the SharePoint admin center from Linux with certificate authentication.

The script is o365-connect-spo-cert-linux.ps1, and it connects to the SharePoint admin center using an encrypted PFX. The README says to keep o365-connect-pnp-cert-linux.ps1 beside it, because the SPO script reuses that template for certificate generation, application provisioning, private file storage and connection.

The requirements are stated precisely: Linux and PowerShell 7.4.6 or newer. Connections use PnP.PowerShell 3.0.0 or newer, not the Windows-only SharePoint Online Management Shell. And the README is explicit about a mistake that is easy to make: use PnP commands such as Get-PnPTenantSite, not Get-SPOSite, after connecting in the same session.

That last point is the kind of detail that saves an afternoon. The SharePoint Online Management Shell does not run on Linux, so a script copied from a Windows blog post will fail at the first Get-SPOSite, and the fix is not a syntax change but a different command module.

There are three documented usage modes, and the difference between them is about whether a human is present.

```powershell
# One-time setup; prompts for a PFX password and administrator device-code sign-in.
./o365-connect-spo-cert-linux.ps1 -GenerateLocalCertificate -ProvisionEntraApp -Tenant contoso.onmicrosoft.com

# Subsequent connections; prompts for the encrypted PFX password.
./o365-connect-spo-cert-linux.ps1 -UseCertificateAuth -ProfileName O365-SPO-AppAuth

# Unattended connection with a password injected by a secret manager.
./o365-connect-spo-cert-linux.ps1 -UseCertificateAuth -ProfileName O365-SPO-AppAuth -Headless -CertificatePasswordEnvironmentVariable SPO_PFX_PASSWORD
```

The first mode is the setup: generate a local certificate and provision the Entra application, with a device-code sign-in so an administrator can approve the registration interactively. The second reuses that generated credential for later connections and only prompts for the PFX password. The third is the one worth understanding for automation, because it removes the prompt entirely by taking the password from an environment variable named SPO_PFX_PASSWORD, which is the shape a secret manager can fill.

## What the script provisions and what it refuses to store

The permissions and the storage model are both spelled out, and they are the parts that decide whether you can use this in a production tenant.

On permissions, the README states that provisioning grants SharePoint Sites.FullControl.All and Microsoft Graph Application.Read.All. That is a deliberately small set compared to a typical SharePoint administrator role, and it is worth noticing that Application.Read.All on Graph is an application permission, so it applies to the app's own identity rather than to a signed-in user.

On storage, the README says certificates and profiles use private XDG data and config directories under ciaops/spo, and that passwords are never saved in profiles. That is the right design. A connection profile that persists a PFX password in plaintext is a credential at rest, and a credential at rest in a home directory is a credential that ends up in a backup, a synced folder or a support ticket screenshot. Keeping only the certificate in the profile and the password in the environment means the unattended path is safe and the interactive path never writes the secret down at all.

The XDG part matters too. Using the XDG data and config directories rather than a dotfile in the home directory means the profile lives where the rest of the user's application state lives, which is what a Linux administrator expects and what makes it straightforward to reason about permissions on.

Two further operational notes are in the README. Headless connections require preinstalled modules and a supplied password, so the script does not install its own dependencies in that mode, which is the right behaviour for a script that may run in a container. And you can specify -AdminUrl for tenant GUIDs, custom domains or renamed SharePoint tenants, because the tenant's admin URL is not always the predictable one.

For everything else, the README points at Get-Help ./o365-connect-spo-cert-linux.ps1 -Full, which covers all the options, including using an existing application and PFX without provisioning.

## The simulators, which are the unusual part

Alongside the scripts there is a set of interactive simulators, and they are the part of the repository with no obvious analogue in most script collections.

The M365 Login simulator visualizes Microsoft 365 sign-in behavior, authentication stages and Conditional Access decision points. The M365 Mail Security simulator demonstrates Exchange Online and Defender for Office 365 mail flow, filtering and policy evaluation order. The third entry, the Image Model Comparison, compares image-generation results from different models, including creation dates and image properties, which is a different kind of tool entirely and suggests the author is running comparisons for other purposes in the same space.

The first two are the interesting ones, and the reason they exist is worth spelling out. Conditional Access evaluation order is a genuine source of confusion: a policy that looks correct on paper can be overridden by a later policy, and a sign-in that appears to be challenged for the wrong reason is hard to debug from the tenant side alone. A simulator that shows the stages a request passes through is a teaching tool for that evaluation order, and it is the kind of thing you would otherwise build by hand in a browser.

The mail flow simulator covers the same ground for mail, where the order in which filtering, transport rules and Defender policies apply determines whether a message is delivered, quarantined or blocked, and where the same message can take different paths depending on how the policies are ordered.

The README describes them as interactive simulators to walk through common Microsoft 365 security scenarios, and they are hosted as static pages under the project GitHub Pages site. There is also a retro wargame, Tigers in the Snow / Ardennes: Winter Offensive, a browser-based game inspired by the Battle of the Bulge, which is unrelated to the admin scripts but tells you something about the repository's character.

There is also a wiki, and the README points at it as the place to start, so the actual guidance for using these assets lives outside the repository readme.

## The wider file tree, and what it implies about scope

The top-level entries give the clearest picture of the scope, and it is wide.

Beyond the scripts already described, there are directories for AI-Ready/, Analysis/, Cowork-Skills/ and docs/, plus a batch of support files. There is an O365-suite-usage.xlsx spreadsheet, a best-practices.txt file, an ipget.ps1 and ipinf.ps1 pair, a graph-odfb-get.exe, and several .exe files where you would expect a .ps1: graph-adapp-add.exe, graph-adapp-del.exe, graph-adapp-per-add.exe, graph-adapp-per.exe, graph-adappperm-del.ps1, graph-mbx-rules.exe, graph-summary-get.exe, graph-summarymx-get.exe, graph-summaryodfb-get.exe, az-keyvault-saveto.exe and mde-apioffboard.ps1.

The mixture of .ps1 and .exe is a packaging decision rather than a technical one, and it is worth asking about before running anything. An .exe in a script repository cannot be read, and the fact that some operations ship as compiled binaries while others ship as readable scripts is a signal about which parts the author wanted protected or compact.

The names also suggest several distinct workflows rather than one. There are reporting scripts with -get suffixes that pull configuration and sign-in data for assessment, there are -set scripts that change policy, and there are offboarding scripts such as mde-apioffboard.ps1 and mde-offboard-check.ps1. The Graph scripts that create and delete app registrations and permissions sit in the same tree, which means this repository includes scripts that grant and revoke application permissions, which is a category that deserves more caution than a read-only reporting script.

The other notable files are the ones that suggest tooling rather than scripts: cw-skykick-exposure-check.ps1 and cw-skykick-iocs.json, which look like exposure checking against a set of indicators, find-name-conflict.ps1, endpoint-api-svbm.ps1, and the graph-signins-get.ps1 style reporting.

The .github/ directory holds the workflows, and the repository carries no GitHub releases, so the scripts are read from the branch rather than consumed at a version.

## Where this collection is the wrong choice

Three limits follow from what the repository is and is not.

The first is support and versioning. There are no releases, so there is no way to say which version of a script ran against which tenant state, and the Graph API and the Defender cmdlets both change. A script collection like this is a set of working examples rather than a maintained product, and the README's framing as practical scripts for administration and troubleshooting reflects that. The GitHub issues path is the only support channel described.

The second is that you inherit the script, all of it, and it is a lot of script. The Graph app registration and permission management files, the offboarding scripts, the Defender offboarding files, these are operations with real consequences in a tenant, and they are distributed as loose files in a directory rather than as a module with parameter validation, tests and a version floor. There is a best-practices.txt file at the root, which suggests the author has opinions, but a text file of advice is not the same as the checks a module would run.

The third is the licence. The project is listed under a custom licence that GitHub cannot classify, and the readme does not summarise it. For personal experimentation in a test tenant that is not a blocker. For a script you intend to run in a production tenant, or to fork and build on inside a product, the licence text is the thing to read first, and the absence of a summary in the readme is not a good sign.

The alternative to a script collection is not another script collection. It is the official tooling: the Graph PowerShell SDK, the Microsoft Graph CLI, the Defender and Intune PowerShell modules, and the PnP.PowerShell module that this very repository's SharePoint script depends on. The difference in approach is that those are versioned modules with published support lifecycles and documented parameters, and they cover the same operations. The trade is real: the official modules take longer to learn and do not include the specific report format or the consolidated workflow these scripts provide, and they do not carry the years of accumulated practical fixes that end up in a collection like this one.

## Conclusion

Office365 is a good fit for a Microsoft 365 administrator who wants a working script for a specific reporting or remediation task instead of writing the Graph query from scratch, because the repository is organised by task, with graph-signins-get.ps1, graph-users-get.ps1, intune-policy-get.ps1 and a long list of asd- and mde- prefixed scripts. It is a poor fit if you need a supported, versioned product with a compatibility promise, since there are no GitHub releases and the licence is one GitHub cannot classify, and a poor fit for SharePoint administration on Windows if you follow the Linux path, since the scripts require PowerShell 7.4.6 and PnP.PowerShell 3.0.0 or newer rather than the Windows-only SharePoint Online Management Shell. Before adopting anything from it, read the LICENSE file, and check that the script you need is current against the Graph endpoint it calls.

## FAQ

### How do I connect to SharePoint Online from Linux with certificate authentication?

Use the o365-connect-spo-cert-linux.ps1 script in this repository, which requires Linux with PowerShell 7.4.6 or newer and PnP.PowerShell 3.0.0 or newer rather than the Windows-only SharePoint Online Management Shell. After connecting, use PnP commands such as Get-PnPTenantSite instead of Get-SPOSite.

### How do I run the Office365 SharePoint connection script unattended?

Use the Headless switch together with a password supplied by a secret manager through the CertificatePasswordEnvironmentVariable parameter, pointing at the SPO_PFX_PASSWORD environment variable. Headless connections require preinstalled modules and a supplied password.

### What permissions does the SharePoint connection script grant?

Provisioning grants SharePoint Sites.FullControl.All and Microsoft Graph Application.Read.All. The script stores certificates and profiles in private XDG data and config directories under ciaops/spo, and passwords are never saved in profiles.

### What kinds of Microsoft 365 tasks do the scripts in this repository cover?

The tree is organised by task, with a graph- family for Microsoft Graph reads and writes, an asd- family for Defender style data pulls such as Conditional Access, mail flow and remote domain data, an m365- family for tenant-wide reporting like inactive users and sensitivity labels, an az- family for Azure connections, and eid- scripts for Entra ID app registration changes.

### What simulators does the Office365 repository include?

Two interactive simulators for Microsoft 365 security scenarios: one visualizing sign-in behavior, authentication stages and Conditional Access decision points, and one demonstrating Exchange Online and Defender for Office 365 mail flow, filtering and policy evaluation order. A third page compares image-generation results from different models.

### What licence applies to the Office365 scripts?

The project is listed under a custom licence that GitHub cannot classify, and the licence file is at the repository root. The repository has no GitHub releases, and the last push was on 2026-10-22.

## Sources

- [directorcia/Office365 on GitHub](https://github.com/directorcia/Office365)
- [Issues](https://github.com/directorcia/Office365/issues)
- [README](https://github.com/directorcia/Office365/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/directorcia-office365
