Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GPO] Add GPO to disable per-user install #25141

Merged
merged 29 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
65a7b88
Add per user installer
stefansjfw Jan 18, 2023
14f36cb
Separate upgrade codes for per machine and per user installation
stefansjfw Feb 8, 2023
a2eac05
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Feb 22, 2023
03ea420
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 7, 2023
34545da
Update installer/PowerToysSetup/generateFileList.ps1
stefansjfw Mar 7, 2023
f44ccca
Update installer/PowerToysSetup/generateAllFileComponents.ps1
stefansjfw Mar 7, 2023
4ba537d
Update installer/PowerToysSetup/generateFileList.ps1
stefansjfw Mar 7, 2023
9bc160f
expect.txt
stefansjfw Mar 7, 2023
68b2f57
Revert "Update installer/PowerToysSetup/generateFileList.ps1"
stefansjfw Mar 7, 2023
30af633
Update release CI to build both installers
stefansjfw Feb 23, 2023
8fc9014
Revert bundle name change
stefansjfw Mar 14, 2023
665a306
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 21, 2023
7235d87
spellcheck
stefansjfw Mar 21, 2023
7d983db
Fix bad merge
stefansjfw Mar 24, 2023
bf0e514
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 27, 2023
7357213
Add RegistryPreview
stefansjfw Mar 27, 2023
29ce624
Include backup_restore_settings.json
stefansjfw Mar 27, 2023
5373de9
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 28, 2023
2512cbf
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 29, 2023
98d3233
Merge remote-tracking branch 'origin/main' into stefan/per_user_instal
stefansjfw Mar 30, 2023
01f83f4
Revert testing endpoint change
stefansjfw Mar 30, 2023
b56cb47
Add per-machine/per-user installation GPOs
stefansjfw Mar 31, 2023
680a28b
Merge remote-tracking branch 'origin/main' into stefan/per_user_gpo
stefansjfw Mar 31, 2023
d7fa079
Update doc/gpo/README.md
stefansjfw Mar 31, 2023
1327742
Update doc/gpo/README.md
stefansjfw Mar 31, 2023
3d468fd
spellcheck
stefansjfw Mar 31, 2023
a171e1d
Merge branch 'stefan/per_user_gpo' of github.com:microsoft/PowerToys …
stefansjfw Mar 31, 2023
5c6392c
Remove disable per-machine policy
stefansjfw Mar 31, 2023
796ca21
Update doc/gpo/README.md
stefansjfw Mar 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion doc/gpo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ If this setting is not configured, experimentation is allowed.

### Installer and Updates

#### Disable per-machine installation
stefansjfw marked this conversation as resolved.
Show resolved Hide resolved

This policy configures whether PowerToys per-machine installation is allowed or not.

If enabled, per-machine installation is not allowed.

If disabled or not configured, per-machine installation is allowed.

#### Disable per-user installation

This policy configures whether PowerToys per-user installation is allowed or not.

If enabled, per-user installation is not allowed.

If disabled or not configured, per-user installation is allowed.

stefansjfw marked this conversation as resolved.
Show resolved Hide resolved
#### Disable automatic downloads

This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.)
Expand All @@ -54,7 +70,7 @@ If disabled or not configured, the user is in control of automatic downloads set

#### 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.)
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.)
stefansjfw marked this conversation as resolved.
Show resolved Hide resolved

If enabled, the notification is suspended.

Expand Down
10 changes: 10 additions & 0 deletions installer/PowerToysSetup/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
<Custom Action="RegisterPowerToysSchTask" After="InstallFiles">
NOT Installed and CREATESCHEDULEDTASK = 1
</Custom>
<Custom Action="CheckGPO" After="InstallInitialize">
NOT Installed
</Custom>
<Custom Action="ApplyModulesRegistryChangeSets" After="InstallFiles">
NOT Installed
</Custom>
Expand Down Expand Up @@ -413,6 +416,13 @@
DllEntry="UnRegisterContextMenuPackagesCA"
/>

<CustomAction Id="CheckGPO"
Return="check"
Impersonate="yes"
BinaryKey="PTCustomActions"
DllEntry="CheckGPOCA"
/>

<!-- Close 'PowerToys.exe' before uninstall-->
<Property Id="MSIRESTARTMANAGERCONTROL" Value="DisableShutdown" />
<Property Id="MSIFASTINSTALL" Value="DisableShutdown" />
Expand Down
38 changes: 38 additions & 0 deletions installer/PowerToysSetupCustomActions/CustomAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <spdlog/sinks/base_sink.h>

#include "../../src/common/logger/logger.h"
#include "../../src/common/utils/gpo.h"
#include "../../src/common/utils/MsiUtils.h"
#include "../../src/common/utils/modulesRegistry.h"
#include "../../src/common/updating/installer.h"
Expand Down Expand Up @@ -50,6 +51,43 @@ HRESULT getInstallFolder(MSIHANDLE hInstall, std::wstring& installationDir)
LExit:
return hr;
}

UINT __stdcall CheckGPOCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;

hr = WcaInitialize(hInstall, "CheckGPOCA");
ExitOnFailure(hr, "Failed to initialize");

LPWSTR currentScope = nullptr;
hr = WcaGetProperty(L"InstallScope", &currentScope);

if(std::wstring{ currentScope } == L"perUser")
{
if (powertoys_gpo::getDisablePerUserInstallationValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
PMSIHANDLE hRecord = MsiCreateRecord(0);
MsiRecordSetString(hRecord, 0, TEXT("The system administrator has disabled per-user installation."));
MsiProcessMessage(hInstall, static_cast<INSTALLMESSAGE>(INSTALLMESSAGE_ERROR + MB_OK), hRecord);
hr = E_ABORT;
}
}
if(std::wstring{ currentScope } == L"perMachine")
{
if (powertoys_gpo::getDisablePerMachineInstallationValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
PMSIHANDLE hRecord = MsiCreateRecord(0);
MsiRecordSetString(hRecord, 0, TEXT("The system administrator has disabled per-machine installation."));
MsiProcessMessage(hInstall, static_cast<INSTALLMESSAGE>(INSTALLMESSAGE_ERROR + MB_OK), hRecord);
hr = E_ABORT;
}
}

LExit:
UINT er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}

UINT __stdcall ApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
Expand Down
1 change: 1 addition & 0 deletions installer/PowerToysSetupCustomActions/CustomAction.def
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
LIBRARY "PowerToysSetupCustomActions"

EXPORTS
CheckGPOCA
ApplyModulesRegistryChangeSetsCA
CreateScheduledTaskCA
CreateWinAppSDKHardlinksCA
Expand Down
13 changes: 13 additions & 0 deletions src/common/utils/gpo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ namespace powertoys_gpo {
const std::wstring POLICY_CONFIGURE_ENABLED_REGISTRY_PREVIEW = L"ConfigureEnabledUtilityRegistryPreview";

// The registry value names for PowerToys installer and update policies.
const std::wstring POLICY_DISABLE_PER_MACHINE_INSTALLATION = L"PerMachineInstallationDisabled";
const std::wstring POLICY_DISABLE_PER_USER_INSTALLATION = L"PerUserInstallationDisabled";
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";
Expand Down Expand Up @@ -260,6 +262,17 @@ namespace powertoys_gpo {
{
return getConfiguredValue(POLICY_CONFIGURE_ENABLED_REGISTRY_PREVIEW);
}

inline gpo_rule_configured_t getDisablePerMachineInstallationValue()
{
return getConfiguredValue(POLICY_DISABLE_PER_MACHINE_INSTALLATION);
}

inline gpo_rule_configured_t getDisablePerUserInstallationValue()
{
return getConfiguredValue(POLICY_DISABLE_PER_USER_INSTALLATION);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a mew method that only reads HKLM? In case someone sets the value manually in registry.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, in that case, user would disable it for himself, right? So,no?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit unclear. What I mean is we have a Machine (HKLM) only policy and checking both. This means that you still manually can set it in HKCU. Not sure if this something we should prevent. 🤔

Copy link
Collaborator Author

@stefansjfw stefansjfw Mar 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that you still manually can set it in HKCU

Yes, but who can? Current user? If the current user wants to disable per-user install for himself, so be it :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. Then let's not overcomplicating thing and read both. I only want to mention it.

}

inline gpo_rule_configured_t getDisableAutomaticUpdateDownloadValue()
{
return getConfiguredValue(POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD);
Expand Down
24 changes: 22 additions & 2 deletions src/gpo/assets/PowerToys.admx
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,27 @@
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DisableAutomaticUpdateDownload" class="Both" displayName="$(string.DisableAutomaticUpdateDownload)" explainText="$(string.DisableAutomaticUpdateDownloadDescription)" key="Software\Policies\PowerToys" valueName="AutomaticUpdateDownloadDisabled">
<policy name="DisablePerMachineInstallation" class="Both" displayName="$(string.DisablePerMachineInstallation)" explainText="$(string.DisablePerMachineInstallationDescription)" key="Software\Policies\PowerToys" valueName="PerMachineInstallationDisabled">
<parentCategory ref="InstallerUpdates" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_69_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DisablePerUserInstallation" class="Both" displayName="$(string.DisablePerUserInstallation)" explainText="$(string.DisablePerUserInstallationDescription)" key="Software\Policies\PowerToys" valueName="PerUserInstallationDisabled">
stefansjfw marked this conversation as resolved.
Show resolved Hide resolved
<parentCategory ref="InstallerUpdates" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_69_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<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>
Expand All @@ -329,7 +349,7 @@
<decimal value="0" />
</disabledValue>
</policy>
<policy name="SuspendNewUpdateToast" class="Both" displayName="$(string.SuspendNewUpdateToast)" explainText="$(string.SuspendNewUpdateToastDescription)" key="Software\Policies\PowerToys" valueName="SuspendNewUpdateAvailableToast">
<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>
Expand Down
20 changes: 17 additions & 3 deletions src/gpo/assets/en-US/PowerToys.adml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ 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="DisablePerMachineInstallationDescription">This policy configures whether per-machine PowerToys installation is allowed or not.

If enabled, per-machine installation is not allowed.

If disabled or not configured, per-machine installation is allowed.
</string>
<string id="DisablePerUserInstallationDescription">This policy configures whether per-user PowerToys installation is allowed or not.

If enabled, per-user installation is not allowed.

If disabled or not configured, per-user installation is allowed.
</string>
<string id="DisableAutomaticUpdateDownloadDescription">This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.)

Expand Down Expand Up @@ -87,9 +99,11 @@ 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="DisablePerMachineInstallation">Disable per-machine installation</string>
<string id="DisablePerUserInstallation">Disable per-user installation</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>
Expand Down