Update 10-03-2023: Together with Jannik Reinhard, Florian Salzmann and Andrew Taylor, we’ve launched a new public repository where all our proactive remediations are stored. Please see the following new blogpost: Endpoint Analysis Proactive Remediation Community Repository – Joey Verlinden

In this blog post I’ll share my most used Proactive remediations with you. Some of them are being created by other community bloggers. Therefor some of the credits go to Simon Eriksen and Peter Klapwijk. Others are made by myself and are (mostly) based on recommendations shown in Defender for Endpoint.

But first, what are Proactive remediations and what are the pre-requisites?

What are Proactive Remediations

Proactive remediations are PowerShell scripts that can detect and fix issues/settings/configurations on Intune (Endpoint) managed devices. A proactive remediation always consists of two (2) scripts.

  • Detection: does a check on a setting (like a registry keys). Does it match the detection or is it different (misconfigured) from the detection?
  • Remediation: Modifies the misconfigured or different setting to the one you prefer. The remediation only fires when the detection script found a valid exit code.

Required licenses

To use proactive remediation you need one of the following licenses. The users logging on/using the devices should have one of the following licenses. For dedicated devices this won’t be an issue in most situations. For shared devices this could be an issue if users are assigned none of the following licenses. Check your licenses! Make sure you are licensed for Endpoint Analytics!

  • 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

Prerequisites

  • Make sure devices are enrolled into Endpoint analytics. This can also be done for machines managed with SCCM (Endpoint Configuration Manager).
  • Co-managed devices should run at least Windows 10 1903.
  • Devices need to be (Hybrid) Azure AD Joined.
  • Devices are running Education, Professional or Enterprise SKU.

My most used proactive remediations

Almost all of my proactive remediations can be found in my Github repository. Below i’ll try to tell you what every script does. All my scripts start with Detect_ or Remediate_. The Detect_ scripts are for the detection (of course), the Remediate_ scripts are the remediation scripts (of course). The last part of the files are identical. Therefor you should be able to match both scripts you need.

Note: Some of these settings can probably be configured via several options like a built in configuration profile or some settings in the settings catalog. If that’s possible this would be recommended. Adding these proactive remediations while also configuring this via configuration profiles does not matter as long as they match the configured setting 🙂

Detect_AdobeDC_Java.ps1 / Remediate_AdobeDC_Java.ps1

This setting is recommended (by Defender for Endpoint) for devices running Adobe DC. This registry key will disable Java within Adobe DC. The script checks the following registry key.

$Path = "HKLM:\SOFTWARE\Policies\Adobe\Adobe Acrobat\DC\FeatureLockDown"
$Name = "bDisableJavaScript"
$Type = "DWORD"
$Value = 1

The complete detection script can be found here. The remediation script can be found here. Note: The remediation script could need some modifications if this key already exists.

Detect_AdobeReader_Flash.ps1 / Remediate_AdobeReader_Flash.ps1

This setting is recommended (by Defender for Endpoint) for devices running Adobe Reader. This registry key disables Flash within Adobe Reader. The script checks the following registry key.

$Path = "HKLM:\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown"
$Name = "bEnableFlash"
$Type = "DWORD"
$Value = 0

The complete detection script can be found here. The remediation script can be found here. Note: The remediation script could need some modifications if this key already exists.

Detect_AdobeReader_Java.ps1 / Remediate_AdobeReader_Java.ps1

This setting is recommended (by Defender for Endpoint) for devices running Adobe Reader. This registry key will disable Java within Adobe Reader. The script checks the following registry key.

$Path = "HKLM:\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown"
$Name = "bDisableJavaScript"
$Type = "DWORD"
$Value = 1

The complete detection script can be found here. The remediation script can be found here. Note: The remediation script could need some modifications if this key already exists.

Detect_Always_Elevated.ps1 / Remediate_Always_Elevated.ps1

You can use the AlwaysInstallElevated policy to install a Windows Installer package with elevated (system) privileges. Recommended (by Defender for Endpoint) you should set this to disabled.

$Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer"
$Name = "AlwaysInstallElevated"
$Type = "DWORD"
$Value = "0"

The complete detection script can be found here. The remediation script can be found here. Note: The remediation script could need some modifications if this key already exists.

Detect_Built-in_MSTeams_W11.ps1 / Remediate_Built-in_MSTeams_W11.ps1

This proactive remediation is built by Peter Klapwijk. Credits go to him directly! I’ll use this script to remove the chat icon in Windows 11. It basically removes the APPX package from the endpoint.

if ($null -eq (Get-AppxPackage -Name MicrosoftTeams)) {
	Write-Host "Microsoft Teams client not found"
	exit 0
} Else {
	Write-Host "Microsoft Teams client found"
	Exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Detect_CloudDeliveredProtection.ps1 / Remediate_CloudDeliveredProtection.ps1

This proactive remediation is built by Simon Eriksen. Credits go to him directly! This proactive remediation configures the device to send advanced information to Microsoft about malicious software, spyware, and potentially unwanted software, including the location of the software, file names, how the software operates, and how it affects your computer.

$version = 'C1'
if(((Get-MpPreference).MAPSReporting -eq 2) -and ((Get-MpPreference).SubmitSamplesConsent) -eq 3) {
    Write-Output "$version COMPLIANT"
    exit 0
} else {
    Write-Output "$version NON-COMPLIANT"
    exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Detect_DeviceUptime7.ps1 / Remediate_DeviceUptime7.ps1

This proactive remediation is built by Jan Ketil Skanke. Credits go to him directly! This proactive remediation script sends a toast notification to users working on endpoints, which have not rebooted the past 7 days. The uptime and used logo’s used can be modified to your needs.

$Uptime= get-computerinfo | Select-Object OSUptime 
if ($Uptime.OsUptime.Days -ge 7){
    Write-Output "Device has not rebootet on $($Uptime.OsUptime.Days) days, notify user to reboot"
    Exit 1
}else {
    Write-Output "Device has rebootet $($Uptime.OsUptime.Days) days ago, all good"
    Exit 0
}

The complete detection script can be found here. The remediation script can be found here.

Detect_FastBoot.ps1 / Remediate_FastBoot.ps1

This proactive remediation script disables fast boot on your endpoints. There are a few reasons why you would disable fast boot. It will save diskspace and more important, some Windows Updates might have issues installing when fast boot is enabled!

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
$Name = "HiberbootEnabled"
$Type = "DWORD"
$Value = 0

The complete detection script can be found here. The remediation script can be found here. Note: The remediation script could need some modifications if this key already exists.

Detect_LSA_Protection.ps1 / Remediate_LSA_Protection.ps1

This remediation script enables LSA protection. This is recommended by Defender for Endpoint. The LSA, which includes the Local Security Authority Server Service (LSASS) process, validates users for local and remote sign-ins and enforces local security policies. The Windows 8.1 operating system provides additional protection for the LSA to prevent reading memory and code injection by non-protected processes. This provides added security for the credentials that the LSA stores and manages. More information can be found here.

$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$Name = "RunAsPPL"
$Type = "DWORD"
$Value = 1

The complete detection script can be found here. The remediation script can be found here.

Detect_NetworkProtection.ps1 / Remediate_NetworkProtection.ps1

This proactive remediation is built by Simon Eriksen. Credits go to him directly! This proactive remediation makes sure that Network Protection is enabled in the endpoint.

Network protection helps protect devices from Internet-based events. Network protection is an attack surface reduction capability. It helps prevent employees from accessing dangerous domains through applications. Domains that host phishing scams, exploits, and other malicious content on the Internet are considered dangerous. Network protection expands the scope of Microsoft Defender SmartScreen to block all outbound HTTP(s) traffic that attempts to connect to low-reputation sources (based on the domain or hostname). More information can be found here.

$version = 'C1'
if((Get-MpPreference).EnableNetworkProtection -eq 1) {
    Write-Output "$version COMPLIANT"
    exit 0
} else {
    Write-Output "$version NON-COMPLIANT"
    exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Detect_Office_Telemetry.ps1 / Remediate_Office_Telemetry.ps1

Way back, Aleksandar Milenkoski revealed that Microsoft Office is sharing more telemetry than we expected. He shared a report, which was made for the German Federal Office for Information Security to the public. This report is still available via this link. You can disable this telemetry sharing with an undocumented registry key. This is officially not supported. Although, I have never experienced any issues you can use it at your own risk.

$Path = "HKCU:\Software\Policies\Microsoft\office\common\clienttelemetry"
$Name = "DisableTelemetry"
$Type = "DWORD"
$Value = 1

The complete detection script can be found here. The remediation script can be found here.

Detect_PUA-Protection.ps1 / Remediate_PUA-Protection.ps1

This proactive remediation is built by Simon Eriksen. Credits go to him directly! This proactive remediation makes sure that Potentially Unwanted Applications is configured in Defender for Endpoint.

$version = 'C1'
if((Get-MpPreference).PUAProtection -eq 1) {
    Write-Output "$version COMPLIANT"
    exit 0
} else {
    Write-Output "$version NON-COMPLIANT"
    exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Detect_RealTimeBehavior.ps1 / Remediate_RealTimeBehavior.ps1

This proactive remediation is built by Simon Eriksen. Credits go to him directly! This proactive remediation makes sure that Real Time Behavior Monitoring is enabled.

$version = 'C1'
if((Get-MpComputerStatus).BehaviorMonitorEnabled  -eq "True") {
    Write-Output "$version COMPLIANT"
    exit 0
} else {
    Write-Output "$version NON-COMPLIANT"
    exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Detect_RealTimeProtection.ps1 / Remediate_RealTimeProtection.ps1

This proactive remediation is built by Simon Eriksen. Credits go to him directly! This proactive remediation makes sure that Real Time Protection is enabled. Real-time protection is a security feature that helps stop malware from being installed on your device. This feature is built into Microsoft Defender, a comprehensive virus and threat detection program that is part of Windows 10/11.

$version = 'C1'
if((Get-MpComputerStatus).RealTimeProtectionEnabled  -eq "True") {
    Write-Output "$version COMPLIANT"
    exit 0
} else {
    Write-Output "$version NON-COMPLIANT"
    exit 1
}

The complete detection script can be found here. The remediation script can be found here.

Related Posts

16 thoughts on “My most used Proactive Remediations

  1. Looks like unicode issue with some strange characters during import of the files in Intune, at least for AdobeDC Java.
    Looks like so in Intune portal:
    $Path = “HKLM:\SOFTWARE\Policies\Adobe\Adobe Acrobat\DC

  2. I noticed on your detection script you don’t first check to see if Acrobat is installed, only that that one registry entry is present. Was this purposeful?

    1. The client where i used this PR script required Adobe Reader/DC on all devices. Checking if the app was installed was not necessary in this use case. Do you need to check for this? Maybe assign the PR script to the Application Group which is installing the application? Otherwise i can modify the PR if you like.

      1. The way I see these scripts is they’d be assigned to all devices or users and then Detection would check for 1) The target software/change is present 2) Remediation requirement. If they are eligible for the fix (Software is present), check for whether remediation is required or already accomplished. This way the script can be assigned to all users/devices, and only remediate when necessary. I can edit the script to include the first step on my own, but wanted to clarify the intent.

  3. I am struggeling to modify the Uptime remediation script to get the Toast notification encoded with UTF8. Any suggestion?

    1. I’m sure it works if you use regular coding software like Visual Studio Code. Do the scripts work without making any modications? Make sure you deploy the script to a single test device otherwise they will see a logo they are not familiar with 😉

  4. Is there a way to setup a detection script if you are just looking to delete the full Registry entry. I am looking to create a detection and remediate script if this entry ‘HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\FPDU’ is present then it will delete the registry entry.

    1. I think something like this. This is not the best PowerShell method by the way..

      Make sure the $Value parameter is filled with the data your devices have in it. If the key, name and value exist exactly it reports not compliant with exit code 1. The exit code continues to the remediation. I guess you’re able to create a remediation yourself?

      [cc lang=”Powershell”]$Path = “HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run”
      $Name = “FPDU”
      $Value = “DATAHERE”

      Try {
      $Registry = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue | Select-Object -ExpandProperty $Name
      If ($Registry -ne $Value){
      Write-Output “Compliant”
      Exit 0
      }
      Write-Warning “Not Compliant”
      Exit 1
      }
      Catch {
      Write-Warning “Not Compliant”
      Exit 1
      }[/cc]

      Examples are here:
      https://github.com/j0eyv/ProactiveRemediations/blob/main/Detect_registryexists1.ps1
      https://github.com/j0eyv/ProactiveRemediations/blob/main/Detect_registryexists2.ps1

      1. Awesome! I think that should do the trick. Basically it is a string value:

        Name: FPDU
        Type: REG_SZ
        Data: C:\Program Files (x86)\FPDU\Fiery Driver Updater.exe -s -sp”-showonupdate”

  5. Oh Also I was thinking this should suffice then for the remediation script:

    Remove-ItemProperty -name “FPDU” -path “HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\FPDU”

  6. Hi,

    I just found your page and repository and I wanted to say thank you for sharing! I also was hoping to see if I could suggest an addition to the other remediations. Can you build one for Adobe Acrobat Reader removal?

    Thank you!

    Ryan

  7. For security i made a script that does multiple so you dont have to much remedeation scripts
    Check
    # Define an array of registry settings to check
    $RegistrySettingsToCheck = @(
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Control\Lsa”
    Name = “RestrictAnonymous”
    Value = 1
    },
    # Set emailscan
    @{
    Path = “HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan”
    Name = “DisableEmailScanning”
    Value = 1
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown”
    Name = “bDisableJavaScript”
    Value = 0
    }

    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters”
    Name = “RequireSecuritySignature”
    Value = 1
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters”
    Name = “RequireSignOrSeal”
    Value = 0
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Control\Lsa”
    Name = “LmCompatibilityLevel”
    Value = 5
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10”
    Name = “Start”
    Value = 4
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Google\Chrome”
    Name = “BackgroundModeEnabled”
    Value = 0
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections”
    Name = “NC_StdDomainUserSetLocation”
    Value = 0
    }
    )

    # Loop through each registry setting to check compliance
    foreach ($Setting in $RegistrySettingsToCheck) {
    $Path = $Setting.Path
    $Name = $Setting.Name
    $Value = $Setting.Value

    # Check if the registry value is compliant
    try {
    $Registry = Get-ItemProperty -Path $Path -Name $Name -ErrorAction Stop | Select-Object -ExpandProperty $Name
    if ($Registry -eq $Value) {
    Write-Output “$Path\$Name is compliant”
    } else {
    Write-Warning “$Path\$Name is not compliant”
    Exit 1 # Exiting with a non-zero exit code to indicate non-compliance
    }
    } catch {
    Write-Warning “Failed to check $Path\$Name $_”
    Exit 1 # Exiting with a non-zero exit code in case of errors
    }
    }

    # If all registry settings are compliant, exit with a zero exit code
    Exit 0
    Remediate
    # Define an array of registry settings to set
    $RegistrySettingsToSet = @(
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Control\Lsa”
    Name = “RestrictAnonymous”
    Value = 1
    },
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Scan”
    Name = “DisableEmailScanning”
    Value = 0
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown”
    Name = “bDisableJavaScript”
    Value = 1
    }

    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters”
    Name = “RequireSecuritySignature”
    Value = 1
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters”
    Name = “RequireSignOrSeal”
    Value = 1
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Control\Lsa”
    Name = “LmCompatibilityLevel”
    Value = 5
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10”
    Name = “Start”
    Value = 4
    }
    # Add more registry settings to check as needed
    @{
    Path = “HKLM:\SOFTWARE\Policies\Google\Chrome”
    Name = “BackgroundModeEnabled”
    Value = 0
    }
    @{
    Path = “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections”
    Name = “NC_StdDomainUserSetLocation”
    Value = 1
    }
    )

    # Loop through each registry setting to set if not compliant
    foreach ($Setting in $RegistrySettingsToSet) {
    $Path = $Setting.Path
    $Name = $Setting.Name
    $Value = $Setting.Value

    # Set the registry value if it’s not compliant
    try {
    if (!(Test-Path $Path)) {
    New-Item -Path $Path -Force
    }
    $Registry = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
    if (!$Registry -or $Registry.$Name -ne $Value) {
    New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType DWORD -Force
    Write-Output “Key created/updated: $Path\$Name = $Value”
    } else {
    Write-Output “$Path\$Name is already compliant”
    }
    } catch {
    Write-Error “Failed to set $Path\$Name $_”
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

two × two =