Windows Components › Remote Desktop Services › Remote Desktop Session Host › Profiles
Limit the size of the entire roaming user profile cache
Supported on At least Windows Server 2008 R2
What it does
This policy setting allows you to limit the size of the entire roaming user profile cache on the local drive. This policy setting only applies to a computer on which the Remote Desktop Session Host role service is installed. Note: If you want to limit the size of an individual user profile, use the "Limit profile size" policy setting located in User Configuration\Policies\Administrative Templates\System\User Profiles. If you enable this policy setting, you must specify a monitoring interval (in minutes) and a maximum size (in gigabytes) for the entire roaming user profile cache. The monitoring interval determines how often the size of the entire roaming user profile cache is checked. When the size of the entire roaming user profile cache exceeds the maximum size that you have specified, the oldest (least recently used) roaming user profiles will be deleted until the size of the entire roaming user profile cache is less than the maximum size specified. If you disable or do not configure this policy setting, no restriction is placed on the size of the entire roaming user profile cache on the local drive. Note: This policy setting is ignored if the "Prevent Roaming Profile changes from propagating to the server" policy setting located in Computer Configuration\Policies\Administrative Templates\System\User Profiles is enabled.
What it writes
- Hive
- HKEY_LOCAL_MACHINE
- Registry key
SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services- Value name
DeleteRoamingUserProfile- When enabled
- DWORD 1
- When disabled
- DWORD 0
In Intune
Native Intune setting: Yes — Policy CSP
./Device/Vendor/MSFT/Policy/Config/ADMX_TerminalServer/TS_DELETE_ROAMING_USER_PROFILESADMX_TerminalServer on Microsoft LearnADMX-backed: Windows ships this template, so it is set with the template's own values, without an import.Windows builds listed: 10.0.22000, 10.0.19043.1202, 10.0.19042.1202, 10.0.19041.1202.
From Microsoft's Policy CSP DDF files (DDF v2 Files, February 2026), read 18 Oct 2026.
Options
| Option | Type | Registry value | Allowed values |
|---|---|---|---|
| Monitoring interval (minutes)RequiredDefault: 900 | Number | MonitoringInterval |
15 to 10080 |
| Maximum cache size (GBs)RequiredDefault: 600 | Number | ProfileDirectoryQuota |
5 to 10000 |
Configure and deploy
Choose a state and the option values; the output below is generated from the template for exactly that.
Enabled · Computer · template defaults
Registry file (.reg)
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services]
"DeleteRoamingUserProfile"=dword:00000001
"MonitoringInterval"=dword:00000384
"ProfileDirectoryQuota"=dword:00000258
PowerShell
$ErrorActionPreference = 'Stop'
function Set-RegistryValue {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $true)][string] $PropertyType,
[Parameter(Mandatory = $true)][object] $Value
)
if (-not (Test-Path -LiteralPath $Path)) {
New-Item -Path $Path -Force | Out-Null
}
New-ItemProperty -LiteralPath $Path -Name $Name -PropertyType $PropertyType -Value $Value -Force | Out-Null
}
function Remove-RegistryValue {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name
)
if (Test-Path -LiteralPath $Path) {
Remove-ItemProperty -LiteralPath $Path -Name $Name -Force -ErrorAction SilentlyContinue
}
}
function Clear-RegistryKeyValues {
param(
[Parameter(Mandatory = $true)][string] $Path
)
if (-not (Test-Path -LiteralPath $Path)) {
return
}
foreach ($propertyName in (Get-Item -LiteralPath $Path).Property) {
Remove-ItemProperty -LiteralPath $Path -Name $propertyName -Force -ErrorAction SilentlyContinue
}
}
# Policy: Limit the size of the entire roaming user profile cache
# Name: TS_DELETE_ROAMING_USER_PROFILES
# Scope: Machine
# State: Enabled
# Source: TerminalServer.admx
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'DeleteRoamingUserProfile' -PropertyType 'DWord' -Value 1
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'MonitoringInterval' -PropertyType 'DWord' -Value 900
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'ProfileDirectoryQuota' -PropertyType 'DWord' -Value 600
These deployment candidates come from the ADMX template; they are separate from the native CSP mapping above.
- The OMA-URI is an inferred ADMX-backed Policy CSP candidate derived from the source ADMX file name and policy name.
- Some Microsoft policies use built-in Policy CSP pages whose area names don't match the ADMX file name, so verify the candidate against Microsoft Learn before deployment.
ADMX profile candidate (OMA-URI)
./Device/Vendor/MSFT/Policy/Config/ADMX_TerminalServer/TS_DELETE_ROAMING_USER_PROFILESADMX SyncML candidate
<SyncML xmlns="SYNCML:SYNCML1.2">
<SyncBody>
<Replace>
<CmdID>1</CmdID>
<Item>
<Meta>
<Format>chr</Format>
<Type>text/plain</Type>
</Meta>
<Target>
<LocURI>./Device/Vendor/MSFT/Policy/Config/ADMX_TerminalServer/TS_DELETE_ROAMING_USER_PROFILES</LocURI>
</Target>
<Data><enabled/>
<data id="TS_PROFILE_DIRECTORY_MONITORING_INTERVAL" value="900"/>
<data id="TS_PROFILE_DIRECTORY_QUOTA" value="600"/></Data>
</Item>
</Replace>
<Final/>
</SyncBody>
</SyncML>Intune remediation scripts
Detection
$ErrorActionPreference = 'Stop'
$reasons = [System.Collections.Generic.List[string]]::new()
function Test-RegistryValueExists {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name
)
if (-not (Test-Path -LiteralPath $Path)) {
return $false
}
return $null -ne (Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction SilentlyContinue)
}
function Test-RegistryValueEquals {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $true)][string] $Kind,
[Parameter(Mandatory = $true)][object] $Expected
)
if (-not (Test-Path -LiteralPath $Path)) {
return $false
}
$valueObject = Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction SilentlyContinue
if ($null -eq $valueObject) {
return $false
}
$actual = $valueObject.$Name
switch ($Kind) {
'String' { return [string]$actual -ceq [string]$Expected }
'ExpandString' { return [string]$actual -ceq [string]$Expected }
'DWord' { return [uint32]$actual -eq [uint32]$Expected }
'QWord' { return [uint64]$actual -eq [uint64]$Expected }
'MultiString' {
$actualArray = @($actual)
$expectedArray = @($Expected)
if ($actualArray.Count -ne $expectedArray.Count) { return $false }
for ($index = 0; $index -lt $actualArray.Count; $index++) {
if ([string]$actualArray[$index] -cne [string]$expectedArray[$index]) { return $false }
}
return $true
}
'Binary' {
$actualArray = [byte[]]$actual
$expectedArray = [byte[]]$Expected
if ($actualArray.Length -ne $expectedArray.Length) { return $false }
for ($index = 0; $index -lt $actualArray.Length; $index++) {
if ($actualArray[$index] -ne $expectedArray[$index]) { return $false }
}
return $true
}
default { return [string]$actual -ceq [string]$Expected }
}
}
# Policy: Limit the size of the entire roaming user profile cache
# Name: TS_DELETE_ROAMING_USER_PROFILES
# Scope: Machine
# State: Enabled
# Source: TerminalServer.admx
$isMatch = Test-RegistryValueEquals -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'DeleteRoamingUserProfile' -Kind 'DWord' -Expected 1
if (-not $isMatch) {
$reasons.Add('Value mismatch: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\DeleteRoamingUserProfile') | Out-Null
}
$isMatch = Test-RegistryValueEquals -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'MonitoringInterval' -Kind 'DWord' -Expected 900
if (-not $isMatch) {
$reasons.Add('Value mismatch: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\MonitoringInterval') | Out-Null
}
$isMatch = Test-RegistryValueEquals -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'ProfileDirectoryQuota' -Kind 'DWord' -Expected 600
if (-not $isMatch) {
$reasons.Add('Value mismatch: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\ProfileDirectoryQuota') | Out-Null
}
if ($reasons.Count -eq 0) {
Write-Output 'Compliant'
exit 0
}
$reasons | ForEach-Object { Write-Output $_ }
exit 1
Remediation
$ErrorActionPreference = 'Stop'
function Set-RegistryValue {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $true)][string] $PropertyType,
[Parameter(Mandatory = $true)][object] $Value
)
if (-not (Test-Path -LiteralPath $Path)) {
New-Item -Path $Path -Force | Out-Null
}
New-ItemProperty -LiteralPath $Path -Name $Name -PropertyType $PropertyType -Value $Value -Force | Out-Null
}
function Remove-RegistryValue {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Name
)
if (Test-Path -LiteralPath $Path) {
Remove-ItemProperty -LiteralPath $Path -Name $Name -Force -ErrorAction SilentlyContinue
}
}
function Clear-RegistryKeyValues {
param(
[Parameter(Mandatory = $true)][string] $Path
)
if (-not (Test-Path -LiteralPath $Path)) {
return
}
foreach ($propertyName in (Get-Item -LiteralPath $Path).Property) {
Remove-ItemProperty -LiteralPath $Path -Name $propertyName -Force -ErrorAction SilentlyContinue
}
}
# Policy: Limit the size of the entire roaming user profile cache
# Name: TS_DELETE_ROAMING_USER_PROFILES
# Scope: Machine
# State: Enabled
# Source: TerminalServer.admx
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'DeleteRoamingUserProfile' -PropertyType 'DWord' -Value 1
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'MonitoringInterval' -PropertyType 'DWord' -Value 900
Set-RegistryValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'ProfileDirectoryQuota' -PropertyType 'DWord' -Value 600
History 5 retained releases
- 22H2 · 1.015 Jul 2024
- Already present in the first release ChangeIntel keeps.
4 later releases left it unchanged.
Template
- Internal name
TS_DELETE_ROAMING_USER_PROFILES- Namespace
Microsoft.Policies.TerminalServer- Template file
TerminalServer.admx- Release
- Windows 11 25H2 · 1.0 · file set
de4e49983ebd651f…
Definition, editor controls and support
Definition
<policy class="Machine" displayName="$(string.TS_DELETE_ROAMING_USER_PROFILES)" explainText="$(string.TS_DELETE_ROAMING_USER_PROFILES_EXPLAIN)" key="SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" name="TS_DELETE_ROAMING_USER_PROFILES" presentation="$(presentation.TS_DELETE_ROAMING_USER_PROFILES)" valueName="DeleteRoamingUserProfile" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.TerminalServer:TS_PROFILES" />
<supportedOn ref="Microsoft.Policies.TerminalServer:TS_SUPPORTED_Windows7_Server" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
<elements>
<decimal id="TS_PROFILE_DIRECTORY_MONITORING_INTERVAL" maxValue="10080" minValue="15" required="true" valueName="MonitoringInterval" />
<decimal id="TS_PROFILE_DIRECTORY_QUOTA" maxValue="10000" minValue="5" required="true" valueName="ProfileDirectoryQuota" />
</elements>
</policy>Editor controls
<presentation id="TS_DELETE_ROAMING_USER_PROFILES" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<decimalTextBox defaultValue="900" refId="TS_PROFILE_DIRECTORY_MONITORING_INTERVAL" spinStep="30">Monitoring interval (minutes):</decimalTextBox>
<decimalTextBox defaultValue="600" refId="TS_PROFILE_DIRECTORY_QUOTA" spinStep="50">Maximum cache size (GBs):</decimalTextBox>
</presentation>Supported platforms and category
Microsoft.Policies.TerminalServer:category:TS_GP_NODE
<category displayName="$(string.TS_GP_NODE)" explainText="$(string.TS_User_Help)" name="TS_GP_NODE" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.Windows:WindowsComponents" />
</category>
Microsoft.Policies.TerminalServer:category:TS_PROFILES
<category displayName="$(string.TS_PROFILES)" explainText="$(string.TS_PROFILES_Help)" name="TS_PROFILES" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.TerminalServer:TS_TERMINAL_SERVER" />
</category>
Microsoft.Policies.TerminalServer:category:TS_TERMINAL_SERVER
<category displayName="$(string.TS_TERMINAL_SERVER)" explainText="$(string.TS_TERMINAL_SERVER_Help)" name="TS_TERMINAL_SERVER" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.TerminalServer:TS_GP_NODE" />
</category>
Microsoft.Policies.TerminalServer:definition:TS_SUPPORTED_Windows7_Server
<definition displayName="$(string.TS_SUPPORTED_Windows7_Server)" name="TS_SUPPORTED_Windows7_Server" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<or>
<reference minVersionIndex="1" ref="Microsoft.Policies.Products:WindowsServer2008_R2" />
</or>
</definition>
Microsoft.Policies.TerminalServer:unresolved:Microsoft.Policies.Products:WindowsServer2008_R2
<unresolved reference="Microsoft.Policies.Products:WindowsServer2008_R2" />
Microsoft.Policies.Windows:category:WindowsComponents
<category displayName="$(string.WindowsComponents)" explainText="$(string.WindowsComponents_Help)" name="WindowsComponents" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions" />
Microsoft.Policies.TerminalServer:category:TS_GP_NODE
<category displayName="$(string.TS_GP_NODE)" explainText="$(string.TS_User_Help)" name="TS_GP_NODE" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.Windows:WindowsComponents" />
</category>
<strings><string id="Microsoft.Policies.TerminalServer:TS_GP_NODE">Remote Desktop Services</string><string id="Microsoft.Policies.TerminalServer:TS_User_Help">Controls configuration of Remote Desktop Services technologies that enable access to a server running Windows-based programs or the full Windows desktop</string></strings>
Microsoft.Policies.TerminalServer:category:TS_PROFILES
<category displayName="$(string.TS_PROFILES)" explainText="$(string.TS_PROFILES_Help)" name="TS_PROFILES" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.TerminalServer:TS_TERMINAL_SERVER" />
</category>
<strings><string id="Microsoft.Policies.TerminalServer:TS_PROFILES">Profiles</string><string id="Microsoft.Policies.TerminalServer:TS_PROFILES_Help">Controls roaming profile and home directory settings for Remote Desktop Services sessions</string></strings>
Microsoft.Policies.TerminalServer:category:TS_TERMINAL_SERVER
<category displayName="$(string.TS_TERMINAL_SERVER)" explainText="$(string.TS_TERMINAL_SERVER_Help)" name="TS_TERMINAL_SERVER" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<parentCategory ref="Microsoft.Policies.TerminalServer:TS_GP_NODE" />
</category>
<strings><string id="Microsoft.Policies.TerminalServer:TS_TERMINAL_SERVER">Remote Desktop Session Host</string><string id="Microsoft.Policies.TerminalServer:TS_TERMINAL_SERVER_Help">Controls configuration of a Remote Desktop Session Host server</string></strings>
Microsoft.Policies.TerminalServer:definition:TS_SUPPORTED_Windows7_Server
<definition displayName="$(string.TS_SUPPORTED_Windows7_Server)" name="TS_SUPPORTED_Windows7_Server" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<or>
<reference minVersionIndex="1" ref="Microsoft.Policies.Products:WindowsServer2008_R2" />
</or>
</definition>
<strings><string id="Microsoft.Policies.TerminalServer:TS_SUPPORTED_Windows7_Server">At least Windows Server 2008 R2</string></strings>
Microsoft.Policies.Windows:category:WindowsComponents
<category displayName="$(string.WindowsComponents)" explainText="$(string.WindowsComponents_Help)" name="WindowsComponents" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions" />
<strings><string id="Microsoft.Policies.Windows:WindowsComponents">Windows Components</string><string id="Microsoft.Policies.Windows:WindowsComponents_Help">Contains settings for operating system components.</string></strings>