In my previous blog post, we have learnt the steps to create registry keys and values using Win32 app method. It requires export of the registry key and import it on target Windows 10/11 devices.
In this blog post, we will see how to create registry keys and values using Intune device remediations. For demonstration purpose, we will be creating registry key and values under HKLM registry node. To create registry keys under HKCU node, refer to the link: Create HKCU Registry Keys using Intune remediations.
Please note that Intune remediations requires Windows 10/11 Enterprise license. For more information, please refer to the prerequisites section.
If you have a requirement to back up and delete a registry key, refer to my other blog post, which offers guidance on addressing the CVE-2022-30190 vulnerability. It also provides the steps for backing up and deleting a registry key using Intune.
Want to backup and delete a registry key?
Contents
Prerequisites
- Device must be Microsoft Entra joined or Entra Hybrid joined.
- Device must be enrolled and managed by Intune.
- Supported Windows operating systems are: Enterprise, Professional, or Education edition of Windows 10 or later.
- Windows 10/11 Enterprise E3 or E5 (included in Microsoft 365 F3, E3, or E5).
- Windows 10/11 Education A3 or A5 (included in Microsoft 365 A3 or A5).
- Windows 10/11 Virtual Desktop Access (VDA) per user.
Create a Remediation Script Package
To create a device remediation script package, we will need a detection and a remediation script. I have provided both the scripts code below. However, you can also download the script files from my GitHub repository: Create Reg Key and Values using Remediations – GitHub.
- Sign in to the Intune admin center > Devices > Scripts and remediatons.
- Click on + Create under the Remediations tab.
- Basics: Provide a Name, Description, and Publisher Information of the remediation script package.
- Settings: Create a detection script using below PowerShell code. Save it as Detect_reg_key.ps1.
You can change the registry path and values in the script according to your requirements. Using this example detection and remediation scripts, I am making sure that cloudinfra.net registry key and entries Location and Status along with the given values and type are always set to values (
$regValues
) given in the script.Note
Detect_reg_key.ps1
<#
.DESCRIPTION
Checks the existence of the cloudinfra.net registry key and its values.
Author: Jatin Makhija
Version: 1.0.0
#>
$regPath = "HKLM:\Software\cloudinfra.net"
$regValues = @{
"Location" = @{ Data = "United Kingdom"; Type = "String" }
"Status" = @{ Data = "1"; Type = "Dword" }
}
$typeMap = @{
"String" = [Microsoft.Win32.RegistryValueKind]::String
"DWord" = [Microsoft.Win32.RegistryValueKind]::DWord
"QWord" = [Microsoft.Win32.RegistryValueKind]::QWord
"Binary" = [Microsoft.Win32.RegistryValueKind]::Binary
"MultiString" = [Microsoft.Win32.RegistryValueKind]::MultiString
"ExpandString" = [Microsoft.Win32.RegistryValueKind]::ExpandString
}
if (Test-Path $regPath) {
Write-Host "Registry key exists. Checking values..."
foreach ($key in $regValues.Keys) {
$expected = $regValues[$key]
$actual = Get-ItemProperty -Path $regPath -Name $key -ErrorAction SilentlyContinue
if ($null -eq $actual) {
Write-Host "Registry value '$key' does not exist!"
Exit 1
}
$actualValue = $actual.$key
$actualType = (Get-Item -Path $regPath).GetValueKind($key)
if ($actualType -ne $typeMap[$expected.Type] -or $actualValue -ne $expected.Data) {
Write-Host "Registry value '$key' is of type $actualType, expected $($expected.Type) or value does not match!"
Exit 1
}
}
Write-Host "All registry values match the expected data. No action required."
Exit 0
} else {
Write-Host "Registry key does not exist."
Exit 1
}
- Create a remediation script using below powershell code. Save it as Remediate_reg_key.ps1.
Remediate_reg_key.ps1
<#
.DESCRIPTION
Checks the existence of the cloudinfra.net registry key and its values. If it does not exist, it creates it.
Author: Jatin Makhija
Version: 1.0.0
#>
$regPath = "HKLM:\Software\cloudinfra.net"
# Define expected values and types
$regValues = @{
"Location" = @{ Data = "United Kingdom"; Type = "String" }
"Status" = @{ Data = "1"; Type = "Dword" }
}
$typeMap = @{
"String" = [Microsoft.Win32.RegistryValueKind]::String
"DWord" = [Microsoft.Win32.RegistryValueKind]::DWord
"QWord" = [Microsoft.Win32.RegistryValueKind]::QWord
"Binary" = [Microsoft.Win32.RegistryValueKind]::Binary
"MultiString" = [Microsoft.Win32.RegistryValueKind]::MultiString
"ExpandString" = [Microsoft.Win32.RegistryValueKind]::ExpandString
}
# Check if the registry key exists
if (-not (Test-Path $regPath)) {
try {
Write-Host "Creating Reg Key"
New-Item -Path HKLM:\Software -Name cloudinfra.net -Force | Out-Null
foreach ($key in $regValues.Keys) {
$value = $regValues[$key]
New-ItemProperty -Path $regPath -Name $key -Value $value.Data -PropertyType $value.Type -Force | Out-Null
}
Exit 0
} catch {
Write-Host "Error Creating Reg Key"
Write-Error $_
Exit 1
}
} else {
Write-Host "Reg Key already exists. Checking values..."
foreach ($key in $regValues.Keys) {
$expected = $regValues[$key]
$actual = Get-ItemProperty -Path $regPath -Name $key -ErrorAction SilentlyContinue
if ($null -eq $actual) {
Write-Host "Registry value '$key' does not exist! Creating it..."
New-ItemProperty -Path $regPath -Name $key -Value $expected.Data -PropertyType $expected.Type -Force | Out-Null
continue
}
$actualValue = $actual.$key
$actualType = (Get-Item -Path $regPath).GetValueKind($key)
# Check if the actual type and value match the expected type and value
if ($actualType -ne $typeMap[$expected.Type] -or $actualValue -ne $expected.Data) {
Write-Host "Incorrect '$key' value or type. Correcting it..."
# Remove the existing property before adding it again
Remove-ItemProperty -Path $regPath -Name $key -ErrorAction SilentlyContinue
New-ItemProperty -Path $regPath -Name $key -Value $expected.Data -PropertyType $expected.Type -Force | Out-Null
}
}
Write-Host "All values are correct or have been remediated. No further action required."
Exit 0
}
- Detection script file – Browse to the Detection script Detect_reg_key.ps1
- Remediation script file – Browse to Remediation script file Remediate_reg_key.ps1
- Run this script using the logged-on credentials – No
- Enforce script signature check – No
- Run script in 64-bit Powershell – Yes
- Assignments: Click on Add group to add an Entra security group containing users or devices. You can also select the Schedule to run this script package. You have three options: Once, hourly, or Daily.
- Review + create: Review the deployment and click on Create.
Sync Intune Policies
The device check-in process might not begin immediately. If you’re testing this policy on a test device, you can manually kickstart Intune sync from the device itself or remotely through the Intune admin center.
Alternatively, you can use PowerShell to force the Intune sync on Windows devices. Restarting the device is another way to trigger the Intune device check-in process.
End User Experience
After the script package is deployed on the target device. You can open the registry editor on the device to check and confirm if the registry keys and values are created as per the script.
Monitor Intune Device Remediations
To check Intune device remediation script packages, do the following:
- Sign in to the Intune admin center > Devices > Scripts and Remediations.
- Click on the Remediation script package you want to monitor – for example, Registry keys Deployment using Intune.
Conclusion
In this blog post, we explored creating registry keys using Intune remediations. Intune offers various methods for deploying registry keys and entries. Another approach involves creating and deploying a PowerShell script through the Devices > Scripts and remediations > Platform scripts method.