Automate your Microsoft Intune tenant configuration with best-practice defaults
Installation • Quick Start • Configuration • Safety Features • Troubleshooting
The Intune Hydration Kit is a PowerShell module that bootstraps Microsoft Intune tenants with boilerplate configurations. It automatically downloads the latest OpenIntuneBaseline policies and imports them alongside compliance policies, dynamic groups, and more—turning hours of manual configuration into a single command.
| Category | Count | Description |
|---|---|---|
| Dynamic Groups | 43 | Device and user targeting groups (OS, manufacturer, Autopilot, ownership, licensing, VMs) |
| Static Groups | 4 | Update ring groups (Pilot, UAT, Broad) and assignment groups |
| Device Filters | 24 | Platform, manufacturer, and VM-based filters (Windows, macOS, iOS, Android) |
| Security Baselines | 70+ | OpenIntuneBaseline policies (Windows, macOS) |
| Compliance Policies | 10 | Multi-platform compliance (Windows, macOS, iOS, Android, Linux) |
| App Protection | 8 | MAM policies following Microsoft's App Protection Framework (Level 1-3 for iOS and Android) |
| Mobile Apps | 17 | Microsoft Store apps (Company Portal, Teams, Slack, Spotify, etc.) |
| Enrollment Profiles | 3 | Autopilot deployment profiles + Enrollment Status Page |
| Conditional Access | 21 | Starter pack policy templates (created disabled) |
⚠️ READ BEFORE USE
- Creates objects in your Intune tenant (policies, groups, filters)
- Can delete objects when run with delete mode enabled
- Modifies Conditional Access policies (though always created disabled)
- Test in a non-production tenant first - Use a dev/test tenant before running against production
- Always preview changes first - Use
-WhatIfin parameter or settings mode - Review the configuration - Understand what will be imported before running
- Have a rollback plan - Know how to manually remove configurations if needed
- Backup existing configurations - Export current settings before running
When using delete mode (-Delete parameter or "delete": true in settings), the kit will only delete objects that it created:
- Objects must have
"Imported by Intune-Hydration-Kit"in their description - Conditional Access policies must also be in
disabledstate to be deleted - Manually created objects with the same names will NOT be deleted
- Idempotent - Safe to run multiple times; skips existing configurations
- Dry-Run Mode - Preview changes with PowerShell
-WhatIfbefore applying - Safe Deletion - Only removes objects created by this kit
- Multi-Platform - Supports Windows, macOS, iOS, Android, and Linux
- OpenIntuneBaseline Integration - Automatically downloads latest community baselines
- Detailed Logging - Full audit trail of all operations
- Summary Reports - Markdown and JSON reports of all changes
- PowerShell 7.0 or later
Install-Module Microsoft.Graph.Authentication -Scope CurrentUserNote: This module uses
Invoke-MgGraphRequestfor all Graph API calls, so only the Authentication module is required.
The authenticated user/app needs these Microsoft Graph permissions:
DeviceManagementConfiguration.ReadWrite.AllDeviceManagementServiceConfig.ReadWrite.AllDeviceManagementManagedDevices.ReadWrite.AllDeviceManagementScripts.ReadWrite.AllDeviceManagementApps.ReadWrite.AllGroup.ReadWrite.AllPolicy.Read.AllPolicy.ReadWrite.ConditionalAccessApplication.Read.AllDirectory.ReadWrite.AllLicenseAssignment.Read.AllOrganization.Read.All
Install directly from the PowerShell Gallery:
Install-Module -Name IntuneHydrationKit -Scope CurrentUserTo update to the latest version:
Update-Module -Name IntuneHydrationKitFor development or to use the latest unreleased changes:
git clone https://github.com/jorgeasaurus/Intune-Hydration-Kit.git
cd Intune-Hydration-Kit
Import-Module ./IntuneHydrationKit.psd1The kit supports two invocation methods: parameters (recommended) or settings file (for complex configurations).
After installing from PSGallery, use the Invoke-IntuneHydration function directly:
# Preview all targets with interactive auth
Invoke-IntuneHydration -TenantId "your-tenant-id" `
-Interactive `
-Create `
-All `
-WhatIf
# Run specific targets only
Invoke-IntuneHydration -TenantId "your-tenant-id" `
-Interactive `
-Create `
-ComplianceTemplates `
-DynamicGroups `
-DeviceFilters
# Use service principal authentication
$secret = ConvertTo-SecureString "your-secret" -AsPlainText -Force
Invoke-IntuneHydration -TenantId "your-tenant-id" `
-ClientId "app-id" `
-ClientSecret $secret `
-Create `
-All
# Use a settings file for complex configurations
Invoke-IntuneHydration -SettingsPath ./settings.json
# Preview with settings file
Invoke-IntuneHydration -SettingsPath ./settings.json -WhatIfIf you cloned the repository, use the wrapper script:
# Preview all targets with interactive auth
./Invoke-IntuneHydration.ps1 -TenantId "your-tenant-id" `
-Interactive `
-Create `
-All `
-WhatIf
# Run specific targets only
./Invoke-IntuneHydration.ps1 -TenantId "your-tenant-id" `
-Interactive `
-Create `
-ComplianceTemplates `
-DynamicGroups `
-DeviceFilters
# Use service principal authentication
$secret = ConvertTo-SecureString "your-secret" -AsPlainText -Force
./Invoke-IntuneHydration.ps1 -TenantId "your-tenant-id" `
-ClientId "app-id" `
-ClientSecret $secret `
-Create `
-AllFor complex or repeated configurations, use a settings file:
# If using cloned repo
Copy-Item settings.example.json settings.json
# If using PSGallery module, create your own settings.jsonEdit settings.json with your tenant details:
{
"tenant": {
"tenantId": "your-tenant-id-here",
"tenantName": "yourtenant.onmicrosoft.com"
},
"authentication": {
"mode": "interactive"
},
"options": {
"dryRun": false,
"create": true,
"delete": false,
"force": false
}
}# PSGallery module
Invoke-IntuneHydration -SettingsPath ./settings.json -WhatIf
# Cloned repo
./Invoke-IntuneHydration.ps1 -SettingsPath ./settings.json -WhatIf# PSGallery module
Invoke-IntuneHydration -SettingsPath ./settings.json
# Cloned repo
./Invoke-IntuneHydration.ps1 -SettingsPath ./settings.json"tenant": {
"tenantId": "00000000-0000-0000-0000-000000000000",
"tenantName": "contoso.onmicrosoft.com"
}The kit supports two authentication methods:
| Method | Use Case | Requirements |
|---|---|---|
| Interactive | Manual runs, testing | User with required permissions |
| Client Secret | Automation, CI/CD | App registration with client secret |
Interactive (recommended for testing):
"authentication": {
"mode": "interactive",
"environment": "Global"
}Uses browser-based login. Best for manual runs and initial testing.
Client Secret (for automation):
"authentication": {
"mode": "clientSecret",
"clientId": "00000000-0000-0000-0000-000000000000",
"clientSecret": "your-client-secret-value",
"environment": "Global"
}Uses app registration credentials. Best for unattended/automated runs.
Security Note: Store client secrets securely. Consider using Azure Key Vault or environment variables instead of plaintext in settings files.
Supported Cloud Environments:
| Environment | Description |
|---|---|
Global |
Commercial/Public cloud (default) |
USGov |
US Government (GCC High) |
USGovDoD |
US Government (DoD) |
Germany |
Germany sovereign cloud |
China |
China sovereign cloud (21Vianet) |
| Option | Description |
|---|---|
dryRun |
Preview changes without applying (same as -WhatIf) |
create |
Create new configurations |
delete |
Delete existing kit-created configurations |
force |
Skip confirmation prompt when running delete mode |
Create mode (default):
"options": {
"create": true,
"delete": false
}Delete mode (cleanup):
"options": {
"create": false,
"delete": true,
"force": false
}Enable or disable specific configuration types (used for both create and delete workflows):
"imports": {
"openIntuneBaseline": true,
"complianceTemplates": true,
"appProtection": true,
"notificationTemplates": true,
"enrollmentProfiles": true,
"dynamicGroups": true,
"staticGroups": true,
"deviceFilters": true,
"conditionalAccess": true,
"mobileApps": true
}The kit supports two mutually exclusive invocation modes:
- Settings File Mode: Use
-SettingsPathto load all configuration from a JSON file - Parameter Mode: Use
-TenantIdwith-Interactiveor-ClientId/-ClientSecret
These modes cannot be combined - choose one or the other.
| Parameter | Type | Description |
|---|---|---|
-TenantId |
String | Azure AD tenant ID (GUID). Required for parameter mode. |
-TenantName |
String | Tenant name for display purposes |
| Parameter | Type | Description |
|---|---|---|
-Interactive |
Switch | Use interactive (browser-based) authentication |
-ClientId |
String | Application ID for service principal auth |
-ClientSecret |
SecureString | Client secret for service principal auth |
-Environment |
String | Cloud environment: Global, USGov, USGovDoD, Germany, China (default: Global) |
| Parameter | Type | Description |
|---|---|---|
-Create |
Switch | Enable creation of configurations |
-Delete |
Switch | Enable deletion of kit-created objects |
-Force |
Switch | Skip confirmation when running in delete mode |
-VerboseOutput |
Switch | Enable verbose logging |
-WhatIf |
Switch | PowerShell built-in preview mode (applies to any parameter set) |
| Parameter | Type | Description |
|---|---|---|
-All |
Switch | Enable all targets |
-OpenIntuneBaseline |
Switch | Process OpenIntuneBaseline policies |
-ComplianceTemplates |
Switch | Process compliance policies |
-AppProtection |
Switch | Process app protection policies |
-NotificationTemplates |
Switch | Process notification templates |
-EnrollmentProfiles |
Switch | Process Autopilot/ESP profiles |
-DynamicGroups |
Switch | Process dynamic groups |
-StaticGroups |
Switch | Process static (assigned) groups |
-DeviceFilters |
Switch | Process device filters |
-ConditionalAccess |
Switch | Process CA starter pack |
-MobileApps |
Switch | Process mobile app templates |
| Parameter | Type | Description |
|---|---|---|
-BaselineRepoUrl |
String | GitHub repository URL |
-BaselineBranch |
String | Git branch to use |
-BaselineDownloadPath |
String | Local download path |
| Parameter | Type | Description |
|---|---|---|
-ReportOutputPath |
String | Output directory for reports |
-ReportFormats |
String[] | Report formats: markdown, json |
| Parameter | Type | Description |
|---|---|---|
-SettingsPath |
String | Path to settings JSON file. Required for settings file mode. |
-WhatIf |
Switch | Preview mode (same as dryRun: true in settings) |
All objects created by this kit include a marker in their description:
Imported by Intune Hydration Kit
This marker is used to:
- Identify objects created by this tool
- Prevent deletion of manually-created objects
- Enable safe cleanup operations
Conditional Access policies receive additional protection:
- Always created in
disabledstate - Never automatically enabled - Deletion requires disabled state - Cannot delete enabled CA policies
- Manual review required - You must manually enable policies after review
All operations support PowerShell -WhatIf preview mode in both parameter and settings modes:
# Parameter mode
./Invoke-IntuneHydration.ps1 -TenantId "guid" -Interactive -Create -All -WhatIf
# Settings file mode
./Invoke-IntuneHydration.ps1 -SettingsPath ./settings.json -WhatIfThe script provides real-time progress with colored status indicators:
[i]Info - Operation details[!]Warning - Non-fatal issuesCreated:- New object createdSkipped:- Object already existsDeleted:- Object removed
Detailed logs are written to an OS-appropriate temp directory:
| OS | Log Path |
|---|---|
| Windows | $env:TEMP\IntuneHydrationKit\Logs\ |
| macOS | /var/folders/.../IntuneHydrationKit/Logs/ |
| Linux | /tmp/IntuneHydrationKit/Logs/ |
hydration-20241127-143052.log
After each run, reports are generated in the OS temp directory (same location as logs):
| OS | Reports Path |
|---|---|
| Windows | $env:TEMP\IntuneHydrationKit\Reports\ |
| macOS | /var/folders/.../IntuneHydrationKit/Reports/ |
| Linux | /tmp/IntuneHydrationKit/Reports/ |
Hydration-Summary.md- Human-readable markdown reportHydration-Summary.json- Machine-readable JSON for automation
You can specify a custom output path using the -ReportOutputPath parameter or reporting.outputPath in settings.
# Install required modules
Install-Module Microsoft.Graph.Authentication -Force- Ensure you have Global Administrator or Intune Administrator role
- Check that all required Graph permissions are consented
- Verify Intune licenses are assigned in the tenant
- Check for INTUNE_A, INTUNE_EDU, or EMS license
- Verify the object has "Imported by Intune-Hydration-Kit" in its description
- For CA policies, ensure the policy is in
disabledstate
Enable verbose logging in settings:
"options": {
"verbose": true
}Or use PowerShell's verbose preference:
$VerbosePreference = "Continue"
./Invoke-IntuneHydration.ps1 -SettingsPath ./settings.jsonIntune-Hydration-Kit/
├── Invoke-IntuneHydration.ps1 # Wrapper script (backward compatibility)
├── IntuneHydrationKit.psd1 # Module manifest
├── IntuneHydrationKit.psm1 # Module loader
├── build.ps1 # Build bootstrap script
├── IntuneHydrationKit.build.ps1 # InvokeBuild tasks
├── settings.example.json # Example configuration
├── Public/ # Exported functions
│ ├── Invoke-IntuneHydration.ps1 # Main orchestrator function
│ ├── Connect-IntuneHydration.ps1
│ ├── Import-IntuneBaseline.ps1
│ ├── Import-IntuneCompliancePolicy.ps1
│ ├── Import-IntuneMobileApp.ps1
│ └── ...
├── Private/ # Internal helper functions
├── Scripts/ # Helper scripts
│ └── New-MobileAppTemplate.ps1 # Generate mobile app JSON templates
├── Templates/ # Configuration templates
│ ├── Compliance/
│ ├── ConditionalAccess/
│ ├── DynamicGroups/
│ ├── Filters/
│ ├── StaticGroups/
│ ├── MobileApps/
│ └── ...
├── Tests/ # Pester tests
├── Logs/ # Execution logs
└── Reports/ # Generated reports
See CHANGELOG.md for a detailed history of changes.
- OpenIntuneBaseline by SkipToTheEndpoint - Community-driven Intune security baselines
- Microsoft Graph PowerShell SDK team
This tool is provided "as-is" without warranty of any kind. Always test in a non-production environment first. The authors are not responsible for any unintended changes to your Intune tenant. Review all configurations before enabling in production.

