A collection of PowerShell scripts for enterprise IT administration, covering Active Directory, Microsoft 365, Exchange Online, Entra ID, and Intune management tasks that i've created over the years.
- Table of Contents
- Features
- Getting Started
- Usage
- Configuration
- Folder Structure
- Modules and Functions
- Testing
- Logging and Troubleshooting
- Accessibility
- Contributing
- Changelog
- License
- Like to say thank you?
- Contact and Support
- ScriptLauncher: Build & Publish
- Active Directory Management: User creation, group management, computer organisation, and bulk operations
- Microsoft 365 Administration: Exchange Online mailbox management, quarantine handling, and transport rules
- Entra ID Integration: External user management, compromised account remediation, and identity operations
- Intune Device Management: Bulk device synchronisation, remediation scripts, and compliance monitoring
- General Utilities: Password generation, module management, and script selection tools
- OneDrive Administration: User content download and management capabilities
- Comprehensive Logging: Standardised logging across all scripts with detailed audit trails
- Error Handling: Robust error handling and retry logic for enterprise environments
- GUI Interfaces: User-friendly forms for complex administrative tasks
- PowerShell 7.0 or later
- Windows operating system
- Appropriate administrative permissions for target systems
- Required PowerShell modules (see individual scripts for specific requirements):
- Active Directory Module
- Exchange Online Management
- Microsoft Graph PowerShell SDK
- Microsoft.Graph.Intune
- MSOnline (where applicable)
-
Clone the repository:
git clone https://github.com/twcau/PowerShellScripting.git
-
Navigate to the project directory:
cd PowerShellScripting -
Review the script you want to use and install any required modules:
# Example: Install Exchange Online Management module Install-Module -Name ExchangeOnlineManagement -Force
-
Configure the scripts according to your environment (see Configuration section)
Each script is designed to be run independently. Navigate to the appropriate folder and execute the script:
# Example: Run user creation script
.\ad\user\creation\User-Creation.ps1
# Example: Run Intune bulk sync
.\intune\devices\Intune-BulkSync.ps1- Active Directory: Scripts for user and computer management in on-premises AD environments
- Exchange 365: Email and mailbox management for cloud and hybrid environments
- Entra ID: Identity and access management for Azure AD/Entra ID
- Intune: Mobile device management and compliance scripts
- General: Utility scripts for common administrative tasks
Many scripts include GUI interfaces for ease of use:
- User creation wizards with form-based input
- Device selection interfaces
- Progress indicators for long-running operations
The technician-friendly, menu-driven CLI for rapid Autopilot preparation and tracking lives here:
- Entry point
- Workflow manifest
- Runtime settings
- Operator guide, operations reference, testing and acceptance and development status
Live can delete managed-device records and change membership and primary users. This is a development implementation, not production-approved. Start with Demo. Live authentication/read inspection, mutations and physical work each require the documented approvals. Keep storage Local; Shared is disabled. The governing checklist is bundled in development. Confirm that this v1.4 copy is the current approved procedure before physical work.
The 14 October 2026 version 0.3.1 Test release adds shared new/existing induction, active-bench or standalone placement, proven dispatch-day statistics with elapsed-time aggregates, aligned bench commands and paged About/help. The current offline implementation also includes canonical step IDs with guarded evidence conversion, stable indexed session filenames, prompt spacing and captured-feedback identity deduplication. Crash-lock inspection/recovery now preserves original evidence; per-run diagnostic logs start automatically. Autopilot discovery uses a serial filter, SDK transport configuration is reused, and accepted Group Tag updates remain pending after unavailable read-back. See the linked development/testing guides for actual fresh gate results, migration status and separate tenant acceptance.
The 15 October operational repairs add DeviceCode as the configured default, session-only -AuthMode overrides and
explicit reconnect after authentication failure. The target is now Intune-Autopilot-Testing, with default-No
prefix-conflict correction. U withdraws eligible physical confirmations without deleting history or reversing Graph
actions; L opens full details behind compact bench summaries. Account selection now uses directory Windows username
first. The incident analysis
distinguishes confirmed code defects from the unresolved native in-page I/O crash and tenant acceptance.
The follow-up makes Show Steps List manifest-driven with separated normal/recovery headings, blank step separators and height-aware paging. Existing serials offer Cancel-default Resume/Restore/Restart, retaining attempts and prior build snapshots; restart is a new cycle, not cloud rollback. The operations reference now includes a practical native crash diagnosis procedure and local-data integrity guidance. Editable local statistics are not independently authenticated compliance evidence.
Offline maintenance now has a repeatable validation runner and a separate two-host Windows CI workflow. The runner requires approved pinned tools, rejects incomplete/skipped/ failed discovery and retains source provenance/reports outside the repository. Operational resume is operator-confirmed; workspace migration remains guarded and tenant/physical acceptance stays paused. Recorded security findings still require owner action; offline passes are not a security clearance or deployment approval.
How to run:
- Open PowerShell 7 in the repository root.
- Rehearse with
./intune/devices/autopilot-express/autopilot-express.ps1 -Mode Demo. - Only after separate approval, use
./intune/devices/autopilot-express/autopilot-express.ps1 -Mode Live. - Select your current site when prompted (default is shown). The site code is used to enforce the Group Tag format.
- Use the on-screen menu to perform common tasks.
Current workflow coverage:
- Capture serial/CI, site and device type; enforce the Group Tag, for example
MI-Desktop. - Display A-O for normal work and P-Q for conditional recovery; saved step IDs/history remain unchanged.
- Resolve identity, prepare Intune, guide physical milestones, assign a confirmed regular technician and final owner.
- Request sync and record application observations; sync is not the named portal application-remediation procedure.
- Use one executable workflow from bench V or main option 3; direct bench P:/CI:/S: selectors open without executing work.
- Use T preparation, X recovery, guarded normal dispatch and reasoned DO administrative closure without fabricated verification.
- Inspect outstanding work, maintain records, view statistics, change site and review enhancement proposals.
- Manage a persistent positions grid with five compact contextual event rows, newest first, and separate full details.
Mode behaviour:
Livedefaults to device-code Microsoft Graph sign-in; Browser remains an explicit preference/session override. Runtime JSON is validated before continuing.Demomode simulates authentication and workflow actions without browser sign-in or tenant requests, while persisting separate progress, recent-user choices and resume state. Outcomes are Simulated, not Live verification.- Live and demo sessions are isolated from each other and prompt to resume or archive-and-start-clean when prior state exists.
Build bench quick reference:
- Displays a grid of positions sized to your window, with centred position numbers and truncated values for readability.
I= Induct new deviceS= Start next step for a deviceT= Prepare one device with per-action save/stop gatesV= Open the shared executable device workflowD= Dispatch after readiness and default-No confirmation; tracked workflow usesDISPATCHDO= Administrative completion with written reason and default-No approval; unresolved evidence remainsX= Start/resume guided recoveryR= Remove from positionM= Move device between positionsW= Read the paged workflow guide without executing actions0/E= Return to main; Enter refreshes, not exits
C remains an undisplayed compatibility command. Plain D in a device workflow selects its step, not dispatch. See the operator guide for display-to-saved ID mapping and unlabelled saved-ID diagnostic messages.
Data and persistence:
- Session JSON is written to
data/under the resolved definition/project root when writable (beside the script/JSON definitions in this layout, not necessarily repository-root data). - If the repository path is read-only or behaves like a synced/reparse-point path that rejects new files, the script automatically falls back to
%LOCALAPPDATA%\PowerShellScriptingNew\AutopilotExpress\data. - Separate per-user files are maintained for live and demo device records, recent users, and build-bench state.
- Startup Resume defaults to Y. N immediately archives the current user's current-mode device/bench pair, without another No/CLEAR prompt. Main option 10 instead requires selection, default-No approval and CLEAR; cancellation preserves active work. Neither path changes tenant state or deletes audit, receipts or import journals.
- Live mode also maintains
autopilot-master-audit.jsonfor manager review of technician actions and resulting device/user outcomes. - Group Tag is enforced as
SITECODE-DeviceType(no override) for consistency and policy compliance. - Required Graph scopes, modules, and tenant-specific values are externalised in the runtime JSON rather than hard-coded in the script body.
Workflow completion, dispatch and physical certification are distinct. Satisfying required steps can automatically mark the record completed before dispatch; it leaves active pickers but its bench slot remains until dispatch/removal. The local audit is not cross-machine search, and checkpointed multi-file saves are not guaranteed atomic or power-loss durable. Tenant/terminal/physical acceptance remains outstanding; offline tests do not authorise Live use.
Some scripts may require environment-specific configuration. Review each script's header for specific requirements.
- Ensure you have appropriate administrative credentials
- Some scripts require multi-factor authentication (MFA)
- Consider using application passwords where applicable
Scripts include configurable parameters at the top of each file. Common customisations include:
- Domain names and organisational units
- Email domains and Exchange settings
- Logging paths and retention policies
- Timeout values and retry attempts
PowerShellScripting/
├── ad/ # Active Directory scripts
│ ├── computer/
│ │ └── FindMachineOU.ps1 # Locate computer objects in AD
│ └── user/
│ ├── creation/ # User account creation scripts
│ │ ├── AD-CopyGroups.ps1 # Copy group memberships
│ │ ├── User-Creation-Bulk.ps1 # Bulk user creation
│ │ ├── User-Creation.ps1 # Individual user creation with GUI
│ │ └── User-Departure.ps1 # User departure processing
│ └── reconcillation/ # User account reconciliation
│ ├── AD-Bulk-DepartedEmployeeReconcillation.ps1
│ ├── Employee-Departure-Reconciliation.ps1
│ └── Employee-Listing.ps1
├── e365/ # Exchange 365 scripts
│ ├── E365-Mailbox-ConvertToShared.ps1 # Convert mailboxes to shared
│ ├── E365-Quarantine-ExportRecord.ps1 # Export quarantine records
│ ├── Exchange-QuarantineTABL-DataDownload.ps1
│ ├── quarantine-to-block-v1.ps1 # Legacy quarantine triage and TABL workflow
│ ├── quarantine-to-block.ps1 # Current quarantine triage, TABL, DNSBL, and deletion workflow
│ └── NewTransportRuleExecName.ps1 # Transport rule management
├── entra/ # Entra ID (Azure AD) scripts
│ ├── AutomateCompromisedAccountRemediation.ps1
│ ├── Entra-UserExternal-Create.ps1 # External user creation
│ └── User-Management-External.ps1 # External user management
├── general/ # General utility scripts
│ ├── ScriptSelector.ps1 # Interactive script launcher
│ ├── module-management/ # PowerShell module utilities
│ │ ├── Module-PowerShell7-Require.ps1
│ │ └── Update-Module.ps1
│ └── password-generation/ # Password generation tools
│ ├── Password-Generator-Silent.ps1
│ └── Password-Generator.ps1
├── intune/ # Microsoft Intune scripts
│ ├── devices/
│ │ └── Intune-BulkSync.ps1 # Bulk device synchronisation
│ └── remediation/ # Intune remediation scripts
│ ├── M365-VersionDetect.ps1 # M365 Apps version detection
│ ├── M365-VersionRemediate.ps1 # M365 Apps version remediation
│ ├── TeamsOld-Detect.ps1 # Legacy Teams detection
│ ├── TeamsOld-Remediate.ps1 # Legacy Teams remediation
│ ├── WinUpdate-23H2to24H2Force-Detect.ps1
│ ├── WinUpdate-23H2to24H2Force-Remediate.ps1
│ ├── WinUpdate-Detect.ps1 # Windows Update detection
│ ├── WinUpdate-Pause-Detect.ps1 # Windows Update pause detection
│ ├── WinUpdate-Pause-Remediate.ps1
│ └── WinUpdate-Remediate.ps1 # Windows Update remediation
├── m365/ # Microsoft 365 scripts
├── onedrive/ # OneDrive management scripts
│ └── M365-OneDrive-DownloadUserContents.ps1
└── testing/ # Development and testing scripts
The scripts in this collection provide:
- User Management: Creation, modification, and departure processing
- Group Management: Membership copying and bulk operations
- Device Management: Synchronisation, detection, and remediation
- Security Operations: Compromised account handling and compliance monitoring
- Utility Functions: Password generation, module management, and system utilities
- User-Creation.ps1: Comprehensive user creation with GUI interface
- Intune-BulkSync.ps1: Mass device synchronisation for Intune environments
- Autopilot Express (CLI):
intune/devices/autopilot-express/autopilot-express.ps1— Menu-driven technician workflow with build bench and per-user persistence - quarantine-to-block.ps1: Interactive Exchange Online quarantine triage with guided release, TABL blocking, optional DNSBL submission, and optional deletion. DNSBL reporting is explicit opt-in.
- AutomateCompromisedAccountRemediation.ps1: Automated security response
- ScriptSelector.ps1: Interactive menu system for script selection
Testing scripts are located in the testing/ folder and include:
- Proof-of-concept implementations
- Version comparisons
- Experimental features
Before using scripts in production:
- Review the script header for version information and changelog
- Test in a non-production environment
- Verify all required modules are installed
- Check logging output for any warnings or errors
- For
e365/quarantine-to-block.ps1, verify release, TABL selection, and deletion behaviour in a test tenant first. DNSBL reporting now runs only when-ReportToDnsblis passed, or when defaults mode is explicitly requested and the saved DNSBL preference is enabled.
All scripts follow consistent logging practices:
- Log files stored in
$env:TEMPwith timestamps - Comprehensive error logging with context
- Success and failure reporting
- Progress indicators for long-running operations
- Module Import Errors: Ensure required PowerShell modules are installed
- Authentication Failures: Verify credentials and MFA settings
- Permission Errors: Check administrative rights for target systems
- Network Connectivity: Ensure access to required cloud services
- Desktop Shortcut Startup: Launch
e365/quarantine-to-block.ps1shortcuts with PowerShell 7, for examplepwsh.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "C:\Path\To\PowerShellScriptingNew\e365\quarantine-to-block.ps1". Starting it withpowershell.exeopens Windows PowerShell 5.1 and shows the Windows PowerShell banner before the script can control output. - Quarantine-to-Block Authentication Startup: The script checks that
login.microsoftonline.comresolves before starting Exchange Online authentication. If DNS, VPN, proxy, or network connectivity is unavailable, the script skips that auth attempt with a concise warning instead of triggering repeated MSAL token stack traces. - Quarantine-to-Block DNSBL Skips: DNSBL reporting is explicit opt-in. The script skips DNSBL submission unless
-ReportToDnsblis supplied, or defaults mode is explicitly requested with DNSBL enabled in the saved preferences.
- Check script headers for specific documentation links
- Review Microsoft documentation for API changes
- Consult PowerShell Gallery for module updates
This project is committed to accessibility and inclusive design:
- Scripts include progress indicators and clear status messages
- Documentation uses descriptive text for all functionality
- Error messages provide actionable guidance
- GUI interfaces follow accessibility best practices
- All documentation supports screen readers
Contributions to improve and expand this script collection are welcome. Please read the contribution guidelines:
- Code Standards: Follow PowerShell best practices and existing code style
- Documentation: Include comprehensive headers and inline comments
- Testing: Validate scripts in appropriate test environments
- Security: Ensure no hardcoded credentials or sensitive information
- Use Australian English (EN-AU) for documentation and comments
- Include proper error handling and logging
- Follow the established folder structure
- Update this README when adding new functionality
- 28/04/2026: Quarantine-to-Block now treats DNSBL reporting as explicit opt-in, keeps DNSBL scope roots separate during evaluation, expands function-level comment-based help across the script, and validates the workflow with dedicated regression tests for PSL loading, filter handling, export fallback, DNSBL gating, and block-expiry validation.
- 30/01/2026: Quarantine-to-Block workflow hardened: cancel on release grid now continues with zero releases; added
-IncludeProviderRootsto opt-in common provider roots for candidate selection; zero-candidate diagnostics preview added; DNSBL and deletion steps gated strictly on domain selections; dry-run guidance documented. - 6/06/2025: Enhanced user creation script with group copying improvements
- 27/03/2025: Added Clear Base User and Clear All User functionality
- 21/05/2025: Implemented base group validation and management
- 4/03/2025: Updated department listings for dynamic group memberships
See individual script headers for detailed version history and changelog information.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Copyright (c) 2025, Michael Harris, All rights reserved.
If these scripts have helped you in your IT administration tasks, consider:
- ⭐ Starring this repository
- 🐛 Reporting issues or suggesting improvements
- 📖 Contributing to the documentation
- ☕ Buy me a coffee to support continued development
- Michael Harris - @twcau
- Issues: Report bugs or request features via GitHub Issues
- Discussions: Join the conversation in GitHub Discussions
- Documentation: Review script headers and Microsoft documentation links
- Provide clear descriptions of issues with relevant log files
- Include PowerShell version and module information
- Specify the target environment (on-premises, cloud, hybrid)
- Follow the issue templates when reporting problems
This project follows Microsoft PowerShell best practices and maintains compatibility with enterprise IT environments.
The WPF-based ScriptLauncher app lives in ScriptLauncher/. It lets you organise and run PowerShell scripts by category, with per-user JSON config and optional elevation.
- Windows 10/11
- .NET SDK 8 (LTS) or 10 (latest). Verify installation:
dotnet --infoIf SDK is missing, install via Winget:
winget install Microsoft.DotNet.SDK.8
# or
winget install Microsoft.DotNet.SDK.10This repo includes global.json to prefer SDK 8 and roll forward to newer SDKs if needed.
dotnet build ScriptLauncher\ScriptLauncher.csproj -c Debug
dotnet run --project ScriptLauncher\ScriptLauncher.csprojFirst run will prompt to browse an existing config or create %AppData%\ScriptLauncher\scripts.json.
This repository includes automated CI for the WPF ScriptLauncher app. On pushes and pull requests to the default branches, GitHub Actions will:
- Build with warnings treated as errors to enforce quality (
-warnaserror). - Run an analyser sweep via
dotnet format analyzersat diagnostic verbosity. - Capture a verbose build (
-v diag) and upload both logs as workflow artefacts.
Workflow: .github/workflows/dotnet-ci.yml
Badge: See the status badge at the top of this README.
PR authors can download the CI logs for troubleshooting:
- Open your pull request on GitHub.
- Select the "Checks" tab, then choose ".NET Build & Analyzers (ScriptLauncher)".
- Open the latest workflow run for your commit.
- In the run summary, find the Artefacts section and download
scriptlauncher-logs. - The zip contains
analyzers-diagnostics.logandbuild-diagnostics.log.
dotnet publish ScriptLauncher\ScriptLauncher.csproj -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true
Compress-Archive -Path ScriptLauncher\bin\Release\net8.0-windows\win-x64\publish\* -DestinationPath ScriptLauncher-win-x64.zip -ForceDistribute the ScriptLauncher-win-x64.zip; users can run ScriptLauncher.exe. On first launch, the app will discover or create the per-user config.
- Commands-only menus: Menu items must use
Commandonly (no duplicateClick + Command). Dialogs open viaCommandBindingsinMainWindow.xaml.cs. - Single-press Esc close: Every modal window implements a native-handle ESC hook (
HwndSource.AddHookwithWM_KEYDOWN/VK_ESCAPE) to close immediately, regardless of focused control or dropdowns. - Owner assignment: All modal dialogs are opened with
Owner = MainWindowto ensure consistent modality and focus behaviour. - No global Esc interceptors: Avoid thread-level ESC interceptors; handle Esc per dialog to prevent unintended interactions.
- Accessibility: Provide access keys in dialog buttons and consistent keyboard navigation (e.g., Tab behaviour in grids).
These standards are enforced to maintain consistent, accessible UX and to prevent regressions like double-Esc or dialog respawn.
in MainWindow.xaml.cs.
- Single-press Esc close: Every modal window implements a native-handle ESC hook (
HwndSource.AddHookwithWM_KEYDOWN/VK_ESCAPE) to close immediately, regardless of focused control or dropdowns. - Owner assignment: All modal dialogs are opened with
Owner = MainWindowto ensure consistent modality and focus behaviour. - No global Esc interceptors: Avoid thread-level ESC interceptors; handle Esc per dialog to prevent unintended interactions.
- Accessibility: Provide access keys in dialog buttons and consistent keyboard navigation (e.g., Tab behaviour in grids).
These standards are enforced to maintain consistent, accessible UX and to prevent regressions like double-Esc or dialog respawn.