HowTo: PowerShell Script for Safe Links Configuration in M365

23rd January 2026 | HowTo HowTo: PowerShell Script for Safe Links Configuration in M365

What This Script Does

Configures Microsoft 365 to allow CyberHoot phishing simulation emails to bypass security filters while maintaining protection for real threats. It handles two critical configurations:

  1. Advanced Delivery – Allows CyberHoot simulation emails through spam/phishing filters
  2. Safe Links – Prevents Microsoft from rewriting/clicking simulation URLs (eliminates false click reports)

Prerequisites

  • PowerShell: Windows PowerShell 5.1+ or PowerShell 7+ (pwsh)
  • Permissions: Exchange Online administrator role
  • Module: ExchangeOnlineManagement (script will install if missing)

Installation

Windows

  1. Download CyberHoot-M365.ps1 to a working directory
  2. Open PowerShell as Administrator
  3. Navigate to the directory: cd C:\path\to\script

macOS/Linux

  1. Download CyberHoot-M365.ps1 to a working directory
  2. Open Terminal
  3. Navigate to the directory: cd /path/to/script
  4. Make executable: chmod +x CyberHoot-M365.ps1

How to Allow-List Link Protection

PowerShell Script to Bypass Link Protection in M365

Save this text file as a .ps1 file and then run as a PowerShell script with appropriate permissions.


Recommended Workflow

Step 1: Validate Current Configuration (Optional but Recommended)

Check what’s currently configured and what will be added:

powershell
./CyberHoot-M365.ps1 -Mode Validate
```

**What it does:**
- Shows which CyberHoot entries are missing
- Reports on existing configuration
- **Makes no changes** to your environment
- Creates JSON snapshots in current directory

**Sample Output:**
```
Validation report:
Advanced Delivery:
 Rule exists: False
 Missing domains: 10
 Missing IP ranges: 9
 Missing simulation URLs: 10
Safe Links:
 Policy exists: False
 Rule exists: False
 Missing DoNotRewriteUrls: 10


Step 2: Apply Configuration

Deploy the CyberHoot configuration:

powershell
./CyberHoot-M365.ps1 -Mode Apply
```

**What it does:**
- Creates/updates Advanced Delivery phishing simulation rules
- Creates/updates Safe Links exclusions
- **Preserves existing vendor entries** (KnowBe4, Proofpoint, etc.)
- Creates before/after JSON snapshots
- Shows summary of what was added

**Sample Output:**
```
Apply completed.

Summary:
 Mode: Apply
 Domains added:            10
 IPs added:                9
 Simulation URLs added:    10
 DoNotRewriteUrls added:   10


Step 3: Verify (Optional)

Re-run validation to confirm everything applied:

powershell
./CyberHoot-M365.ps1 -Mode Validate

Should show all missing counts at 0.


Advanced Usage

Verbose Logging

Get detailed output during execution:

powershell
./CyberHoot-M365.ps1 -Mode Apply -Verbose

Custom Output Directory

Save snapshots to a specific folder:

powershell
./CyberHoot-M365.ps1 -Mode Apply -OutputDir "C:\M365-Snapshots"

Rollback Configuration

Remove only CyberHoot entries (preserves other vendors):

powershell
./CyberHoot-M365.ps1 -Mode Rollback

Warning: This removes CyberHoot’s configuration. Only use if you’re discontinuing CyberHoot or troubleshooting.


Understanding the Output

JSON Snapshots

The script creates timestamped JSON files:

  • cyberhoot-m365-Apply-before-YYYYMMDD-HHMMSS.json – State before changes
  • cyberhoot-m365-Apply-after-YYYYMMDD-HHMMSS.json – State after changes

Use these for:

  • Audit trails
  • Change documentation
  • Troubleshooting
  • Compliance reporting

Troubleshooting

“Missing required cmdlets”

Cause: Insufficient permissions or tenant licensing
Solution: Ensure you have Exchange Online administrator role and Advanced Delivery is available in your tenant

“Pre-flight read check failed”

Cause: Connectivity or permission issues
Solution: Verify you can access Exchange Online admin center manually

Script shows 0 items added on second run

Expected behavior: Script is idempotent – safe to run multiple times without duplicating entries

Safe Links still rewriting URLs after running script

Cause: Configuration propagation delay
Solution: Wait 15-30 minutes, then send a test simulation email


Important Notes

  • Multi-vendor safe: This script merges with existing phishing simulation vendors (doesn’t overwrite)
  • Idempotent: Safe to run multiple times
  • Tenant-wide scope: Safe Links rule applies to all accepted domains
  • Propagation time: Allow 15-30 minutes for Safe Links changes to take effect

Support

For issues with the script, review:

  1. Before/after JSON snapshots
  2. Verbose output: ./CyberHoot-M365.ps1 -Mode Validate -Verbose
  3. Microsoft 365 Admin Center → Security → Advanced Delivery
Latest Blogs

Stay sharp with the latest security insights

Discover and share the latest cybersecurity trends, tips and best practices – alongside new threats to watch out for.

MongoBleed: Why 87,000 Databases Had Their Front Doors Wide Open (And How to Close Yours)

MongoBleed: Why 87,000 Databases Had Their Front Doors Wide Open (And How to Close Yours)

Remember Heartbleed? That security nightmare from a few years back that made everyone panic about their...

Read more
QR Codes Are Back (They Still Want Your Password)

QR Codes Are Back (They Still Want Your Password)

Remember 2020? We scanned QR codes for everything. Restaurant menus. Parking meters. That awkward moment at a...

Read more
AI-Powered Phishing Kits Are Game-Changing, In a Very Bad Way

AI-Powered Phishing Kits Are Game-Changing, In a Very Bad Way

Phishing emails used to be easy to spot. Bad grammar. Weird links. Obvious scams. Those days are...

Read more