From 0004e0f240a208d590fe9d6cb2612c2a373b61d8 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 19 Mar 2026 16:59:50 -0500 Subject: [PATCH] =?UTF-8?q?Article:=20Shorten,=20link=20out=20-=20Update?= =?UTF-8?q?=20migrating-intune-policies-to-flee=E2=80=A6=20(#42113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …t-csp-converter.md --- ...-intune-policies-to-fleet-csp-converter.md | 149 +----------------- 1 file changed, 3 insertions(+), 146 deletions(-) diff --git a/articles/migrating-intune-policies-to-fleet-csp-converter.md b/articles/migrating-intune-policies-to-fleet-csp-converter.md index b2b05cb3e0..de64778009 100644 --- a/articles/migrating-intune-policies-to-fleet-csp-converter.md +++ b/articles/migrating-intune-policies-to-fleet-csp-converter.md @@ -6,33 +6,6 @@ Migrating Windows configuration policies from Microsoft Intune to Fleet doesn't If you're new to Windows CSPs in Fleet, start with [Creating Windows configuration profiles (CSPs)](https://fleetdm.com/guides/creating-windows-csps) first. That guide explains the SyncML format, registry lookups, and how Fleet applies profiles to devices. -## How it works - -The converter takes an Intune JSON policy export and produces SyncML XML files for each policy setting, ready to upload to Fleet as [custom OS settings](https://fleetdm.com/guides/custom-os-settings). - -It does this in four steps: - -1. **Policy extraction** — Recursively parses the Intune JSON, including nested choice settings and their child configurations. -2. **Registry lookup** — Queries the Windows CSP NodeCache registry (`HKLM:\SOFTWARE\Microsoft\Provisioning\NodeCache\CSP\Device\MS DM Server\Nodes`) to find the exact `NodeURI` path with proper TitleCase casing — which Windows CSPs require. -3. **Format detection** — Determines whether each setting should use `bool`, `int`, or `chr` SyncML format, based on the policy type and Microsoft's CSP documentation. -4. **Value resolution** — For policies where Intune stores `ExpectedValue = -1` (unset), a resolver map of PowerShell expressions queries the current system state to determine the correct value. - -Each setting becomes a SyncML `` block: - -```xml - - - - bool - - - ./Vendor/MSFT/Firewall/MdmStore/PrivateProfile/EnableFirewall - - true - - -``` - ## Prerequisites Before running the converter: @@ -66,44 +39,8 @@ Open PowerShell as Administrator on your Intune-enrolled Windows host and run: .\Convert-IntuneToFleetCSP.ps1 -JsonPath "C:\Path\To\YourPolicy.json" ``` -### Common usage patterns - -Basic conversion (individual XML files per policy): -```powershell -.\Convert-IntuneToFleetCSP.ps1 -JsonPath "MyFirewallPolicy.json" -``` - -Create a single merged XML file: -```powershell -.\Convert-IntuneToFleetCSP.ps1 -JsonPath "MyPolicy.json" -MergeXml -OutputPath "C:\Fleet\CSPs" -``` - -Dry run — analyze without creating files: -```powershell -.\Convert-IntuneToFleetCSP.ps1 -JsonPath "MyPolicy.json" -DryRun -``` - -Debug mode — verbose output for troubleshooting: -```powershell -.\Convert-IntuneToFleetCSP.ps1 -JsonPath "MyPolicy.json" -DebugMode -``` - -### Parameters - -| Parameter | Description | Default | -|-----------|-------------|---------| -| `JsonPath` | Path to Intune policy JSON export | *Required* | -| `ResolverMapPath` | Path to `resolver-map.json` | `C:\CSPConverter\resolver-map.json` | -| `OutputPath` | Directory for output XML files | `C:\CSPConverter\Output` | -| `LogPath` | Path for conversion log CSV | `C:\CSPConverter\ConversionLog.csv` | -| `DebugMode` | Verbose debug output | `$false` | -| `DryRun` | Analyze only, no files created | `$false` | -| `MergeXml` | Merge all policies into one XML file | `$false` | - ### Step 3: Review the results -### Console summary - When the script finishes, it prints a summary: ``` @@ -123,24 +60,11 @@ Not Found: 2 | Skipped | No value could be determined (no resolver, no usable suffix) | | Not Found | No matching entry in the CSP NodeCache registry | -### Conversion log - -A CSV log is saved to `C:\CSPConverter\ConversionLog.csv` (or your specified `-LogPath`). Open it in Excel or any CSV viewer to review every policy: - -| Column | Description | -|--------|-------------| -| `Setting` | Original Intune `settingDefinitionId` | -| `NodeUri` | The resolved CSP path used in the XML | -| `Status` | Exported / Resolved / Skipped / Not Found / Error | -| `Value` | The data value written into `` | -| `Notes` | Format type and any resolution details | - -Review `Not Found` and `Skipped` rows carefully — these are the policies that didn't convert and will need manual attention. - -### Output files Individual XML files are saved to `C:\CSPConverter\Output\` by default. Each file is named after the sanitized `NodeUri` path. If you used `-MergeXml`, you'll find a single `MergedPolicies.xml` instead. +> **Important:** For troubleshooting tips and more information on how this works, check out the [`intune-to-fleet` README](https://github.com/tux234/intune-to-fleet). + ### Step 4: Upload to Fleet 1. Review each output XML file. Verify the `` and `` values look correct for your environment. @@ -149,75 +73,8 @@ Individual XML files are saved to `C:\CSPConverter\Output\` by default. Each fil Fleet will deploy the profile to matching Windows devices on their next MDM check-in. -> **Tip:** Use a small test group or canary team in Fleet before rolling out converted profiles broadly. Even a "Resolved" policy may need tweaking if the resolver returned a value that doesn't match your intended configuration. +> Use a small test group or canary team in Fleet before rolling out converted profiles broadly. Even a "Resolved" policy may need tweaking if the resolver returned a value that doesn't match your intended configuration. -## Resolver map - -The `resolver-map.json` file handles the `ExpectedValue = -1` edge case — policies where Intune didn't explicitly store the enforced value in the registry. The resolver map contains PowerShell expressions that query the current system state at conversion time. - -Built-in resolvers cover common scenarios including: -- Windows Firewall profiles (`EnableFirewall`, `AllowLocalPolicyMerge`, etc.) -- Defender settings (`RealTimeProtection`, `CloudProtection`, `TamperProtection`) -- BitLocker (`RequireDeviceEncryption`, `RequireTPM`) -- SmartScreen, DeviceLock, Privacy, Update, and System policies - -**To add a custom resolver**, add an entry to `resolver-map.json` where the key is the last segment of the CSP path and the value is a PowerShell expression returning `1` (enabled) or `0` (disabled): - -```json -{ - "YourPolicyName": "try { if ((Get-ItemPropertyValue -Path 'HKLM:\\...' -Name 'PolicyValue') -eq 1) { 1 } else { 0 } } catch { 0 }" -} -``` - -## Extending the tool - -### Adding boolean format policies - -Most policies use integer format (`0` / `1`), but some Windows CSPs require `true` / `false` boolean values. If you find a policy is being written as `int` when it should be `bool`, add a wildcard pattern to the `$booleanFormatPolicies` array in the `Get-SyncMLFormatAndData` function: - -```powershell -$booleanFormatPolicies = @( - # ... existing patterns ... - "*your*custom*policy*pattern*" -) -``` - -## Troubleshooting - -### "No match found for NodeUri" - -The policy wasn't found in the CSP NodeCache registry. This means either: -- The policy isn't supported on your Windows version. -- The policy was never applied to the device via Intune (the NodeCache is only populated for settings that have been pushed and applied). - -Try running the script on a Windows host where that specific policy has been actively enforced by Intune. - -### "Resolver execution failed" - -A resolver map entry failed to execute. Check that: -- The required PowerShell modules are installed (e.g., `Get-MpPreference` requires Windows Defender). -- The PowerShell expression syntax in `resolver-map.json` is valid. -- The script is running with sufficient privileges. - -### Policies convert with unexpected values - -Use debug mode to trace the processing of a specific policy: - -```powershell -.\Convert-IntuneToFleetCSP.ps1 -JsonPath "MyPolicy.json" -DebugMode -DryRun -``` - -Debug output shows the registry lookup result, format detection logic, and the value determination for each setting. No files are created when combined with `-DryRun`. - -### Profile fails to apply in Fleet - -If Fleet reports a profile error after upload, check the Windows MDM event log on an affected device: - -```powershell -Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin'; Level=2} -MaxEvents 15 | Format-Table -Wrap -``` - -The most common cause is a `` mismatch — the CSP expects `bool` but received `int`, or vice versa. Cross-reference the CSP path in [Microsoft's documentation](https://learn.microsoft.com/en-us/windows/client-management/mdm/) to confirm the expected format. ## What this tool doesn't cover