cancel
Showing results for 
Search instead for 
Did you mean: 

Running Winget as System with JumpCloud Commands + winget upgrade --all --silent on User Logon

JacobLawson
Novitiate II

I've done some experimenting with automating software installs using powershell and winget.  As many of you know, one of the primary blockers to winget is the fact that it runs in the user session.  After a few hours of reading discussions on github, I came across this thread with a promising approach from rothgecw to running winget as system.  This opened up a world of possibility! 

In my testing I discovered that when winget upgrades, the old directory in C:\Program Files\WindowsApps isn't always deleted so I needed a way to find the most up to date version of winget in the WindowsApps folder.  Hence the first part of the script below.  I start by finding the directory winget is installed in, if there are multiple versions, I sort the directories by path and save the last path as a variable.  From there I write the output of the variable to the console for sanity and troubleshooting purposes so I can see the directory in the command results from within the JumpCloud admin console.  Then I cd to that directory and we are ready to start using winget as system. 

Note: winget must be installed for this to work. 

 

#Powershell script that checks if apps are installed and installs them if they aren't

#Query for directory most updated winget.exe is stored in
$wingetdir = (Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" | Sort-Object -Property Path | Select-Object -Last 1)
#Output directory
Write-Host "cd to directory: $wingetdir"
#navigate to directory containing winget.exe
cd $wingetdir

 

After navigating to the correct directory, we can pass commands to winget.  Below is an example of a powershell script that installs Adobe Acrobat Reader on a system if it isn't already installed.  I start by searching the device for the software using winget list.  Then I use an if statement to determine whether or not the software needs installed.  If the software does need installed, I pass the following command to winget for a silent install of Adobe Acrobat Reader: winget install --id 'Adobe.Acrobat.Reader.64-bit' --silent --accept-package-agreements --accept-source-agreements. 

 

#Variable containing results of search for app on the system
$AdobeReader = (.\winget.exe list --id 'Adobe.Acrobat.Reader.64-bit')
#If statement to install app or move on
If ($AdobeReader -like '*No installed package found*')
{
    .\winget.exe install --id 'Adobe.Acrobat.Reader.64-bit' --silent --accept-package-agreements --accept-source-agreements
}
else
{
    Write-Host 'Adobe Reader is already installed.'
}

 

All together:

 

#Script that checks if apps are installed and installs them if they aren't

#Query for directory most updated winget.exe is stored in
$wingetdir = (Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" | Sort-Object -Property Path | Select-Object -Last 1)
#Output directory
Write-Host "cd to directory: $wingetdir"
#navigate to directory containing winget.exe
cd $wingetdir

#Variable containing results of search for app on the system
$AdobeReader = (.\winget.exe list --id 'Adobe.Acrobat.Reader.64-bit')
#If statement to install app or move on
If ($AdobeReader -like '*No installed package found*')
{
    .\winget.exe install --id 'Adobe.Acrobat.Reader.64-bit' --silent --accept-package-agreements --accept-source-agreements
}
else
{
    Write-Host 'Adobe Reader is already installed.'
}

 

Winget has a very helpful feature that allows users to update all of their apps with a single command: winget upgrade --all

To make use of this, I have a JumpCloud command that creates a scheduled task on the users machine and moves a script to a desired directory to be ran at each user login.  

Full disclosure: we aren't using this portion below in production yet, we are currently testing the user experience. 

Script containing winget upgrade --all command: 

 

#Query for directory most updated winget.exe is stored in
$wingetdir = (Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" | Sort-Object -Property Path | Select-Object -Last 1)
#Output directory
Write-Host "cd to directory: $wingetdir"
#navigate to directory containing winget.exe
cd $wingetdir

#Command to update all apps with updates available. | Outfile is optional but I find it helpful for knowing the script ran on login. 
.\winget.exe upgrade --all --silent --accept-package-agreements --accept-source-agreements | Out-File -FilePath 'C:\Path\To\CommandResults.txt' -Force

 

Script that creates the scheduled task to run the above script on each user login as system:

 

#Move the Winget Upgrade script to the desired directory here.
#Once the script is in the correct directory, create the scheduled task. 
    #Create Task to run at logon
    echo 'Creating scheduled task'
    #Create variables needed for the task
    $action = New-ScheduledTaskAction -Execute "C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe" -Argument '-ExecutionPolicy Bypass -File "C:\Path\To\WingetUpgrade.ps1"'
    $trigger = New-ScheduledTaskTrigger -AtLogon
    $principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
    $settings = New-ScheduledTaskSettingsSet
    $description = 'runs: winget upgrade --all --silent --accept-package-agreemments --accept-source-agreements at logon to keep applications up to date.'
    #Create the Task
    $task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settings -Description $description
    #Register the Task
    Register-ScheduledTask WingetUpgrade -InputObject $task
    #Enable the task
    Enable-ScheduledTask -TaskName "WingetUpgrade"  
    #Test task was created
    $TestTask = (Get-ScheduledTask -TaskName 'WingetUpgrade')
    echo 'Outputting result of task creation'
    Write-Host $TestTask
}

 

4 REPLIES 4

chhetriabi
Novitiate II

Thanks for sharing Jacob. Been following winget for a while but running with Jumpcloud has never been successful. 
Just tested the script above to install an app but it just returns Adobe Reader is already installed, but actually its not installed on the device.

Have you stumbled across this issue before ? Or where do you reckon I might have gone wrong?

BScott
Community Manager Community Manager
Community Manager

Want to share the script as you are running it and the message you receive, @chhetriabi? Maybe that will help @JacobLawson and others.

Like someone's post? Give them a kudo!
Did someone's answer help you? Please mark it as a solution.

chhetriabi
Novitiate II

@BeckyScott Sure thing.

So the script is literally the same as @JacobLawson has posted above but to install OpenVPN Connect. I have tried the above script and the result is the same for Adobe Reader too.

Here is the screen recording: https://drive.google.com/file/d/12ngwFLfiERZGgy_eXmDJgvIpqvbDP9o5/view?usp=sharing

Here is the script from Jacob where I have just replaced Adobe to install OpenVPN

$wingetdir = (Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" | Sort-Object -Property Path | Select-Object -Last 1)
Write-Host "cd to directory: $wingetdir"
cd $wingetdir
$OpenVPNConnect = (.\winget.exe list --id 'OpenVPNTechnologies.OpenVPNConnect')
If ($OpenVPNConnect -like '*No installed package found*')
{
    .\winget.exe install --id 'OpenVPNTechnologies.OpenVPNConnect' --silent --accept-package-agreements --accept-source-agreements
}
else
{
    Write-Host 'OpenVPN Connect is already installed.'
}

I have the ps file uploaded to the command and have just executed from there

chhetriabi_0-1659546686145.png

 

I just watched the video you shared and you cleared up a couple things.  Winget is installed and OpenVPN isn't already installed, at least for that user session. 

The if statement is showing as false so I'm curious what the output of $OpenVPNConnect is.  Can you run this and share the results? 

 

$wingetdir = (Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe" | Sort-Object -Property Path | Select-Object -Last 1)
Write-Host "cd to directory: $wingetdir"
cd $wingetdir
$OpenVPNConnect = (.\winget.exe list --id 'OpenVPNTechnologies.OpenVPNConnect')
$OpenVPNConnect
If ($OpenVPNConnect -like '*No installed package found*')
{
    .\winget.exe install --id 'OpenVPNTechnologies.OpenVPNConnect' --silent --accept-package-agreements --accept-source-agreements
}
else
{
    Write-Host 'OpenVPN Connect is already installed.'
}