wingetautoupdate/Winget-AutoUpdate-Install.ps1

328 lines
14 KiB
PowerShell
Raw Normal View History

2022-02-12 15:35:51 +00:00
<#
.SYNOPSIS
Configure Winget to daily update installed apps.
.DESCRIPTION
Install powershell scripts and scheduled task to daily run Winget upgrade and notify connected users.
Possible to exclude apps from auto-update
https://github.com/Romanitho/Winget-AutoUpdate
.PARAMETER Silent
Install Winget-AutoUpdate and prerequisites silently
.PARAMETER WingetUpdatePath
Specify Winget-AutoUpdate installation localtion. Default: C:\ProgramData\Winget-AutoUpdate\
2022-02-12 15:35:51 +00:00
.PARAMETER DoNotUpdate
2022-03-07 01:35:40 +00:00
Do not run Winget-AutoUpdate after installation. By default, Winget-AutoUpdate is run just after installation.
.PARAMETER DisableWAUAutoUpdate
Disable Winget-AutoUpdate update checking. By default, WAU auto update if new version is available on Github.
2022-02-12 15:35:51 +00:00
2022-04-05 10:38:54 +00:00
.PARAMETER UseWhiteList
Use White List instead of Black List. This setting will not create the "exclude_apps.txt" but "include_apps.txt"
2022-04-02 17:24:18 +00:00
.PARAMETER Uninstall
Remove scheduled tasks and scripts.
2022-04-24 08:51:51 +00:00
.PARAMETER NotificationLevel
Specify the Notification level: Full (Default, displays all notification), SuccessOnly (Only displays notification for success) or None (Does not show any popup).
2022-04-30 10:00:39 +00:00
.PARAMETER UpdatesAtLogon
Set WAU to run at user logon.
.PARAMETER UpdatesInterval
Specify the update frequency: Daily (Default), Weekly, Biweekly or Monthly.
2022-02-12 15:35:51 +00:00
.EXAMPLE
.\winget-install-and-update.ps1 -Silent -DoNotUpdate
2022-04-05 13:23:36 +00:00
.EXAMPLE
.\winget-install-and-update.ps1 -Silent -UseWhiteList
2022-04-30 10:00:39 +00:00
.EXAMPLE
.\winget-install-and-update.ps1 -Silent -UpdatesAtLogon -UpdatesInterval Weekly
2022-02-12 15:35:51 +00:00
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$False)] [Alias('S')] [Switch] $Silent = $false,
[Parameter(Mandatory=$False)] [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate",
2022-03-07 01:35:40 +00:00
[Parameter(Mandatory=$False)] [Switch] $DoNotUpdate = $false,
2022-04-02 17:24:18 +00:00
[Parameter(Mandatory=$False)] [Switch] $DisableWAUAutoUpdate = $false,
2022-04-05 10:38:54 +00:00
[Parameter(Mandatory=$False)] [Switch] $Uninstall = $false,
2022-04-24 09:02:39 +00:00
[Parameter(Mandatory=$False)] [Switch] $UseWhiteList = $false,
2022-04-30 10:00:39 +00:00
[Parameter(Mandatory=$False)] [ValidateSet("Full","SuccessOnly","None")] [String] $NotificationLevel = "Full",
[Parameter(Mandatory=$False)] [Switch] $UpdatesAtLogon = $false,
[Parameter(Mandatory=$False)] [ValidateSet("Daily","Weekly","BiWeekly","Monthly")] [String] $UpdatesInterval = "Daily"
2022-02-12 15:35:51 +00:00
)
<# FUNCTIONS #>
2022-03-26 07:49:53 +00:00
function Install-Prerequisites{
2022-04-10 10:50:45 +00:00
#Check if Visual C++ 2019 or 2022 installed
2022-04-15 16:39:11 +00:00
$Visual2019 = "Microsoft Visual C++ 2015-2019 Redistributable*"
$Visual2022 = "Microsoft Visual C++ 2015-2022 Redistributable*"
2022-04-10 10:50:45 +00:00
$path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object {$_.GetValue("DisplayName") -like $Visual2019 -or $_.GetValue("DisplayName") -like $Visual2022}
2022-02-12 15:35:51 +00:00
#If not installed, ask for installation
if (!($path)){
#If -silent option, force installation
if ($Silent){
2022-04-09 08:42:00 +00:00
$InstallApp = 1
2022-02-12 15:35:51 +00:00
}
else{
#Ask for installation
2022-04-09 08:42:00 +00:00
$MsgBoxTitle = "Winget Prerequisites"
2022-04-10 10:50:45 +00:00
$MsgBoxContent = "Microsoft Visual C++ 2015-2022 is required. Would you like to install it?"
2022-04-09 09:03:11 +00:00
$MsgBoxTimeOut = 60
2022-04-09 08:42:00 +00:00
$MsgBoxReturn = (New-Object -ComObject "Wscript.Shell").Popup($MsgBoxContent,$MsgBoxTimeOut,$MsgBoxTitle,4+32)
if ($MsgBoxReturn -ne 7) {
$InstallApp = 1
}
else {
$InstallApp = 0
2022-02-12 15:35:51 +00:00
}
}
2022-04-09 08:42:00 +00:00
#Install if approved
if ($InstallApp -eq 1){
2022-02-12 15:35:51 +00:00
try{
if((Get-CimInStance Win32_OperatingSystem).OSArchitecture -like "*64*"){
$OSArch = "x64"
}
else{
$OSArch = "x86"
}
Write-host "Downloading VC_redist.$OSArch.exe..."
2022-04-10 10:50:45 +00:00
$SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe"
2022-02-12 15:35:51 +00:00
$Installer = $WingetUpdatePath + "\VC_redist.$OSArch.exe"
$ProgressPreference = 'SilentlyContinue'
2022-03-10 21:09:23 +00:00
Invoke-WebRequest $SourceURL -OutFile (New-Item -Path $Installer -Force)
2022-02-12 15:35:51 +00:00
Write-host "Installing VC_redist.$OSArch.exe..."
2022-02-26 01:07:50 +00:00
Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait
2022-02-12 15:35:51 +00:00
Remove-Item $Installer -ErrorAction Ignore
2022-04-10 10:50:45 +00:00
Write-host "MS Visual C++ 2015-2022 installed successfully" -ForegroundColor Green
2022-02-12 15:35:51 +00:00
}
catch{
2022-04-10 10:50:45 +00:00
Write-host "MS Visual C++ 2015-2022 installation failed." -ForegroundColor Red
2022-02-12 15:35:51 +00:00
Start-Sleep 3
}
}
2022-04-09 08:42:00 +00:00
else{
2022-04-10 10:50:45 +00:00
Write-host "MS Visual C++ 2015-2022 wil not be installed." -ForegroundColor Magenta
2022-04-09 08:42:00 +00:00
}
2022-02-12 15:35:51 +00:00
}
else{
Write-Host "Prerequisites checked. OK" -ForegroundColor Green
}
}
2022-04-15 16:39:11 +00:00
function Install-WinGet{
#Check Package Install
Write-Host "Checking if Winget is installed" -ForegroundColor Yellow
$TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object {$_.DisplayName -eq "Microsoft.DesktopAppInstaller"}
If([Version]$TestWinGet.Version -gt "2022.213.0.0") {
2022-04-15 16:39:11 +00:00
Write-Host "WinGet is Installed" -ForegroundColor Green
}
Else{
2022-04-15 16:48:45 +00:00
2022-04-15 16:39:11 +00:00
#Download WinGet MSIXBundle
2022-04-15 16:48:45 +00:00
Write-Host "Not installed. Downloading WinGet..."
$WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.3.431/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
2022-04-15 16:39:11 +00:00
$WebClient=New-Object System.Net.WebClient
$WebClient.DownloadFile($WinGetURL, "$PSScriptRoot\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle")
#Install WinGet MSIXBundle
try{
2022-04-15 16:48:45 +00:00
Write-Host "Installing MSIXBundle for App Installer..."
2022-04-15 16:39:11 +00:00
Add-AppxProvisionedPackage -Online -PackagePath "$PSScriptRoot\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -SkipLicense
2022-04-15 16:48:45 +00:00
Write-Host "Installed MSIXBundle for App Installer" -ForegroundColor Green
2022-04-15 16:39:11 +00:00
}
catch{
2022-04-15 16:48:45 +00:00
Write-Host "Failed to intall MSIXBundle for App Installer..." -ForegroundColor Red
2022-04-15 16:39:11 +00:00
}
#Remove WinGet MSIXBundle
Remove-Item -Path "$PSScriptRoot\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue
}
}
2022-02-12 15:35:51 +00:00
function Install-WingetAutoUpdate{
try{
#Copy files to location
if (!(Test-Path $WingetUpdatePath)){
New-Item -ItemType Directory -Force -Path $WingetUpdatePath
}
Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue
2022-04-05 13:17:18 +00:00
2022-04-05 10:38:54 +00:00
#White List or Black List apps
if ($UseWhiteList){
if (Test-Path "$PSScriptRoot\included_apps.txt"){
Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue
}
else{
2022-04-05 13:17:18 +00:00
New-Item -Path $WingetUpdatePath -Name "included_apps.txt" -ItemType "file" -ErrorAction SilentlyContinue
2022-04-05 10:38:54 +00:00
}
}
else {
Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue
}
2022-02-12 15:35:51 +00:00
# Set dummy regkeys for notification name and icon
& reg add "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /v DisplayName /t REG_EXPAND_SZ /d "Application Update" /f | Out-Null
& reg add "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /v IconUri /t REG_EXPAND_SZ /d %SystemRoot%\system32\@WindowsUpdateToastIcon.png /f | Out-Null
# Settings for the scheduled task for Updates
2022-03-22 07:29:19 +00:00
$taskAction = New-ScheduledTaskAction Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($WingetUpdatePath)\winget-upgrade.ps1`""
2022-04-30 10:00:39 +00:00
$taskTriggers = @()
if ($UpdatesAtLogon){
$tasktriggers += New-ScheduledTaskTrigger -AtLogOn
}
if ($UpdatesInterval -eq "Daily"){
$tasktriggers += New-ScheduledTaskTrigger -Daily -At 6AM
}
elseif ($UpdatesInterval -eq "Weekly"){
$tasktriggers += New-ScheduledTaskTrigger -Weekly -At 6AM -DaysOfWeek 2
}
elseif ($UpdatesInterval -eq "BiWeekly"){
$tasktriggers += New-ScheduledTaskTrigger -Weekly -At 6AM -DaysOfWeek 2 -WeeksInterval 2
}
elseif ($UpdatesInterval -eq "Monthly"){
$tasktriggers += New-ScheduledTaskTrigger -Weekly -At 6AM -DaysOfWeek 2 -WeeksInterval 4
}
2022-02-12 15:35:51 +00:00
$taskUserPrincipal = New-ScheduledTaskPrincipal -UserId S-1-5-18 -RunLevel Highest
$taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00
# Set up the task, and register it
2022-04-30 10:00:39 +00:00
$task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings -Trigger $taskTriggers
2022-04-09 09:03:11 +00:00
Register-ScheduledTask -TaskName 'Winget-AutoUpdate' -InputObject $task -Force | Out-Null
2022-02-12 15:35:51 +00:00
# Settings for the scheduled task for Notifications
2022-03-22 07:29:19 +00:00
$taskAction = New-ScheduledTaskAction Execute "wscript.exe" -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-notify.ps1`"`""
2022-02-12 15:35:51 +00:00
$taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11
$taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 00:05:00
# Set up the task, and register it
$task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings
2022-04-09 09:03:11 +00:00
Register-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -InputObject $task -Force | Out-Null
2022-02-12 15:35:51 +00:00
2022-03-07 01:35:40 +00:00
# Install config file
[xml]$ConfigXML = @"
<?xml version="1.0"?>
<app>
<WAUautoupdate>$(!($DisableWAUAutoUpdate))</WAUautoupdate>
2022-04-05 18:15:11 +00:00
<WAUprerelease>False</WAUprerelease>
2022-04-05 10:38:54 +00:00
<UseWAUWhiteList>$UseWhiteList</UseWAUWhiteList>
2022-04-24 08:51:51 +00:00
<NotificationLevel>$NotificationLevel</NotificationLevel>
2022-03-07 01:35:40 +00:00
</app>
"@
$ConfigXML.Save("$WingetUpdatePath\config\config.xml")
2022-04-15 16:51:30 +00:00
Write-host "`n WAU Installation succeeded!" -ForegroundColor Green
2022-02-12 15:35:51 +00:00
Start-sleep 1
#Run Winget ?
Start-WingetAutoUpdate
}
catch{
2022-04-15 16:51:30 +00:00
Write-host "`n WAU Installation failed! Run me with admin rights" -ForegroundColor Red
2022-02-12 15:35:51 +00:00
Start-sleep 1
return $False
}
}
2022-04-02 17:24:18 +00:00
function Uninstall-WingetAutoUpdate{
try{
#Check if installed location exists and delete
if (Test-Path ($WingetUpdatePath)){
Remove-Item $WingetUpdatePath -Force -Recurse
Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False
Get-ScheduledTask -TaskName "Winget-AutoUpdate-Notify" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False
& reg delete "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /f | Out-Null
Write-host "Uninstallation succeeded!" -ForegroundColor Green
Start-sleep 1
}
else {
Write-host "$WingetUpdatePath not found! Uninstallation failed!" -ForegroundColor Red
}
}
catch{
Write-host "`nUninstallation failed! Run as admin ?" -ForegroundColor Red
Start-sleep 1
}
}
2022-02-12 15:35:51 +00:00
function Start-WingetAutoUpdate{
#If -DoNotUpdate is true, skip.
if (!($DoNotUpdate)){
#If -Silent, run Winget-AutoUpdate now
if ($Silent){
2022-04-09 08:42:00 +00:00
$RunWinget = 1
2022-02-12 15:35:51 +00:00
}
#Ask for WingetAutoUpdate
else{
2022-04-09 08:42:00 +00:00
$MsgBoxTitle = "Winget-AutoUpdate"
$MsgBoxContent = "Would you like to run Winget-AutoUpdate now?"
2022-04-09 09:03:11 +00:00
$MsgBoxTimeOut = 60
2022-04-09 08:42:00 +00:00
$MsgBoxReturn = (New-Object -ComObject "Wscript.Shell").Popup($MsgBoxContent,$MsgBoxTimeOut,$MsgBoxTitle,4+32)
if ($MsgBoxReturn -ne 7) {
$RunWinget = 1
}
else {
$RunWinget = 0
2022-02-12 15:35:51 +00:00
}
}
2022-04-09 08:42:00 +00:00
if ($RunWinget -eq 1){
2022-02-12 15:35:51 +00:00
try{
Write-host "Running Winget-AutoUpdate..." -ForegroundColor Yellow
Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue
2022-04-02 17:24:18 +00:00
while ((Get-ScheduledTask -TaskName "Winget-AutoUpdate").State -ne 'Ready') {
Start-Sleep 1
}
2022-02-12 15:35:51 +00:00
}
catch{
Write-host "Failed to run Winget-AutoUpdate..." -ForegroundColor Red
}
}
}
else{
Write-host "Skip running Winget-AutoUpdate"
}
}
<# MAIN #>
2022-04-03 10:40:44 +00:00
Write-Host "`n"
Write-Host "`t###################################"
Write-Host "`t# #"
Write-Host "`t# Winget AutoUpdate #"
Write-Host "`t# #"
Write-Host "`t###################################"
Write-Host "`n"
2022-02-12 15:35:51 +00:00
2022-04-02 17:24:18 +00:00
if (!$Uninstall){
2022-04-09 08:42:00 +00:00
Write-host "Installing WAU to $WingetUpdatePath\"
2022-04-02 17:24:18 +00:00
Install-Prerequisites
2022-04-15 16:39:11 +00:00
Install-WinGet
2022-04-02 17:24:18 +00:00
Install-WingetAutoUpdate
}
else {
2022-04-09 08:42:00 +00:00
Write-Host "Uninstall WAU"
2022-04-02 17:24:18 +00:00
Uninstall-WingetAutoUpdate
}
2022-02-12 15:35:51 +00:00
Write-host "End of process."
2022-04-03 07:12:39 +00:00
if (!$Silent) {
Timeout 10
2022-04-05 18:15:11 +00:00
}