[GPO; Enterprise] Updater policies (#24221)

* Implement GPO

* Add GPOs in updater

* Rename policy

* fix

* fix

* Update GPOWrapper.h

Added relative path to Generated Files folder for GPOWrapper.g.h

* fix and inactivate PeriodicUpdateCheck gpo

* Docs

* GPO name change

* Templates

* Templates: Text changes

* Templates: Text changes

* Templates: Text changes

* docs: spell fix

* settings ui

* fixes

* fixes

* fix gpo description

* EOF fix

* Fix include in UpdateUtils.cpp and remove build workaround

* UI improvements

* spell fixes

* code improvements

* Update README.md

* Update PowerToys.adml

* Update src/gpo/assets/PowerToys.admx

* Remove forbidden pattern
This commit is contained in:
Heiko 2023-02-24 15:35:33 +01:00 committed by GitHub
parent 0524a4bddd
commit 6750442d91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 201 additions and 15 deletions

View File

@ -39,3 +39,35 @@ This policy configures whether PowerToys experimentation is allowed. With experi
If this setting is not configured or enabled, the user can control experimentation in the PowerToys settings menu.
If this setting is disabled, experimentation is not allowed.
If this setting is not configured, experimentation is allowed.
### Installer and Updates
#### Disable automatic downloads
This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.)
If enabled, automatic downloads are disabled.
If disabled or not configured, the user is in control of automatic downloads setting.
#### Suspend Action Center notification for new updates
This policy configures whether the action center notification for new updates is suspended for 2 minor releases. (Example: if the installed version is v0.60.0, then the next notification is shown for the v0.63.* release.)
If enabled, the notification is suspended.
If disabled or not configured, the notification is shown.
Note: The notification about new major versions is always displayed.
<!-- This policy is implemented for later usage (PT v1.0 and later) and therefore inactive. (To make it working please update `src/runner/UpdateUtils.cpp`)
#### Disable automatic update checks
This policy allows you to disable automatic update checks running in the background. (The manual check in PT Settings is not affected by this policy.)
If enabled, the automatic update checks are disabled.
If disabled or not configured, the automatic update checks are enabled.
-->

View File

@ -120,6 +120,10 @@ namespace winrt::PowerToys::GPOWrapper::implementation
{
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredVideoConferenceMuteEnabledValue());
}
GpoRuleConfigured GPOWrapper::GetDisableAutomaticUpdateDownloadValue()
{
return static_cast<GpoRuleConfigured>(powertoys_gpo::getDisableAutomaticUpdateDownloadValue());
}
GpoRuleConfigured GPOWrapper::GetAllowExperimentationValue()
{
return static_cast<GpoRuleConfigured>(powertoys_gpo::getAllowExperimentationValue());

View File

@ -36,6 +36,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation
static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue();
static GpoRuleConfigured GetConfiguredPastePlainEnabledValue();
static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue();
static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue();
static GpoRuleConfigured GetAllowExperimentationValue();
};
}

View File

@ -40,6 +40,7 @@ namespace PowerToys
static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue();
static GpoRuleConfigured GetConfiguredPastePlainEnabledValue();
static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue();
static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue();
static GpoRuleConfigured GetAllowExperimentationValue();
}
}

View File

@ -48,6 +48,13 @@ namespace powertoys_gpo {
const std::wstring POLICY_CONFIGURE_ENABLED_TEXT_EXTRACTOR = L"ConfigureEnabledUtilityTextExtractor";
const std::wstring POLICY_CONFIGURE_ENABLED_PASTE_PLAIN = L"ConfigureEnabledUtilityPastePlain";
const std::wstring POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE = L"ConfigureEnabledUtilityVideoConferenceMute";
// The registry value names for PowerToys installer and update policies.
const std::wstring POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD = L"AutomaticUpdateDownloadDisabled";
const std::wstring POLICY_SUSPEND_NEW_UPDATE_TOAST = L"SuspendNewUpdateAvailableToast";
const std::wstring POLICY_DISABLE_PERIODIC_UPDATE_CHECK = L"PeriodicUpdateCheckDisabled";
// The registry value names for other PowerToys policies.
const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation";
inline gpo_rule_configured_t getConfiguredValue(const std::wstring& registry_value_name)
@ -248,6 +255,21 @@ namespace powertoys_gpo {
return getConfiguredValue(POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE);
}
inline gpo_rule_configured_t getDisableAutomaticUpdateDownloadValue()
{
return getConfiguredValue(POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD);
}
inline gpo_rule_configured_t getSuspendNewUpdateToastValue()
{
return getConfiguredValue(POLICY_SUSPEND_NEW_UPDATE_TOAST);
}
inline gpo_rule_configured_t getDisablePeriodicUpdateCheckValue()
{
return getConfiguredValue(POLICY_DISABLE_PERIODIC_UPDATE_CHECK);
}
inline gpo_rule_configured_t getAllowExperimentationValue()
{
return getConfiguredValue(POLICY_ALLOW_EXPERIMENTATION);

View File

@ -13,7 +13,9 @@
</definitions>
</supportedOn>
<categories>
<category name="PowerToys" displayName="$(string.PowerToys)">
<category name="PowerToys" displayName="$(string.PowerToys)" />
<category name="InstallerUpdates" displayName="$(string.InstallerUpdates)">
<parentCategory ref="PowerToys" />
</category>
</categories>
<policies>
@ -307,6 +309,38 @@
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DisableAutomaticUpdateDownload" class="Both" displayName="$(string.DisableAutomaticUpdateDownload)" explainText="$(string.DisableAutomaticUpdateDownloadDescription)" key="Software\Policies\PowerToys" valueName="AutomaticUpdateDownloadDisabled">
<parentCategory ref="InstallerUpdates" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_68_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="SuspendNewUpdateToast" class="Both" displayName="$(string.SuspendNewUpdateToast)" explainText="$(string.SuspendNewUpdateToastDescription)" key="Software\Policies\PowerToys" valueName="SuspendNewUpdateAvailableToast">
<parentCategory ref="InstallerUpdates" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_68_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<!-- This policy is implemented for later usage (PT v1.0 and later) and therefore inactive. (To make it working please update `src/runner/UpdateUtils.cpp`)
<policy name="DisablePeriodicUpdateCheck" class="Both" displayName="$(string.DisablePeriodicUpdateCheck)" explainText="$(string.DisablePeriodicUpdateCheckDescription)" key="Software\Policies\PowerToys" valueName="PeriodicUpdateCheckDisabled">
<parentCategory ref="InstallerUpdates" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_68_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
-->
<policy name="AllowExperimentation" class="Both" displayName="$(string.AllowExperimentation)" explainText="$(string.AllowExperimentationDescription)" key="Software\Policies\PowerToys" valueName="AllowExperimentation">
<parentCategory ref="PowerToys" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_68_0" />

View File

@ -7,6 +7,7 @@
<resources>
<stringTable>
<string id="PowerToys">Microsoft PowerToys</string>
<string id="InstallerUpdates">Installer and Updates</string>
<string id="SUPPORTED_POWERTOYS_0_64_0">PowerToys version 0.64.0 or later</string>
<string id="SUPPORTED_POWERTOYS_0_68_0">PowerToys version 0.68.0 or later</string>
@ -28,6 +29,26 @@ If you enable this setting, the utility will be always enabled and the user won'
If you disable this setting, the utility will be always disabled and the user won't be able to enable it.
If you don't configure this setting, users are able to disable or enable the utility.
</string>
<string id="DisableAutomaticUpdateDownloadDescription">This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.)
If enabled, automatic downloads are disabled.
If disabled or not configured, the user is in control of automatic downloads setting.
</string>
<string id="SuspendNewUpdateToastDescription">This policy configures whether the action center notification for new updates is suspended for 2 minor releases. (Example: if the installed version is v0.60.0, then the next notification is shown for the v0.63.* release.)
If enabled, the notification is suspended.
If disabled or not configured, the notification is shown.
Note: The notification about new major versions is always displayed.
</string>
<string id="DisablePeriodicUpdateCheckDescription">This policy allows you to disable automatic update checks running in the background. (The manual check in PT Settings is not affected by this policy.)
If enabled, the automatic update checks are disabled.
If disabled or not configured, the automatic update checks are enabled.
</string>
<string id="AllowExperimentationDescription">This policy configures whether PowerToys experimentation is allowed. With experimentation allowed the user sees the new features being experimented if it gets selected as part of the test group. (Experimentation will only happen on Windows Insider builds.)
@ -64,6 +85,9 @@ If this setting is disabled, experimentation is not allowed.
<string id="ConfigureEnabledUtilityShortcutGuide">Shortcut Guide: Configure enabled state</string>
<string id="ConfigureEnabledUtilityTextExtractor">Text Extractor: Configure enabled state</string>
<string id="ConfigureEnabledUtilityVideoConferenceMute">Video Conference Mute: Configure enabled state</string>
<string id="DisableAutomaticUpdateDownload">Disable automatic downloads</string>
<string id="SuspendNewUpdateToast">Suspend Action Center notification for new updates</string>
<string id="DisablePeriodicUpdateCheck">Disable automatic update checks</string>
<string id="AllowExperimentation">Allow Experimentation</string>
</stringTable>
</resources>

View File

@ -6,6 +6,7 @@
#include "general_settings.h"
#include "UpdateUtils.h"
#include <common/utils/gpo.h>
#include <common/logger/logger.h>
#include <common/notifications/notifications.h>
#include <common/updating/installer.h>
@ -21,6 +22,10 @@ namespace
{
constexpr int64_t UPDATE_CHECK_INTERVAL_MINUTES = 60 * 24;
constexpr int64_t UPDATE_CHECK_AFTER_FAILED_INTERVAL_MINUTES = 60 * 2;
// How many minor versions to suspend the toast notification (example: installed=0.60.0, suspend=2, next notification=0.63.*)
// Attention: When changing this value please update the ADML file to.
const int UPDATE_NOTIFICATION_TOAST_SUSPEND_MINOR_VERSION_COUNT = 2;
}
using namespace notifications;
using namespace updating;
@ -113,7 +118,7 @@ bool IsMeteredConnection()
void ProcessNewVersionInfo(const github_version_info& version_info,
UpdateState& state,
const bool download_update,
const bool show_notifications)
bool show_notifications)
{
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
if (std::holds_alternative<version_up_to_date>(version_info))
@ -135,6 +140,22 @@ void ProcessNewVersionInfo(const github_version_info& version_info,
return;
}
// Check notification GPO.
// We check only if notifications are allowed. This is the case if we are triggered by the periodic check.
if (show_notifications && powertoys_gpo::getSuspendNewUpdateToastValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
Logger::info(L"GPO to suspend new update toast notification is enabled.");
if (new_version_info.version.major <= VERSION_MAJOR && new_version_info.version.minor - VERSION_MINOR <= UPDATE_NOTIFICATION_TOAST_SUSPEND_MINOR_VERSION_COUNT)
{
Logger::info(L"The difference between the installed version and the newer version is within the allowed period. The toast notification is not shown.");
show_notifications = false;
}
else
{
Logger::info(L"The installed version is older than allowed for suspending the toast notification. The toast notification is shown.");
}
}
if (download_update)
{
Logger::trace(L"Downloading installer for a new version");
@ -168,6 +189,14 @@ void ProcessNewVersionInfo(const github_version_info& version_info,
void PeriodicUpdateWorker()
{
// Check if periodic update check is disabled by GPO.
// This policy code is implemented but not active. It is for later usage in PT version after 1.0 release.
//if (powertoys_gpo::getDisablePeriodicUpdateCheckValue() == powertoys_gpo::gpo_rule_configured_enabled)
//{
// Logger::info(L"Initialization of periodic update checks stopped. Periodic update checks are disabled by GPO.");
// return;
//}
for (;;)
{
auto state = UpdateState::read();
@ -184,7 +213,14 @@ void PeriodicUpdateWorker()
std::this_thread::sleep_for(std::chrono::minutes{ sleep_minutes_till_next_update });
const bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
// Auto download setting.
bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
if (powertoys_gpo::getDisableAutomaticUpdateDownloadValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
Logger::info(L"Automatic download of updates is disabled by GPO.");
download_update = false;
}
bool version_info_obtained = false;
try
{
@ -230,7 +266,15 @@ void CheckForUpdatesCallback()
new_version_info = version_up_to_date{};
Logger::error(L"Couldn't obtain version info from github: {}", new_version_info.error());
}
const bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
// Auto download setting
bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
if (powertoys_gpo::getDisableAutomaticUpdateDownloadValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
Logger::info(L"Automatic download of updates is disabled by GPO.");
download_update = false;
}
ProcessNewVersionInfo(*new_version_info, state, download_update, false);
UpdateState::store([&](UpdateState& v) {
v = std::move(state);

View File

@ -3040,4 +3040,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Enable Mouse Jump</value>
<comment>"Mouse Jump" is the name of the utility.</comment>
</data>
<data name="GPO_AutoDownloadUpdatesIsDisabled.Title" xml:space="preserve">
<value>The system administrator has disabled the automatic download of updates.</value>
</data>
</root>

View File

@ -142,6 +142,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_updateCheckedDate = UpdatingSettingsConfig.LastCheckedDateLocalized;
_experimentationIsGpoDisallowed = GPOWrapper.GetAllowExperimentationValue() == GpoRuleConfigured.Disabled;
_autoDownloadUpdatesIsGpoDisabled = GPOWrapper.GetDisableAutomaticUpdateDownloadValue() == GpoRuleConfigured.Enabled;
if (dispatcherAction != null)
{
@ -156,6 +157,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private int _themeIndex;
private bool _autoDownloadUpdates;
private bool _autoDownloadUpdatesIsGpoDisabled;
private bool _enableExperimentation;
private bool _experimentationIsGpoDisallowed;
@ -272,11 +274,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
// Are we running a dev build? (Please note that we verify this in the code that gets the newest version from GitHub too.)
public static bool AutoUpdatesDisabledOnDevBuild
{
get
{
return Helper.GetProductVersion() == "v0.0.1";
}
}
public bool AutoDownloadUpdates
{
get
{
return _autoDownloadUpdates;
return _autoDownloadUpdates && !_autoDownloadUpdatesIsGpoDisabled;
}
set
@ -290,6 +301,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
public bool IsAutoDownloadUpdatesCardEnabled
{
get => !AutoUpdatesDisabledOnDevBuild && !_autoDownloadUpdatesIsGpoDisabled;
}
// The settings card is hidden for users who are not a member of the Administrators group and in this case the GPO info should be hidden too.
// We hide it, because we don't want a normal user to enable the setting. He can't install the updates.
public bool ShowAutoDownloadUpdatesGpoInformation
{
get => _isAdmin && _autoDownloadUpdatesIsGpoDisabled;
}
public bool EnableExperimentation
{
get
@ -313,14 +336,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
get => _experimentationIsGpoDisallowed;
}
public static bool AutoUpdatesEnabled
{
get
{
return Helper.GetProductVersion() != "v0.0.1";
}
}
public string SettingsBackupAndRestoreDir
{
get
@ -659,7 +674,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
get
{
return AutoUpdatesEnabled && !IsNewVersionDownloading;
return !AutoUpdatesDisabledOnDevBuild && !IsNewVersionDownloading;
}
}

View File

@ -190,12 +190,18 @@
<labs:SettingsCard
x:Uid="GeneralPage_ToggleSwitch_AutoDownloadUpdates"
Margin="0,-6,0,0"
IsEnabled="{Binding AutoUpdatesEnabled}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsAutoDownloadUpdatesCardEnabled}"
Visibility="{Binding Mode=OneWay, Path=IsAdmin, Converter={StaticResource BoolToVisibilityConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{Binding Mode=TwoWay, Path=AutoDownloadUpdates}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_AutoDownloadUpdatesIsDisabled"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.ShowAutoDownloadUpdatesGpoInformation}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.ShowAutoDownloadUpdatesGpoInformation}"
Severity="Informational" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Admin_Mode">