Set-ApplicationCompatibility: Sets application's compatibility settings for applications


#region Function Set-ApplicationCompatibility
Function Set-ApplicationCompatibility {
<#
.SYNOPSIS
    Sets application's compatibility settings for applications
.DESCRIPTION
    Sets application's compatibility settings for applications.
	
	NOTE: Unlike what the dialog GUI for shortcut properties suggests, 
	Application Compatibility settings are NOT linked to shortcuts (.lnk)
	you can view and set Application Compatibility settings via Properties of the EXE, Compatibility tab, [Change settings for all users] button
.PARAMETER UserScope
    Set the application's compatibility settings on the CurrentUser or on AllUsers
	Defaults to affect AllUsers (recommended)
.PARAMETER Path
	location of the application EXE
	Can accept a string or an array of strings
.PARAMETER CompatibilityMode
	Specifies the OS compatibility Mode
.PARAMETER DisplaySettings
	Specifies the display compatibility setting
.PARAMETER RunAsAdmin
	Specifies if the application must run using an administrator account privilege
.EXAMPLE
	Set-ApplicationCompatibility -Path "C:\TABQUIK\TQ.EXE" -Remove $true
	Removes compatibility for TQ.EXE located in "C:\TABQUIK\TQ.EXE"
.EXAMPLE
	Set-ApplicationCompatibility -Path "C:\TABQUIK\TQ.EXE" -CompatibilityMode Windows7
	Adds Windows7 compatibility for TQ.EXE located in "C:\TABQUIK\TQ.EXE"
.EXAMPLE
	Set-ApplicationCompatibility -Path "C:\TABQUIK\TQ.EXE" -CompatibilityMode Windows7 -DisableFullScreenOpt $true -Display640x480 $true -ReducedColorMode 16BITCOLOR -HighDPIScalingOverride System
	Same as above plus:
		-Disable Full Screen Optimizations
		-Displays at 640x480 resolution
		-Reduced Color Mode to 16-BIT Color
		-Override High DPI Scaling Override scaling performed by the System
.EXAMPLE
	Set-ApplicationCompatibility -Path @("C:\TABQUIK\TQ.EXE","C:\TABQUIK\TQFilter.EXE") -CompatibilityMode Windows7 -RunAsAdmin $true
	Adds Windows7 compatibility for TQ.EXE and TQFilter.EXE located in the C:\TABQUIK folder
	Notice that Full paths are required in the array
.NOTES
	Author: Denis St-Pierre (Ottawa, Canada)
	Only tested on Windows 10.
	-Based on https://gallery.technet.microsoft.com/scriptcenter/How-to-set-the-compatibilit-f055ef26
	-Added support for windows 10 (1809) and more settings, made combining settings more foolproof 
		but not all Compatibility settings are supported at this time.
	-Removed all switches to support Splats
	-The $Path is not checked to see if it exists or not.
	-Tested on Windows10(1809) only.
	-Not tested on Windows 7 at all but should work.
#>
	[CmdletBinding()]
    Param (
		[Parameter(Mandatory = $false,HelpMessage="Defaults to AllUsers")]
		[ValidateSet("AllUsers","CurrentUser")]
        [String]$UserScope = "AllUsers",
        [Parameter(Mandatory = $true,HelpMessage="Full path to the affected EXE")]
		[ValidateNotNullorEmpty()]
        [String[]]$Path,
        [Parameter(Mandatory = $false,HelpMessage="OS Compatibility Mode")]
		[ValidateNotNullorEmpty()]
        [ValidateSet("Windows95","Windows98","WindowsXPSP2","WindowsXPSP3","WindowsVista","WindowsVistaSP1","WindowsVistaSP2","Windows7","Windows8")]
        [String]$CompatibilityMode,
        [Parameter(Mandatory = $false,HelpMessage="select: 8BITCOLOR, 256Colors, 16BITCOLOR")]
		[ValidateNotNullorEmpty()]
        [ValidateSet("8BITCOLOR","256Colors","16BITCOLOR")]
        [String]$ReducedColorMode,
        [Parameter(Mandatory = $false,HelpMessage="Run in 640x480 screen resolution")]
        [Bool]$Display640x480=$false,
        [Parameter(Mandatory = $false,HelpMessage="Override High DPI Scaling Per: App,System,SystemEnhanced")]
		[ValidateNotNullorEmpty()]
        [String[]]$HighDPIScalingOverride,
        [Parameter(Mandatory = $false,HelpMessage="Disable Full Screen Optimizations")]
        [Bool]$DisableFullScreenOpt=$false,
		[Parameter(Mandatory = $false,HelpMessage="Application MUST run with an Administrator account")]
        [Bool]$RunAsAdmin=$false,
		[Parameter(Mandatory = $false,HelpMessage="Remove Application Compatibility setting")]
		[Bool]$Remove = $false
    )
	
    Begin {
        ## Get the name of this function and write header
        [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
    }
    Process {
		If ($UserScope -eq "CurrentUser") {
			$RegPath = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers'
		} ElseIf ($UserScope -eq "AllUsers") {
			$RegPath = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers'
		} Else {
			Write-Log "UserScope [$UserScope] is not supported" -Severity 3 -Source ${CmdletName}
			Throw "UserScope [$UserScope] is not supported"
		}
	
		If ($Remove) {
	        Foreach($AppPath in $Path) {
				Write-Log "Removing Application Compatibility for app path [$AppPath]" -Source ${CmdletName}
				Remove-RegistryKey -Key $RegPath -Name $AppPath -ContinueOnError $true
	        }

		} Else {
		    [Hashtable]$CompatRules = @{"Windows95" = "WIN95"; "Windows98" = "WIN98"; "WindowsXPSP2" = "WINXPSP2"; "WindowsXPSP3" = "WINXPSP3"; "WindowsVista"= "VISTARTM"; "WindowsVistaSP1"= "VISTASP1"; "WindowsVistaSP2"= "VISTASP2"; "Windows7"= "WIN7RTM"; "Windows8"= "WIN8RTM"}
		    [Hashtable]$DisplayRules = @{"640*480"="640X480"; "256Colors"="256COLOR";"16BITCOLOR"="16BITCOLOR";
									"App"="HIGHDPIAWARE";"System"="DPIUNAWARE";"SystemEnhanced"="GDIDPISCALING DPIUNAWARE"}

		    #Define a variable named $Rules and set the value as null
		    $Rules = $null

		    #convert $CompatibilityMode Parameter value to Compatibility Rule value
		    If ($CompatibilityMode) {
		        If ($CompatRules.ContainsKey($CompatibilityMode)) {
		            $Rules += $CompatRules.$CompatibilityMode+" "
		        } else {
					Write-Log "[-CompatibilityMode $CompatibilityMode] is not supported"  -Severity 3 -Source ${CmdletName}
				}
		    }

			#convert -ReducedColorMode Parameter value to Compatibility Rule value
		    If ($ReducedColorMode) {
		        Foreach ($DisplaySetting in $ReducedColorMode) {
		            If ($DisplayRules.ContainsKey($DisplaySetting)) {
		                $Rules += $DisplayRules.$DisplaySetting+" "
			        } else {
						Write-Log "[-ReducedColorMode $ReducedColorMode] is not supported"  -Severity 3 -Source ${CmdletName}
			        }
				}
		    }
			
			#convert -Display640x480 Parameter value to Compatibility Rule value
		    If ($Display640x480) {
                $Rules += "640X480"+" "
		    }
			
			#convert -HighDPIScalingOverride Parameter value to Compatibility Rule value
		    If ($HighDPIScalingOverride) {
		        Foreach ($DisplaySetting in $HighDPIScalingOverride) {
		            If ($DisplayRules.ContainsKey($DisplaySetting)) {
		                $Rules += $DisplayRules.$DisplaySetting+" "
			        } else {
						Write-Log "[-HighDPIScalingOverride $HighDPIScalingOverride] is not supported"  -Severity 3 -Source ${CmdletName}
			        }
				}
		    }

			#convert -RunAsAdmin Parameter value to Compatibility Rule value
		    If ($RunAsAdmin) {
		        $Rules += "RUNASADMIN"+" "
		    }

			#convert -DisableFullScreenOpt Parameter value to Compatibility Rule value
		    If ($DisableFullScreenOpt) {
				#CAVEAT: DISABLEDXMAXIMIZEDWINDOWEDMODE must be at front of $Rules if used.
				$Rules = "DISABLEDXMAXIMIZEDWINDOWEDMODE"+" " + $Rules
		    }

		    If ($Rules -eq $null) {
		        Write-Log "No compatibility modes set. Nothing to do." -Severity 2 -Source ${CmdletName}
		    } Else {
				If ( $(Get-OsNickName) -eq "Win10" ) {
					Write-Log "Running on Windows 10, adding [~ ] in front of `$Rules" -Source ${CmdletName}
					$Rules = "~ " + $Rules
				} Else {
					Write-Log "NOT running on Windows 10, no changes needed." -Source ${CmdletName}
				}
				
		        Foreach($AppPath in $Path) {
					Write-Log "Adding Application Compatibility for [$AppPath] with [$Rules]" -Source ${CmdletName}
					Set-RegistryKey -Key $RegPath -Name $AppPath -Value $Rules -Type String -ContinueOnError $true
		        }
		    }
		}
	}
    End {
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
    }
}
#endregion Function Set-ApplicationCompatibility

1 Like

CAVEAT: I Have discovered that “Run As Administrator” no longer works in AT LEAST Windows 10 20H2.

When set via GUI, MS seem to have added a unique Identifier similar to what they have done with file associations. The whole function might now not work at all.
USE AT YOUR OWN RISK