Compensation Folder Automation - Complete Guide
📌 THIS IS THE OFFICIAL, CONSOLIDATED README - Use this file as your reference guide
Replaces: README-CompensationFolders.md and COMPENSATION-FOLDER-AUTOMATION-README.md
⚡ Quick Reference
If you just want to run it and don't need details:
# 1. Connect to VPN
# 2. Open PowerShell
# 3. Navigate to script directory:
cd "C:\Users\Jricica\OneDrive - Rudolph Libbe Group\Scripts\OneDrive-SharePoint"
# 4. Run THIS command (the production wrapper script):
.\Run-CompensationFolders-Production.ps1
# DO NOT run New-CompensationFolderStructure.ps1 directly!
First time running? Read the full guide below, especially Prerequisites.
📋 Table of Contents
- Quick Reference
- What This Does
- How the Cascading Permissions Work
- Prerequisites
- Pre-Flight Checklist
- Running the Script
- What to Expect
- Troubleshooting
- Post-Run Verification
- Advanced Usage
- Technical Details
- Support
🎯 What This Does
This automation creates a compensation review folder structure in SharePoint Online with automatic cascading permissions based on your Active Directory organizational hierarchy.
What It Creates (Flat Structure - Default):
SharePoint: RLGManagers Site
└── Documents
└── General
└── Bonus 2025 NEW
├── Rudolph, Bill
├── Executive 1
├── Executive 2
├── Manager A
├── Manager B
├── Manager C
├── Manager D
└── (all other managers at same level)
Note: All folders are created at the same level (flat structure). This ensures managers can navigate directly to their folders without needing access to parent folders.
Automatic Permissions:
- Bill Rudolph (CEO) → Edit access to ALL folders (entire company)
- Executive 1 → Edit access to their folder + all their subordinates' folders (Manager A, Manager B, etc.)
- Manager A → Edit access to their folder + their subordinates' folders (Manager B, etc.)
- Manager B → Edit access to only their folder
- Security: Other site members cannot see any folders (unique permissions)
How It Works: The organizational hierarchy is maintained through permissions, not folder nesting. Each manager can only see and access their own folder and their subordinates' folders, even though all folders appear at the same level.
Key Features:
- ✅ Reads organizational structure from Active Directory
- ✅ Creates flat folder structure with one folder per manager
- ✅ Sets edit permissions for entire management chain (based on org hierarchy)
- ✅ Breaks permission inheritance for security
- ✅ Handles email/UPN mismatches automatically
- ✅ Generates detailed log file for audit trail
- ✅ Ensures all managers can navigate to their folders without access issues
🔐 How the Cascading Permissions Work
Each manager receives Edit access to:
- Their own folder
- All direct reports' folders
- All managers who report to them (and their folders)
- All employees down their entire reporting chain
Example Organizational Chart:
CEO (Jane Smith)
├── VP of Operations (John Doe)
│ ├── Plant Manager (Mike Johnson)
│ │ ├── Supervisor (Sarah Lee)
│ │ │ ├── Employee A
│ │ │ └── Employee B
│ │ └── Employee C
│ └── Safety Manager (Tom Wilson)
│ └── Employee D
└── VP of Finance (Lisa Brown)
└── Controller (David Garcia)
└── Employee E
Who Can Access What:
| Person | Can Access These Folders | Total Folders |
|---|---|---|
| CEO Jane | Everyone (herself + all 10 subordinates) | 11 folders |
| VP John | Himself + all 7 in Operations chain | 8 folders |
| Plant Manager Mike | Himself + Sarah + Employee A + Employee B + Employee C | 5 folders |
| Supervisor Sarah | Herself + Employee A + Employee B | 3 folders |
| VP Lisa | Herself + David + Employee E | 3 folders |
| Employee A | No access since they do not have any direct reports |
Important Notes:
- ✅ Permissions cascade down the org chart (managers can see subordinates)
- ❌ Permissions do NOT cascade up (employees cannot see their managers' folders)
- ✅ Peers cannot see each other's folders (John can't see Lisa's folders)
- ✅ Site Collection Administrators (HR Director) can see everything
✅ Prerequisites
1. Network Access
- Connected to RLG VPN (required for Active Directory access)
- Internet connection (required for SharePoint Online)
2. PowerShell Modules
Open PowerShell as Administrator and run:
# Check if modules are installed
Get-Module -ListAvailable PnP.PowerShell, ActiveDirectory
# If missing, install them:
Install-Module -Name PnP.PowerShell -Scope CurrentUser -Force
# ActiveDirectory module comes with RSAT tools (usually already installed)
3. Permissions Required
- Active Directory: Read access to user objects and organizational hierarchy
- SharePoint: Site Owner or Site Collection Administrator on
https://rlgbuilds.sharepoint.com/sites/RLGManagers - Azure AD App: Access to the RLG SharePoint enterprise app (authentication handled automatically)
4. Site Collection Administrator Setup (CRITICAL for HR Access)
⚠️ IMPORTANT: The HR Director (or person responsible for compensation management) MUST be a Site Collection Administrator to access all folders.
Why? The script breaks permission inheritance on all folders for security. Only these people will have access:
- ✅ Site Collection Administrators (HR Director, IT admins)
- ✅ Managers in the reporting chain (granted by script)
- ❌ Regular Site Owners (no access to folders)
- ❌ Site Members (no access to folders)
How to Add HR Director as Site Collection Administrator:
- Navigate to the site:
https://rlgbuilds.sharepoint.com/sites/RLGManagers - Click the Settings gear (⚙️) in the top right
- Select Site settings
- Under Users and Permissions, click Site Collection Administrators
- In the text box, enter the HR Director's email (e.g.,
hr.director@rlgbuilds.com) - Click OK
Verify:
# Connect to SharePoint
.\Connect-SharePoint.ps1 -SiteUrl "https://rlgbuilds.sharepoint.com/sites/RLGManagers"
# Check who has Site Collection Admin rights
Get-PnPSiteCollectionAdmin
You should see:
- Your account (IT admin)
- HR Director's account
- Any other administrators
✅ Checklist:
- HR Director is listed as Site Collection Administrator
- HR Director can access the site
- After running script, HR Director can access all folders
5. Active Directory Cleanup
⚠️ IMPORTANT: Before running, ask HR to ensure:
- Terminated employees with direct reports have been reassigned to active managers
- Disabled accounts are not in manager positions with active reports
- Bill Rudolph (CEO) is at the top of the org chart
Why? The script grants permissions via Microsoft 365. Disabled/unlicensed accounts will cause permission failures.
🚦 Pre-Flight Checklist
Before running the production script, verify:
1. Site Collection Administrators Configured
CRITICAL FIRST STEP - Ensure HR Director has full access:
# Connect to the site
.\Connect-SharePoint.ps1 -SiteUrl "https://rlgbuilds.sharepoint.com/sites/RLGManagers"
# Verify Site Collection Administrators
Get-PnPSiteCollectionAdmin
Confirm:
- HR Director is listed as Site Collection Administrator
- Your account is listed (you're running the script)
- All required admins are listed
If HR Director is missing: Follow the steps in Prerequisites > Site Collection Administrator Setup
2. SharePoint Site Structure
Navigate to: https://rlgbuilds.sharepoint.com/sites/RLGManagers/Shared%20Documents
Confirm:
- "General" folder exists in the Documents library
- You have edit permissions (can create folders)
3. Working Directory & Understanding the Scripts
Navigate to the script directory:
cd "C:\Users\YourUsername\OneDrive - Rudolph Libbe Group\Scripts\OneDrive-SharePoint"
# Verify files exist
ls *.ps1
⚠️ IMPORTANT: Understanding Which Script to Run
There are multiple PowerShell scripts in this directory. Here's what each one does:
Scripts You Will Run:
Run-CompensationFolders-Production.ps1 ⭐ ← RUN THIS FOR PRODUCTION
- This is your main production script
- Pre-configured with correct defaults:
- Site: RLGManagers
- Path: General/Bonus 2025 NEW
- Top Manager: Bill Rudolph
- Structure: Flat
- Shows confirmation prompts before running
- Analyzes and displays results afterward
- Internally calls the main engine script
Test-CompensationScript.ps1 ⭐ ← RUN THIS FOR TESTING
- Test version that uses the JRTestTeam site
- Safe for testing without affecting production
- Same functionality as production script
- Internally calls the main engine script
Scripts Called Automatically (Don't Run Directly):
New-CompensationFolderStructure.ps1 🔧 ← THE ENGINE (800+ lines)
- DO NOT run this directly unless you know what you're doing
- This is the main automation engine with all the logic:
- Active Directory queries
- Folder creation
- Permission management
- Graph API integration
- Called by Run-CompensationFolders-Production.ps1 and Test-CompensationScript.ps1
- Requires all parameters to be specified
- Both files are needed - don't delete either one!
Connect-SharePoint.ps1 🔌 ← HELPER SCRIPT
- Authentication helper
- Called automatically by other scripts
- Can run manually if you need to connect to SharePoint for troubleshooting
How They Work Together:
You run: Run-CompensationFolders-Production.ps1
↓
(Shows settings, asks for confirmation)
↓
Calls: New-CompensationFolderStructure.ps1
↓
(Does all the work: AD queries, folders, permissions)
↓
Returns control to production script
↓
(Production script shows summary and results)
Analogy:
- New-CompensationFolderStructure.ps1 = The car engine (complex, powerful, requires expertise)
- Run-CompensationFolders-Production.ps1 = The steering wheel and dashboard (easy to use, has defaults)
You could operate the engine directly with manual controls, but the steering wheel makes it much easier!
DO NOT DELETE:
- ❌ Don't delete
New-CompensationFolderStructure.ps1- Nothing will work - ❌ Don't delete
Run-CompensationFolders-Production.ps1- You'll lose production defaults - ❌ Don't delete
Connect-SharePoint.ps1- Authentication will fail - ✅ Keep all scripts in the directory
4. Test Run (Optional but Recommended)
Before production, test with a smaller department:
.\Test-CompensationScript.ps1 -TopManager "Doug.Mallette@rlgbuilds.com"
This creates a test folder in the JRTestTeam site using flat structure (default) that you can verify and delete afterward.
🚀 Running the Script
⭐ QUICK START: The command you need to run is:
.\Run-CompensationFolders-Production.ps1
DO NOT RUN New-CompensationFolderStructure.ps1 directly - it's the engine that gets called automatically!
Production Run - Step by Step
Step 1: Open PowerShell
- Press
Windows + X - Select "Windows PowerShell" or "Terminal"
- Navigate to script directory:
cd "C:\Users\YourUsername\OneDrive - Rudolph Libbe Group\Scripts\OneDrive-SharePoint"
Step 2: Execute Production Script
.\Run-CompensationFolders-Production.ps1
Default Settings:
- Site:
https://rlgbuilds.sharepoint.com/sites/RLGManagers - Path:
Documents > General > Bonus 2025 NEW - Top Manager:
Bill.Rudolph@rlgbuilds.com - Structure: Flat (all folders at same level - recommended)
Step 3: Review Configuration
The script will display:
========================================
Compensation Folder Creation - 2025
========================================
This script will:
✓ Build organizational hierarchy from AD
✓ Connect to SharePoint: https://rlgbuilds.sharepoint.com/sites/RLGManagers
✓ Create folder structure: General/Bonus 2025 NEW
✓ Set cascading edit permissions automatically
✓ Break permission inheritance for security
Configuration:
Top-level manager: Bill.Rudolph@rlgbuilds.com
Folder structure: Flat
(All manager folders at same level - ensures proper navigation)
Continue? (Y/n)
Step 4: Authenticate to SharePoint
When prompted:
- A browser window will open
- Go to
https://microsoft.com/devicelogin - Enter the device code shown in PowerShell
- Sign in with your RLG Microsoft 365 account
- Accept the permissions prompt
Step 5: Monitor Progress
The script will show:
[Step 1/4] Building organizational hierarchy from Active Directory...
[0] Rudolph, Bill - 8 direct reports
[1] Schaller, Jeff - 12 direct reports
[2] Manager Name - 5 direct reports
...
[Step 2/4] Connecting to SharePoint Online...
✓ Connected
[Step 3/4] Creating folder structure...
Creating root folder: General/Bonus 2025 NEW
Root folder created/verified
Creating folder: General/Bonus 2025 NEW/Rudolph, Bill
SUCCESS: Created Rudolph, Bill
Breaking permission inheritance...
✓ Unique permissions set (inheritance broken)
...
[Step 4/4] Applying cascading permissions...
Security Model:
- Each folder has unique permissions (inheritance broken)
- Only managers in the chain can access folders
- Site admins/owners retain access for administration
Setting permissions for: Rudolph, Bill
Folder: General/Bonus 2025 NEW/Rudolph, Bill
Granting edit access to 150 folders
Granted edit to: General/Bonus 2025 NEW/Rudolph, Bill
Granted edit to: General/Bonus 2025 NEW/Schaller, Jeff
...
Step 6: Review Results
========================================
Deployment Complete!
========================================
Location: https://rlgbuilds.sharepoint.com/sites/RLGManagers
Path: Documents → General/Bonus 2025 NEW
Permission Grants: 4,523
Successful: 4,498
Failed: 25
✓ All permissions set successfully!
Managers can now access their compensation folders.
Security:
• Each folder has unique permissions (inheritance broken)
• Only managers in the chain can access folders
• Managers have EDIT permissions to modify files
Log file: CompensationFolderStructure_Log_20251120_143022.csv
📊 What to Expect
Timing
- Small department (10-20 managers): 2-3 minutes
- Full company (150+ managers): 10-15 minutes
- Permission grants: ~2 seconds per folder per manager
Success Metrics
| Metric | Expected | Action if Different |
|---|---|---|
| Folder creation | 100% success | Check SharePoint permissions |
| Permission grants | 95%+ success | Review log for failed users |
| Failed permissions | <5% (disabled accounts) | Expected - see Troubleshooting |
Folder Name Handling
Special Character Sanitization: The script automatically removes characters that are invalid in SharePoint folder names:
- Periods → Removed (e.g., "King, A.J." becomes "King, AJ")
- Special chars → Removed:
\ / : * ? " < > | # { } % ~ &
When a name is sanitized, you'll see a console message:
Sanitized folder name: 'King, A.J.' -> 'King, AJ'
Generated Files
The script creates a date and timestamped CSV log file:
CompensationFolderStructure_Log_20251120_143022.csv
Log Format:
Manager,ManagerEmail,FolderPath,Permission,Status
"Rudolph, Bill",Bill.Rudolph@rlgbuilds.com,General/Bonus 2025 NEW/Rudolph, Bill,Edit,Success
"Schaller, Jeff",Jeff.Schaller@rlgbuilds.com,General/Bonus 2025 NEW/Schaller, Jeff,Edit,Success
"Manager Name",manager@rlgbuilds.com,General/Bonus 2025 NEW/Manager Name,Edit,Failed: noResolvedUsers
Note: The Manager column shows the original AD name, while FolderPath shows the sanitized folder name created in SharePoint.
🔧 Troubleshooting
Issue: "Unable to find a default server with Active Directory Web Services running"
Cause: Not connected to VPN
Solution:
- Connect to RLG VPN
- Re-run script
Issue: "Access is denied" when creating folders
Cause: Insufficient SharePoint permissions
Solution:
- Verify you're a Site Owner on
https://rlgbuilds.sharepoint.com/sites/RLGManagers - Check with SharePoint admins to grant Site Owner role
- Try: Site Settings → Site Permissions → Check Members group
Issue: Many "noResolvedUsers" permission failures
Cause: Users exist in AD but not in Microsoft 365 (disabled/unlicensed accounts)
What happens:
ERROR: Failed to set permission on [folder] -
{
"error": {
"code": "noResolvedUsers",
"message": "Exception of type 'Microsoft.Vroom.Exceptions.NoResolvedUsersVroomException' was thrown."
}
}
Solution:
- Check the log file - it lists all failed users
- Review with HR - these are typically:
- Terminated employees still in AD
- Disabled accounts with direct reports
- Accounts without M365 licenses
- Options:
- Have HR reassign reports to active managers → re-run script
- Manually grant permissions in SharePoint for specific cases
- Accept failures for accounts that don't need SharePoint access
The script automatically retries with UPN if email fails, so most legitimate users will succeed.
Issue: "Retrying with UPN" messages for many users
Cause: AD EmailAddress doesn't match M365 identity (common in hybrid environments)
Example:
Retrying with UPN: Jim.Philo@rlgbuilds.com
✓ Granted edit to: [folder] (via UPN)
Solution: This is normal and expected. The script automatically handles this. No action needed.
Issue: Script creates "Bill Rudolph/Bill Rudolph/Bill Rudolph/..." infinitely
Cause: CEO's Manager field in AD points to himself (circular reference)
Solution: This has been fixed in the script (filters out self-references). If you still see this, the fix isn't applied - contact IT.
Issue: "General" folder not found
Cause: Root path doesn't exist in SharePoint
Solution:
- Verify "General" folder exists in Documents library
- If missing, either:
- Create "General" folder manually in SharePoint
- OR edit production script to use different path (edit line 98)
Issue: Want to see detailed troubleshooting output
Solution: Run with -Verbose flag:
.\Run-CompensationFolders-Production.ps1 -Verbose
This shows:
- HTTP requests/responses
- Graph API calls
- Detailed error messages
- CSOM operations
✔️ Post-Run Verification
1. Check SharePoint Structure
Navigate to: https://rlgbuilds.sharepoint.com/sites/RLGManagers/Shared%20Documents/Forms/AllItems.aspx?id=%2Fsites%2FRLGManagers%2FShared%20Documents%2FGeneral%2FBonus%202025%20NEW
Verify:
- All expected manager folders exist
- Folders show lock icon (unique permissions)
- Folders are all at the same level (flat structure)
2. Spot-Check Permissions
Pick 2-3 random managers and verify:
Example: Check "Manager Name"
- Right-click folder → Manage access
- Confirm:
- Manager has Edit access
- Manager's boss has Edit access
- Manager's boss's boss has Edit access
- Other unrelated managers do not appear
3. Review Log File
Open the CSV log in Excel:
# Find latest log
Get-ChildItem CompensationFolderStructure_Log_*.csv | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Review:
- Success rate is >95%
- Failed users are expected (disabled accounts)
- No unexpected errors
4. Verify HR Director Access (CRITICAL)
Test HR Director can access ALL folders:
- Have the HR Director log in to SharePoint
- Navigate to: Documents → General → Bonus 2025 NEW
- Verify they can:
- See ALL folders (every manager's folder)
- Open any folder (click into any folder)
- Edit/upload files in any folder
- Access is not blocked or restricted
If HR Director CANNOT access folders:
- They are NOT a Site Collection Administrator
- Go back to Prerequisites > Site Collection Administrator Setup
- Add them, then verify again
5. Test Access as Manager
Ask a manager to test:
- Navigate to SharePoint site
- Go to: Documents → General → Bonus 2025 NEW
- Verify they can:
- See their own folder
- See their subordinates' folders
- Edit/upload files in those folders
- Cannot see unrelated managers' folders
6. Rename Folder (After Verification)
Once everything is confirmed working:
- In SharePoint, navigate to "General"
- Right-click "Bonus 2025 NEW"
- Select Rename
- Change to:
Bonus 2025 - All permissions are preserved during rename
🔀 Advanced Usage
Run for a Specific Department Only
Instead of full company, create folders for just one department:
.\Run-CompensationFolders-Production.ps1 -TopManager "dept.head@rlgbuilds.com"
Example - IT Department only:
.\Run-CompensationFolders-Production.ps1 -TopManager "Doug.Mallette@rlgbuilds.com"
Use Hierarchical Structure (Not Recommended)
⚠️ WARNING: Hierarchical structure has a critical limitation - managers cannot navigate to their folders if they don't have access to parent folders. This is a fundamental SharePoint security restriction.
If you need hierarchical structure for a specific reason:
.\Run-CompensationFolders-Production.ps1 -Structure "Hierarchical"
Flat Structure (Default - Recommended):
Bonus 2025 NEW/
├── Rudolph, Bill
├── Schaller, Jeff
├── Manager A
├── Manager B
└── Manager C
- ✅ Managers can access their folders directly
- ✅ No parent folder navigation required
- ✅ Permissions work as expected
Hierarchical Structure (Not Recommended):
Bonus 2025 NEW/
└── Rudolph, Bill/
└── Schaller, Jeff/
├── Manager A/
├── Manager B/
└── Manager C/
- ❌ Manager A cannot access their folder without also having access to Rudolph and Schaller's folders
- ❌ SharePoint requires Read permission on ALL parent folders to traverse the path
- ❌ Defeats the purpose of unique permissions per folder
Recommendation: Always use Flat structure unless you have a specific requirement and understand the navigation limitations.
Different Year
For 2026 compensation:
.\Run-CompensationFolders-Production.ps1 -Year 2026
This creates: General/Bonus 2026 NEW
Combine Multiple Options
# IT Department, Flat structure, 2026, with verbose output
.\Run-CompensationFolders-Production.ps1 `
-TopManager "Doug.Mallette@rlgbuilds.com" `
-Structure "Flat" `
-Year 2026 `
-Verbose
Test Before Production
Always test first with a small department:
# Test with IT department (smaller hierarchy)
.\Test-CompensationScript.ps1 -TopManager "Doug.Mallette@rlgbuilds.com"
Test site: Creates folders in https://rlgbuilds.sharepoint.com/sites/JRTestTeam using flat structure (default)
After verifying test works, run production script.
🔍 Technical Details
How It Works
Phase 1: Build Organizational Hierarchy
- Connects to Active Directory via PowerShell
- Queries for top-level manager (Bill Rudolph)
- Recursively finds all direct reports
- Builds tree structure with manager/subordinate relationships
- Filters out:
- Self-references (CEO reporting to self)
- Circular manager relationships
- Duplicate entries
Phase 2: Connect to SharePoint
- Uses Azure AD enterprise app for authentication
- Opens device code authentication flow
- Acquires Microsoft Graph API token with
Sites.FullControl.Allpermission - Establishes PnP PowerShell connection
Phase 3: Create Folder Structure
- Creates root folder:
General/Bonus 2025 NEW - For each manager with direct reports:
- Sanitizes display name (removes periods and invalid SharePoint characters)
- Creates folder named "LastName, FirstName"
- If hierarchical: nests under their manager's folder
- If flat: creates at root level
- Immediately breaks permission inheritance on each folder:
- Removes all inherited permissions
- Starts with clean slate (only admins have access)
Phase 4: Set Cascading Permissions
- For each manager in hierarchy:
- Identifies all folders they should access:
- Their own folder
- All direct reports' folders
- All subordinates down the chain
- Uses Microsoft Graph API
/inviteendpoint to grant Edit permission: - Gets folder item ID via Graph API
- Sends invite request with
roles: ["write"] - Sets
requireSignIn: true(internal users only) - Sets
sendInvitation: false(no email notification) - If email fails with "noResolvedUsers":
- Automatically retries with UserPrincipalName
- Handles AD/M365 identity mismatches
- Logs success/failure for each permission grant
Phase 5: Generate Report
- Exports CSV log with all operations
- Shows summary statistics
- Identifies any failures for manual review
Architecture
Main Script: New-CompensationFolderStructure.ps1
- Core automation logic
- 800+ lines of PowerShell
- Key Functions:
Build-OrgHierarchy- Recursive AD tree builderGet-SanitizedFolderName- Remove invalid SharePoint charactersNew-SharePointFolderStructure- Folder creation with sanitizationSet-UniquePermissions- Break inheritance via CSOMInitialize-GraphAPI- Get Graph tokens and site/drive IDsGet-GraphFolderItem- Find folder item ID via Graph APISet-CascadingPermissions- Recursive permission grants via Graph API
Wrapper Scripts:
Run-CompensationFolders-Production.ps1- Production defaultsTest-CompensationScript.ps1- Test site wrapper
Helper Scripts:
Connect-SharePoint.ps1- Multi-method authenticationFind-ITManager.ps1- Utility to find test managers
Authentication Flow
User runs script
↓
PnP.PowerShell requests Graph token
↓
Browser opens to microsoft.com/devicelogin
↓
User enters device code
↓
User signs in with M365 account
↓
Azure AD issues token with:
- Audience: https://graph.microsoft.com
- Permission: Sites.FullControl.All
↓
Script uses token for:
- PnP PowerShell operations (folder creation, CSOM context)
- Microsoft Graph API (permission granting)
- CSOM direct manipulation (inheritance breaking only)
APIs and Methods Used
PnP PowerShell:
Add-PnPFolder- Create folders in document libraryGet-PnPFolder- Retrieve folder metadata and list item IDsGet-PnPContext- Get CSOM context for inheritance breaking
Microsoft Graph API:
GET /sites/{hostname}:{path}- Get SharePoint site IDGET /sites/{siteId}/drives- Get document library drive IDGET /sites/{siteId}/drives/{driveId}/root:/{path}- Get folder item IDPOST /sites/{siteId}/drives/{driveId}/items/{itemId}/invite- Grant permissions
CSOM (SharePoint Client Side Object Model):
$listItem.BreakRoleInheritance($false, $true)- Break permission inheritance
Permission Model
Folder: "Manager A"
│
├── Unique Permissions (inheritance broken)
│ ├── Site Admins: Full Control (automatic)
│ ├── Manager A: Edit (granted by script)
│ ├── Manager A's Boss: Edit (granted by script)
│ └── CEO: Edit (granted by script)
│
└── Hidden from:
├── Other managers
├── General site members
└── Manager A's peers
Why Graph API Instead of PnP Cmdlets?
Problem: PnP cmdlets like Set-PnPListItemPermission require SharePoint API tokens, but DeviceLogin authentication provides Graph API tokens.
Solution: Use Graph API's /invite endpoint directly, which:
- Accepts Graph tokens (what we have)
- Grants permissions to SharePoint items
- Handles email resolution automatically
- Supports retry logic for email/UPN mismatches
File Structure
OneDrive-SharePoint/
├── New-CompensationFolderStructure.ps1 # Main script (800+ lines)
├── Run-CompensationFolders-Production.ps1 # Production wrapper
├── Test-CompensationScript.ps1 # Test wrapper
├── Connect-SharePoint.ps1 # Authentication helper
├── Find-ITManager.ps1 # Test utility
├── SharePoint-Config.json # Azure AD app config
├── README-Compensation-Folders-CONSOLIDATED.md # This file (OFFICIAL)
└── NotNeeded/ # Archived diagnostic scripts
├── Test-*.ps1 # 30+ test scripts
└── Check-*.ps1 # Diagnostic utilities
Logs
CSV Format:
Manager,ManagerEmail,FolderPath,Permission,Status
"Rudolph, Bill","Bill.Rudolph@rlgbuilds.com","General/Bonus 2025 NEW/Rudolph, Bill","Edit","Success"
Status Values:
Success- Permission granted with EmailAddressSuccess (via UPN)- Permission granted after UPN retryFailed: noResolvedUsers- User doesn't exist in M365Failed: serviceNotAvailable- Temporary Microsoft API issueFailed: [other error]- Other Graph API errors
📞 Support
Common Questions
Q: Can I run this script multiple times? A: Yes, but it will create duplicate folders. For updates, manually adjust permissions or delete/recreate the folder structure.
Q: What if someone's manager changes mid-year? A: Re-run the script to create a new folder structure reflecting the current org chart, or manually adjust permissions in SharePoint.
Q: Can external users see these folders? A: No. Permissions are limited to internal managers with M365 accounts. Inheritance is broken so only explicitly granted users have access.
Q: How do I delete the test folders? A: In SharePoint, navigate to the test folder → Delete. All permissions are deleted with it.
Q: What if Bill Rudolph retires and we have a new CEO? A: Update the production script (line 34) to change the default TopManager, or specify at runtime:
.\Run-CompensationFolders-Production.ps1 -TopManager "new.ceo@rlgbuilds.com"
Q: Why can't the HR Director access folders even though they're a Site Owner? A: Site Owners do not have access after the script runs because permission inheritance is broken. Only Site Collection Administrators have automatic access to all folders. To fix:
- Follow Prerequisites > Site Collection Administrator Setup
- Add HR Director as Site Collection Administrator
- Verify with:
Get-PnPSiteCollectionAdmin
Q: Who will be able to access the compensation folders? A: Only these people:
- ✅ Site Collection Administrators (HR Director, IT admins) - Full access to everything
- ✅ Managers in reporting chain - Edit access to their own folder and all subordinates
- ✅ Bill Rudolph (CEO) - Edit access to all folders (top of hierarchy)
- ❌ Site Owners (unless also Site Collection Admins) - No access
- ❌ Site Members - No access
- ❌ General users - No access
Q: A new HR Director has started, what do I do? A: Add them as a Site Collection Administrator so they can access all folders:
- Go to:
https://rlgbuilds.sharepoint.com/sites/RLGManagers - Settings gear ⚙️ → Site settings
- Under Users and Permissions → Site Collection Administrators
- Add the new HR Director's email
- (Optional) Remove the old HR Director if they've left
Q: Why is the folder name different from the person's name in Active Directory? A: The script automatically sanitizes folder names to comply with SharePoint restrictions. For example:
- "King, A.J." (AD) → "King, AJ" (SharePoint folder)
- Periods, special characters like
* ? " < >are removed - The original AD name is preserved in the CSV log under the
Managercolumn - This is automatic and ensures all folders can be created successfully
Q: Why do we use flat structure instead of hierarchical? A: SharePoint has a fundamental security restriction - users cannot navigate through folders they don't have Read access to. In a hierarchical structure, even if a manager has Edit permissions on their own folder 3 levels deep, they cannot access it because they don't have Read permissions on the parent folders. Flat structure solves this by putting all folders at the same level, while still maintaining the organizational hierarchy through permissions.
Getting Help
- Check this README - Most issues are documented
- Review the log file - Shows exactly what failed
- Run with
-Verbose- Shows detailed error messages - Contact: Jeff Ricica (script author) - jeff.ricica@rlgbuilds.com
📝 Change Log
Version 2.1 (November 2025)
- ✅ Changed default structure to Flat (was Hierarchical)
- ✅ Updated documentation to clearly explain flat vs hierarchical limitations
- ✅ Consolidated two separate README files into single source of truth
- ✅ Added detailed cascading permission example with fictional org chart
- ✅ Enhanced troubleshooting section
Version 2.0 (November 2025)
- ✅ Automatic permission inheritance breaking for security (CSOM)
- ✅ Email/UPN retry logic for AD/M365 mismatches
- ✅ Self-referencing manager filter (CEO circular reference fix)
- ✅ Hierarchical and flat folder structure support
- ✅ Cleaner output (verbose is optional)
- ✅ Microsoft Graph API permission grants (modern, future-proof)
- ✅ Folder name sanitization (removes periods and special characters)
- ✅ Comprehensive error handling and logging
Version 1.0 (2024)
- Initial version
- Manual permission setup required after folder creation
Last Updated: November 21, 2025 Script Author: Jeff Ricica, IT Department Script Location: C:\Users\[Username]\OneDrive - Rudolph Libbe Group\Scripts\OneDrive-SharePoint README File: README-Compensation-Folders-CONSOLIDATED.md (official version)