Supprimer les paramètres de stratégie obsolètes après une mise à niveau

Dernière publication : Nov 13, 2026
Lorsqu'un composant produit est déprécié par Citrix®, ses paramètres de stratégie associés deviennent invalides. Utilisez GpoClean.ps1 pour identifier et supprimer ces paramètres obsolètes des stratégies Citrix Virtual Apps and Desktops™ après une mise à niveau, y compris toutes les stratégies qui deviennent vides en conséquence.

Avant de commencer

Assurez-vous de respecter les exigences suivantes avant d'exécuter le script :
  • Une version prise en charge de Citrix Virtual Apps and Desktops avec Broker SDK et Group Policy Management installés
  • Autorisations d'administration des stratégies Citrix sur un Delivery Controller™
Remarque :
Le script charge automatiquement les composants logiciels enfichables Citrix.Broker.Admin.V2 et Citrix.Common.GroupPolicy.

Supprimer les paramètres de stratégie obsolètes

Exécutez GpoClean.ps1 pour supprimer les paramètres de stratégie obsolètes :
  1. Copiez GpoClean.ps1 sur un Delivery Controller sur lequel vous disposez des autorisations d'administration des stratégies Citrix.
  2. Ouvrez une session PowerShell sur le Delivery Controller.
  3. Exécutez le script. Aucun paramètre n'est requis.
    .\GpoClean.ps1
    Remarque :
    Ajoutez -Verbose pour une journalisation détaillée par paramètre : .\GpoClean.ps1 -Verbose.
Le script s'exécute en deux phases :
Phase Ce qui se passe
Phase 1 Exécute Test-BrokerDesktopPolicy, identifie les erreurs DeprecatedSetting et définit chaque paramètre affecté sur NotConfigured
Phase 2 Réexécute Test-BrokerDesktopPolicy, identifie les stratégies sans paramètres configurés (PolicyHasNoSettings) et les supprime
Toutes les modifications sont enregistrées en une seule opération d'écriture. Un résumé indique le nombre de paramètres et de stratégies supprimés. Si aucun paramètre obsolète n'est trouvé, le script se termine sans aucune modification.
Remarque :
  • La stratégie Unfiltered n'est jamais supprimée, même si elle ne contient aucun paramètre configuré.

Script

Enregistrez le contenu suivant sous GpoClean.ps1, puis exécutez-le comme décrit dans Supprimer les paramètres de stratégie obsolètes :
<#
.Synopsis

    Cleans up deprecated settings from Citrix policies and removes policies that no longer have any settings.

.Description

    This script runs Test-BrokerDesktopPolicy to identify deprecated settings in policies. When a setting is
    deprecated (DeprecatedSetting error), the script removes the setting from the policy using the Citrix Group Policy
    PowerShell Provider. After removing deprecated settings, if a policy has no settings remaining
    (PolicyHasNoSettings error), the policy is removed automatically, except for the 'Unfiltered' policy which is
    preserved.

    This script is useful for cleaning up policies after upgrading to a newer version where some settings have been
    deprecated.

.Requirements

    Run this script on a DDC that has the Citrix Group Policy Management and Citrix Broker SDK installed.
#>

[CmdletBinding()]
param()

Write-Host "Checking Citrix policies for deprecated settings..."

# Load the Citrix Broker PowerShell Snapin.
$BrokerSnapin = "Citrix.Broker.Admin.V2"
$loaded = Get-PSSnapin $BrokerSnapin -ErrorAction SilentlyContinue
if ($loaded -eq $null)
{
    Add-PSSnapin $BrokerSnapin
}

# First pass: Run Test-BrokerDesktopPolicy to check for errors.
Write-Host "Running policy validation..."
$testResults = Test-BrokerDesktopPolicy | Select-Object -Property *

if ($testResults -eq $null -or $testResults.Count -eq 0)
{
    Write-Host "No policy errors found. All policies are clean."
    exit 0
}

# Check if there are any DeprecatedSetting errors.
$hasDeprecatedSettings = $false
foreach ($result in $testResults)
{
    if ([string]$result.ErrorCode -eq 'DeprecatedSetting')
    {
        $hasDeprecatedSettings = $true
        break
    }
}

if (-not $hasDeprecatedSettings)
{
    Write-Host "No deprecated settings found. Policy errors exist but do not require cleaning."
    Write-Host "Run 'Test-BrokerDesktopPolicy' to see other policy issues."
    exit 0
}

# Load the Citrix Group Policy PowerShell Provider (only if we need to clean).
Write-Host "`nDeprecated settings found. Loading Group Policy provider for cleanup..."
$GpSnapin = "Citrix.Common.GroupPolicy"
$Provider = "CitrixGroupPolicy"
$SiteName = "CitrixGP"

$loaded = Get-PSSnapin $GpSnapin -ErrorAction SilentlyContinue
if ($loaded -eq $null)
{
    Add-PSSnapin $GpSnapin
}

# Mount the provider drive if it has not been mounted.
$GpDrive = Get-PSDrive $SiteName -ErrorAction SilentlyContinue
if ($GpDrive -eq $null)
{
    [void]($GpDrive = New-PSDrive -PSProvider $Provider -Name $SiteName -Root \ -Controller localhost)
}

$uRoot = $SiteName + ":\User\"
$cRoot = $SiteName + ":\Computer\"

$GpDrive.AutoWriteBack = $false

$settingsRemoved = 0
$policiesRemoved = 0

$settingNameMappings = @{
    'PvsIntegrationEnabled' = 'ImageProviderIntegrationEnabled'
}

function Remove-SettingFromPolicy
{
    param(
        [string] $policyName,
        [string] $settingName
    )

    $targetSettingName = Split-Path -Path $settingName -Leaf

    if ($settingNameMappings.ContainsKey($targetSettingName))
    {
        $mappedSettingName = $settingNameMappings[$targetSettingName]
        Write-Verbose "Mapping deprecated setting name '$targetSettingName' to '$mappedSettingName'"
        $targetSettingName = $mappedSettingName
    }

    $searchPattern = $SiteName + ":\" + "*\" + $policyName + "\Settings\*"
    Write-Verbose "Searching for settings matching '$targetSettingName' in policy '$policyName'..."
    $allSettings = Get-ChildItem -Path $searchPattern -Recurse -ErrorAction SilentlyContinue |
        Where-Object {
            ($_.PSObject.Properties['State'] -and $_.State -ne 'NotConfigured') -or
            ($_.Name -eq 'Values' -and $_.Values -ne $null -and $_.Values -ne '')
        }

    $found = $false
    foreach ($setting in $allSettings)
    {
        $RootPath = "{0}\{1}::{2}:" -f $GpSnapin, $Provider, $SiteName
        $relativePath = $setting.PSPath.Substring($RootPath.Length)
        Write-Verbose "  Checking configured setting: $relativePath"
        $currentSettingName = Split-Path -Path $setting.PSPath -Leaf
        if ($currentSettingName -ne $targetSettingName) { continue }
        Write-Verbose "  Found matching setting: $relativePath"
        Set-ItemProperty -Path $setting.PSPath -Name State -Value NotConfigured
        Write-Host "  Set setting '$relativePath' to NotConfigured"
        $Script:settingsRemoved++
        $found = $true
    }

    if (-not $found)
    {
        Write-Warning "Could not find setting '$targetSettingName' in policy '$policyName'"
    }
}

function Remove-PolicyByName
{
    param(
        [string] $policyName
    )

    if ($policyName -eq 'Unfiltered')
    {
        Write-Host "  Skipping removal of 'Unfiltered' policy (reserved policy)"
        return
    }

    $uPath = $uRoot + $policyName
    $cPath = $cRoot + $policyName

    if (Test-Path $uPath)
    {
        $uSettings = Get-ChildItem -Path ($uPath + "\Settings") -Recurse -ErrorAction SilentlyContinue |
            Where-Object {
                ($_.PSObject.Properties['State'] -and $_.State -ne 'NotConfigured') -or
                ($_.Name -eq 'Values' -and $_.Values -ne $null -and $_.Values -ne '')
            }
        if ($uSettings.Count -eq 0)
        {
            Remove-Item -Path $uPath -Force -Recurse
            Write-Host "  Removed policy: \User\$policyName"
            $Script:policiesRemoved++
        }
    }

    if (Test-Path $cPath)
    {
        $cSettings = Get-ChildItem -Path ($cPath + "\Settings") -Recurse -ErrorAction SilentlyContinue |
            Where-Object {
                ($_.PSObject.Properties['State'] -and $_.State -ne 'NotConfigured') -or
                ($_.Name -eq 'Values' -and $_.Values -ne $null -and $_.Values -ne '')
            }
        if ($cSettings.Count -eq 0)
        {
            Remove-Item -Path $cPath -Force -Recurse
            Write-Host "  Removed policy: \Computer\$policyName"
            $Script:policiesRemoved++
        }
    }
}

# Phase 1: Remove deprecated settings.
Write-Host "`nPhase 1: Removing deprecated settings (this may take some time)..."
foreach ($result in $testResults)
{
    if ([string]$result.ErrorCode -eq 'DeprecatedSetting')
    {
        Write-Host "`nPolicy '$($result.PolicyName)' has deprecated settings:"
        if ($result.Settings -ne $null)
        {
            foreach ($setting in $result.Settings)
            {
                Write-Host "  - Setting '$($setting.SettingName)' is deprecated"
                Remove-SettingFromPolicy -policyName $result.PolicyName -settingName $setting.SettingName
            }
        }
    }
}

# Phase 2: Remove empty policies.
Write-Host "`nPhase 2: Checking for policies with no settings..."
$testResults2 = Test-BrokerDesktopPolicy | Select-Object -Property *

if ($testResults2 -eq $null -or $testResults2.Count -eq 0)
{
    Write-Host "No policy errors found."
}
else
{
    foreach ($result in $testResults2)
    {
        if ([string]$result.ErrorCode -eq 'PolicyHasNoSettings')
        {
            Write-Host "`nPolicy '$($result.PolicyName)' has no settings remaining:"
            Remove-PolicyByName -policyName $result.PolicyName
        }
    }
}

# Save all changes.
if ($settingsRemoved -gt 0 -or $policiesRemoved -gt 0)
{
    Write-Host "`nSaving changes..."
    $GpDrive.Save()
}

Remove-PSDrive $SiteName

Write-Host "`n=========================================="
Write-Host "Policy Cleanup Summary:"
Write-Host "  Settings removed: $settingsRemoved"
Write-Host "  Policies removed: $policiesRemoved"
Write-Host "=========================================="

if ($settingsRemoved -eq 0 -and $policiesRemoved -eq 0)
{
    Write-Host "`nNo issues found. All policies are clean."
}
else
{
    Write-Host "`nCleanup completed successfully."
}

exit 0

Contenu associé

Pour plus d'informations sur les paramètres obsolètes dans chaque version, consultez Modifications de stratégie.