Atlas
Atlas copied to clipboard
[FEATURE] - Disable auto start for additional apps
What is your feature request regarding to?
Atlas Playbook
Is your feature request related to a problem? Please describe.
Automatically disable the auto start and background services for all of the optional apps from the "Install Software.ps1" script.
Describe the solution you would like.
The install script should automatically disable all background services and auto start entries of all of the additional software the playbook offers to install.
Describe alternatives you have considered.
does not apply
Additional context.
No response
Make this optional, I like it when Steam auto starts.
@Ast3risk-ops You will still be able to enable autostart afterward. However not disabling auto start of the additional apps by default kinda goes against the philosophy of Atlas as it unnecessarily bloats the system...
Configuring apps post-install is currently not an aim of Atlas. Maybe in the future, but currently, our decision is to allow users to decide themselves. We can't prevent users from 'bloating' their own systems.
True, we cannot prevent users from bloating their own system. But it would still be nice not having to remove/disable/set-to-manual all the scheduled tasks, services and auto start items for additional software like firefox, chrome, brave, steam, ... manually. (Similar to how windows shouldn't be bloated out of the box, so shouldn't the applications).
So hopefully this can be added in the future.
True, we cannot prevent users from bloating their own system. But it would still be nice not having to remove/disable/set-to-manual all the scheduled tasks, services and auto start items for additional software like firefox, chrome, brave, steam, ... manually. (Similar to how windows shouldn't be bloated out of the box, so shouldn't the applications).
So hopefully this can be added in the future.
Most don't even give a damn. Using task manager isn't hard.
Well, that's not enough to remove all of the background services and tasks...
True, we cannot prevent users from bloating their own system. But it would still be nice not having to remove/disable/set-to-manual all the scheduled tasks, services and auto start items for additional software like firefox, chrome, brave, steam, ... manually. (Similar to how windows shouldn't be bloated out of the box, so shouldn't the applications).
So hopefully this can be added in the future.
Services are usually related to automatic/standard updates of those apps
True, we cannot prevent users from bloating their own system. But it would still be nice not having to remove/disable/set-to-manual all the scheduled tasks, services and auto start items for additional software like firefox, chrome, brave, steam, ... manually. (Similar to how windows shouldn't be bloated out of the box, so shouldn't the applications). So hopefully this can be added in the future.
Services are usually related to automatic/standard updates of those apps
what do you suggest in this case one should do, go 1 by 1 of these apps and do it manually?
I'd suggest to disable all of the auto updaters scheduled tasks and services. Including potential UAC bypass (I.E. silent elevation) ones.
AND to provide a simple update everything script together with all of the other scripts. The update everything script could reuse the logic of the app installation aka. winget.
That way there are no background updates causing unexpected CPU spikes as well as no unexpected behavior at normal use. And having that update everything script will provide a good compromise for security as it'll allow the users to easily check and update everything. Including the stuff that doesn't have automated updating capabilities.
This will basically cause the update mechanism of everything to rely on winget (as it already should to begin with tbh) and will be similar to the one on other systems with e.g. apt-get.
We also could provide the option to invoke the automated updating script on a schedule too. However because of the issue with winget currently not automatically dropping privileges for setups that (claim to) not support elevation we'd have to create two scheduled tasks. One running with elevation (and as probably also desirably as system to hide any accidental UI even though we'd do winget upgrade --all --disable-interactivity --silent --accept-package-agreements there could still be surprise UIs that would/could cause an EoP vulnerability if we trigger it privileged [for a non privileged user]. By running it as system we move that into Session0 where MS already took care of this by not allowing interacting with it and not showing it to the user) and another one within user context and without elevation that would only update all of the things that do not want to be upgraded with elevation (or are installed as user-install and not for AllUsers).
This probably sounds more complicated than it actually is. Basically it'd be two scheduled tasks that invoke winget with two different sets of parameters. And one runs as system and another one for each user.
However my desired setup would be no such scheduled task and having the user (me) manually trigger an update. I.E. Just the initially mentioned script. I could then spawns two winget instances to update everything (one elevated and one not, at least until that bug about it not automatically dropping elevation for setups that claim to not support it is fixed). For this it would be enough to do both within user context (and skip trying to start the elevated one if the current user doesn't have administrative privileges). For this setup there would not be a need to consider the above Session0 and EoP risk, as we're not launching anything using a different user and windows itself will already take care of securing elevated processes adequately (at least as far as we care about it).
The two winget commands would be:
- Elevated:
winget upgrade --all --disable-interactivity --silent --accept-package-agreements --accept-source-agreements --scope machine(setting the scope to machine will exclude all single-user installs and thereby also all withElevationRequirement: elevationProhibitedas combining it withScope: machinewouldn't work anyway) - AsLimited:
winget upgrade --all --disable-interactivity --silent --accept-package-agreements --accept-source-agreements --scope user
And an additional to output a table of everything that MAY have an update: winget.exe list --upgrade-available --include-unknown --include-pinned this one is mainly for stuff that the user themself installed, as everything we install is already through winget and therefoer won't be unknown nor pinned (as we don't pin anything in winget). However when we provide an update script it kinda also would be nice to show a summary of what we did NOT update. Either because of missing (unknown) version info or because the user themselves pinned it (and may forgot about it by now).
And the update script (for the manual update case) could literally be just AtlasDesktop/1. Software/Update-Software.cmd:
@echo off
set "script=%windir%\AtlasModules\Scripts\ScriptWrappers\UpdateSoftware.ps1"
if not exist "%script%" (
echo Script not found.
echo %script%
exit /b 1
)
powershell -EP Bypass -NoP Unblock-File -Path """$env:script""" -EA 0; ^& """$env:script""" %*
and AtlasModules\Scripts\ScriptWrappers\UpdateSoftware.ps1:
Param(
[Switch]$Wait = $true,
[Switch]$AlwaysElevate
)
& "$env:windir\AtlasModules\Scripts\wingetCheck.cmd"
if ($LASTEXITCODE -ne '0') {exit 1}
$ErrorActionPreference = 'SilentlyContinue'
[bool]$isElevated = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
# $isElevated indicates if we are Elevated. In this case we'll NOT run the Limited user steps and ONLY run the machine/AllUser ones.
[bool]$canElevate = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).HasClaim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid", "S-1-5-32-544") -or $AlwaysElevate
# $canElevate indicates if the user is able to elevate without changing user contexts (e.g. without a password prompt and as themselve)
# $canElevate will also be $false if we are already elevated e.g. when $isElevated = $true, as an elevated user cannot elevate (again).
# $canElevate is forced to $true if we're executed with the `-Alwayselevate` Parameter and the UAC will be shown regardless of the user needing to enter credentials of a different user in order to elevate.
# Note: Three edge cases are currently not handled. 1) UAC is disabled entirely then the username+password uac prompt won't be shown even if we try to elevate. 2) A shim forces us to run without elevation, the UAC prompt won't be shown but we'll try to run the elevated commands and fail 3) We do not check the secpol settings for UAC, technically even if the user is administrator triggering the UAC could cause the username+password instead of approver mode one.
if (-not $iselevated) {
if (-not $canElevate) {
"User cannot elevate, continuing with user scoped update only" | Write-Warning
} else {
# Self elevate and wait for completion of machine/AllUser stage.
Start-Process -FilePath "winget.exe" -UseNewEnvironment -Verb RunAs -Wait
# TODO: We do NOT exit the script here, as we'll have to run some things unelevated as well (and it's simpler to do this after the elevated self terminated, as we won't have to drop privileges within it then)
# FIXME: However the dropping permissions approach would be more desirable as that would allow us to show the console output of all winget invocations in one single window. I.E. the user could "scroll up"
# I've created a feature request to get an additional flag for Start-Process to do this, so that we do not have to write the dropping privileges part ourselves (e.g. using PInvoke and Token manipulation). See https://github.com/PowerShell/PowerShell/issues/21225 for details
}
}
# Depending on $isElevated we're going to run either the machine/AllUsers or currentUser stage.
# This is mainly required because of winget allowing apps to reject Elevation and thereby fail to update when we try to do it elevated anyway.
if ($isElevated) {
# Scope Machine/AllUsers
Start-Process -FilePath "winget.exe" -NoNewWindow -LoadUserProfile -WorkingDirectory $PWD -ArgumentList @("upgrade", "--all", "--disable-interactivity", "--silent", "--accept-package-agreements", "--accept-source-agreements", "--scope", "machine") -Wait
} else {
# Scope (current) User
Start-Process -FilePath "winget.exe" -NoNewWindow -LoadUserProfile -WorkingDirectory $PWD -ArgumentList @("upgrade", "--all", "--disable-interactivity", "--silent", "--accept-package-agreements", "--accept-source-agreements", "--scope", "user") -Wait
# Because currently the user won't be able to "just scroll up" in this terminal to see both winget invocations (the admin one will be in a separate window and exit once completed or failed without allowing to see its output)
# we're going to query for all outstanding updates so that the user has some idea of weather or not manual actions are required.
# NOTE: This will run as limited user therefore it'll also run after the Machien/AllUser winget stage has returned.
# This also will be the final command we execute and therefore it'll also be our "final summary".
"Still pending updates. Manual steps may be required:" | Write-Host
Start-Process -FilePath "winget.exe" -NoNewWindow -LoadUserProfile -WorkingDirectory $PWD -ArgumentList @("list", "--upgrade-available", "--include-pinned", "--include-unknown") -Wait
if ($Wait) {
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}
}
Although this could be useful for some users, having an 'Update all software' script would cause issues, as some Winget manifests are sometimes broken or otherwise don't install properly for some apps, so I'd rather not have Atlas blamed for that.
However, turning off auto-updating for critical apps like browsers is something other than what Atlas would do. They're essential for security and many users realistically don't check the Atlas folder or update manually.
Turning off background services for other apps in the software install script would be too much to maintain realistically and likely break functionality.
For these reasons, I'm going to close the issue, but maybe in the future, apps can be configured in other ways.