From 1320e7d356a198728743d341f6745e149dee2f27 Mon Sep 17 00:00:00 2001 From: Joerg Hochwald Date: Fri, 15 Sep 2023 16:33:51 +0200 Subject: [PATCH 1/4] Start some refactoring Refactor the existing code. Apply some good practices and reformat the existing code. No new functionality was added --- Winget-AutoUpdate-Install.ps1 | 1110 +++++++++-------- Winget-AutoUpdate/User-Run.ps1 | 151 ++- Winget-AutoUpdate/WAU-Uninstall.ps1 | 141 ++- Winget-AutoUpdate/Winget-Notify.ps1 | 33 +- Winget-AutoUpdate/Winget-Upgrade.ps1 | 172 +-- .../functions/Add-ScopeMachine.ps1 | 52 +- Winget-AutoUpdate/functions/Add-Shortcut.ps1 | 29 +- .../functions/Confirm-Installation.ps1 | 52 +- Winget-AutoUpdate/functions/Get-AZCopy.ps1 | 94 +- Winget-AutoUpdate/functions/Get-AppInfo.ps1 | 22 +- .../functions/Get-ExcludedApps.ps1 | 48 +- .../functions/Get-IncludedApps.ps1 | 53 +- .../functions/Get-NotifLocale.ps1 | 22 +- Winget-AutoUpdate/functions/Get-Policies.ps1 | 770 +++++++----- .../functions/Get-WAUAvailableVersion.ps1 | 39 +- Winget-AutoUpdate/functions/Get-WingetCmd.ps1 | 28 +- .../functions/Get-WingetOutdatedApps.ps1 | 140 ++- .../functions/Get-WingetSystemApps.ps1 | 25 +- .../functions/Invoke-LogRotation.ps1 | 196 +-- .../functions/Invoke-ModsProtect.ps1 | 130 +- .../functions/Invoke-PostUpdateActions.ps1 | 440 ++++--- Winget-AutoUpdate/functions/Start-Init.ps1 | 118 +- .../functions/Start-NotifTask.ps1 | 313 ++--- Winget-AutoUpdate/functions/Test-ListPath.ps1 | 181 +-- Winget-AutoUpdate/functions/Test-Mods.ps1 | 75 +- Winget-AutoUpdate/functions/Test-ModsPath.ps1 | 482 ++++--- Winget-AutoUpdate/functions/Test-Network.ps1 | 131 +- .../functions/Test-PendingReboot.ps1 | 47 +- Winget-AutoUpdate/functions/Update-App.ps1 | 224 ++-- Winget-AutoUpdate/functions/Update-WAU.ps1 | 127 +- Winget-AutoUpdate/functions/Write-ToLog.ps1 | 24 +- 31 files changed, 3014 insertions(+), 2455 deletions(-) diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index 6ab9df9..79d3261 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -1,611 +1,713 @@ <# -.SYNOPSIS -Configure Winget to daily update installed apps. + .SYNOPSIS + Configure Winget to daily update installed apps. -.DESCRIPTION -Install powershell scripts and scheduled task to daily run Winget upgrade and notify connected users. -Posibility to exclude apps from auto-update -https://github.com/Romanitho/Winget-AutoUpdate + .DESCRIPTION + Install powershell scripts and scheduled task to daily run Winget upgrade and notify connected users. + Posibility to exclude apps from auto-update + https://github.com/Romanitho/Winget-AutoUpdate -.PARAMETER Silent -Install Winget-AutoUpdate and prerequisites silently + .PARAMETER Silent + Install Winget-AutoUpdate and prerequisites silently -.PARAMETER MaxLogFiles -Specify number of allowed log files (Default is 3 of 0-99: Setting MaxLogFiles to 0 don't delete any old archived log files, 1 keeps the original one and just let it grow) + .PARAMETER MaxLogFiles + Specify number of allowed log files (Default is 3 of 0-99: Setting MaxLogFiles to 0 don't delete any old archived log files, 1 keeps the original one and just let it grow) -.PARAMETER MaxLogSize -Specify the size of the log file in bytes before rotating. (Default is 1048576 = 1 MB) + .PARAMETER MaxLogSize + Specify the size of the log file in bytes before rotating. (Default is 1048576 = 1 MB) -.PARAMETER WingetUpdatePath -Specify Winget-AutoUpdate installation localtion. Default: C:\ProgramData\Winget-AutoUpdate\ + .PARAMETER WingetUpdatePath + Specify Winget-AutoUpdate installation localtion. Default: C:\ProgramData\Winget-AutoUpdate\ -.PARAMETER DoNotUpdate -Do not run Winget-AutoUpdate after installation. By default, Winget-AutoUpdate is run just after installation. + .PARAMETER DoNotUpdate + 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. + .PARAMETER DisableWAUAutoUpdate + Disable Winget-AutoUpdate update checking. By default, WAU auto update if new version is available on Github. -.PARAMETER UseWhiteList -Use White List instead of Black List. This setting will not create the "exclude_apps.txt" but "include_apps.txt" + .PARAMETER UseWhiteList + Use White List instead of Black List. This setting will not create the "exclude_apps.txt" but "include_apps.txt" -.PARAMETER ListPath -Get Black/White List from Path (URL/UNC/GPO/Local) + .PARAMETER ListPath + Get Black/White List from Path (URL/UNC/GPO/Local) -.PARAMETER ModsPath -Get mods from Path (URL/UNC/Local/AzureBlob) + .PARAMETER ModsPath + Get mods from Path (URL/UNC/Local/AzureBlob) -.PARAMETER AzureBlobURL -Set the Azure Storage Blob URL including the SAS token. The token requires at a minimum 'Read' and 'List' permissions. It is recommended to set this at the container level + .PARAMETER AzureBlobURL + Set the Azure Storage Blob URL including the SAS token. The token requires at a minimum 'Read' and 'List' permissions. It is recommended to set this at the container level -.PARAMETER Uninstall -Remove scheduled tasks and scripts. + .PARAMETER Uninstall + Remove scheduled tasks and scripts. -.PARAMETER NoClean -Keep critical files when installing/uninstalling + .PARAMETER NoClean + Keep critical files when installing/uninstalling -.PARAMETER DesktopShortcut -Create a shortcut for user interaction on the Desktop to run task "Winget-AutoUpdate" + .PARAMETER DesktopShortcut + Create a shortcut for user interaction on the Desktop to run task "Winget-AutoUpdate" -.PARAMETER StartMenuShortcut -Create shortcuts for user interaction in the Start Menu to run task "Winget-AutoUpdate", open Logs and Web Help + .PARAMETER StartMenuShortcut + Create shortcuts for user interaction in the Start Menu to run task "Winget-AutoUpdate", open Logs and Web Help -.PARAMETER NotificationLevel -Specify the Notification level: Full (Default, displays all notification), SuccessOnly (Only displays notification for success) or None (Does not show any popup). + .PARAMETER NotificationLevel + Specify the Notification level: Full (Default, displays all notification), SuccessOnly (Only displays notification for success) or None (Does not show any popup). -.PARAMETER UpdatesAtLogon -Set WAU to run at user logon. + .PARAMETER UpdatesAtLogon + Set WAU to run at user logon. -.PARAMETER UpdatesInterval -Specify the update frequency: Daily (Default), BiDaily, Weekly, BiWeekly, Monthly or Never + .PARAMETER UpdatesInterval + Specify the update frequency: Daily (Default), BiDaily, Weekly, BiWeekly, Monthly or Never -.PARAMETER UpdatesAtTime -Specify the time of the update interval execution time. Default 6AM + .PARAMETER UpdatesAtTime + Specify the time of the update interval execution time. Default 6AM -.PARAMETER RunOnMetered -Run WAU on metered connection. Default No. + .PARAMETER RunOnMetered + Run WAU on metered connection. Default No. -.PARAMETER InstallUserContext -Install WAU with system and user context executions + .PARAMETER InstallUserContext + Install WAU with system and user context executions -.PARAMETER BypassListForUsers -Configure WAU to bypass the Black/White list when run in user context. Applications installed in system context will be ignored under user context. + .PARAMETER BypassListForUsers + Configure WAU to bypass the Black/White list when run in user context. Applications installed in system context will be ignored under user context. -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -DoNotUpdate -MaxLogFiles 4 -MaxLogSize 2097152 + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -DoNotUpdate -MaxLogFiles 4 -MaxLogSize 2097152 -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -UseWhiteList + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -UseWhiteList -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -ListPath https://www.domain.com/WAULists -StartMenuShortcut -UpdatesInterval BiDaily + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -ListPath https://www.domain.com/WAULists -StartMenuShortcut -UpdatesInterval BiDaily -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -ModsPath https://www.domain.com/WAUMods -DesktopShortcut -UpdatesInterval Weekly + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -ModsPath https://www.domain.com/WAUMods -DesktopShortcut -UpdatesInterval Weekly -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -UpdatesAtLogon -UpdatesInterval Weekly + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -UpdatesAtLogon -UpdatesInterval Weekly -.EXAMPLE -.\Winget-AutoUpdate-Install.ps1 -Silent -Uninstall -NoClean + .EXAMPLE + .\Winget-AutoUpdate-Install.ps1 -Silent -Uninstall -NoClean #> [CmdletBinding()] param( - [Parameter(Mandatory = $False)] [Alias('S')] [Switch] $Silent = $false, - [Parameter(Mandatory = $False)] [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate", - [Parameter(Mandatory = $False)] [Alias('List')] [String] $ListPath, - [Parameter(Mandatory = $False)] [Alias('Mods')] [String] $ModsPath, - [Parameter(Mandatory = $False)] [Alias('AzureBlobURL')] [String] $AzureBlobSASURL, - [Parameter(Mandatory = $False)] [Switch] $DoNotUpdate = $false, - [Parameter(Mandatory = $False)] [Switch] $DisableWAUAutoUpdate = $false, - [Parameter(Mandatory = $False)] [Switch] $RunOnMetered = $false, - [Parameter(Mandatory = $False)] [Switch] $Uninstall = $false, - [Parameter(Mandatory = $False)] [Switch] $NoClean = $false, - [Parameter(Mandatory = $False)] [Switch] $DesktopShortcut = $false, - [Parameter(Mandatory = $False)] [Switch] $StartMenuShortcut = $false, - [Parameter(Mandatory = $False)] [Switch] $UseWhiteList = $false, - [Parameter(Mandatory = $False)] [ValidateSet("Full", "SuccessOnly", "None")] [String] $NotificationLevel = "Full", - [Parameter(Mandatory = $False)] [Switch] $UpdatesAtLogon = $false, - [Parameter(Mandatory = $False)] [ValidateSet("Daily", "BiDaily", "Weekly", "BiWeekly", "Monthly", "Never")] [String] $UpdatesInterval = "Daily", - [Parameter(Mandatory = $False)] [DateTime] $UpdatesAtTime = ("06am"), - [Parameter(Mandatory = $False)] [Switch] $BypassListForUsers = $false, - [Parameter(Mandatory = $False)] [Switch] $InstallUserContext = $false, - [Parameter(Mandatory = $False)] [ValidateRange(0, 99)] [int32] $MaxLogFiles = 3, - [Parameter(Mandatory = $False)] [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB + [Alias('S')] [Switch] $Silent = $false, + [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate", + [Alias('List')] [String] $ListPath, + [Alias('Mods')] [String] $ModsPath, + [Alias('AzureBlobURL')] [String] $AzureBlobSASURL, + [Switch] $DoNotUpdate = $false, + [Switch] $DisableWAUAutoUpdate = $false, + [Switch] $RunOnMetered = $false, + [Switch] $Uninstall = $false, + [Switch] $NoClean = $false, + [Switch] $DesktopShortcut = $false, + [Switch] $StartMenuShortcut = $false, + [Switch] $UseWhiteList = $false, + [ValidateSet('Full', 'SuccessOnly', 'None')] [String] $NotificationLevel = 'Full', + [Switch] $UpdatesAtLogon = $false, + [ValidateSet('Daily', 'BiDaily', 'Weekly', 'BiWeekly', 'Monthly', 'Never')] [String] $UpdatesInterval = 'Daily', + [DateTime] $UpdatesAtTime = ('06am'), + [Switch] $BypassListForUsers = $false, + [Switch] $InstallUserContext = $false, + [ValidateRange(0, 99)] [int] $MaxLogFiles = 3, + [long] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB ) <# FUNCTIONS #> -function Install-Prerequisites { +function Install-Prerequisites +{ + Write-Host -Object "`nChecking prerequisites..." -ForegroundColor Yellow - Write-Host "`nChecking prerequisites..." -ForegroundColor Yellow + #Check if Visual C++ 2019 or 2022 installed + $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' + $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' + $path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object -FilterScript { + $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 + } - #Check if Visual C++ 2019 or 2022 installed - $Visual2019 = "Microsoft Visual C++ 2015-2019 Redistributable*" - $Visual2022 = "Microsoft Visual C++ 2015-2022 Redistributable*" - $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 } - - #If not installed, ask for installation - if (!($path)) { - #If -silent option, force installation - if ($Silent) { + #If not installed, ask for installation + if (!($path)) + { + #If -silent option, force installation + if ($Silent) + { + $InstallApp = 1 + } + else + { + #Ask for installation + $MsgBoxTitle = 'Winget Prerequisites' + $MsgBoxContent = 'Microsoft Visual C++ 2015-2022 is required. Would you like to install it?' + $MsgBoxTimeOut = 60 + $MsgBoxReturn = (New-Object -ComObject 'Wscript.Shell').Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) + if ($MsgBoxReturn -ne 7) + { $InstallApp = 1 - } - else { - #Ask for installation - $MsgBoxTitle = "Winget Prerequisites" - $MsgBoxContent = "Microsoft Visual C++ 2015-2022 is required. Would you like to install it?" - $MsgBoxTimeOut = 60 - $MsgBoxReturn = (New-Object -ComObject "Wscript.Shell").Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) - if ($MsgBoxReturn -ne 7) { - $InstallApp = 1 + } + else + { + $InstallApp = 0 + } + } + #Install if approved + if ($InstallApp -eq 1) + { + try + { + if ((Get-CimInstance Win32_OperatingSystem).OSArchitecture -like '*64*') + { + $OSArch = 'x64' } - else { - $InstallApp = 0 + else + { + $OSArch = 'x86' } - } - #Install if approved - if ($InstallApp -eq 1) { - try { - if ((Get-CimInStance Win32_OperatingSystem).OSArchitecture -like "*64*") { - $OSArch = "x64" - } - else { - $OSArch = "x86" - } - Write-host "-> Downloading VC_redist.$OSArch.exe..." - $SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe" - $Installer = $WingetUpdatePath + "\VC_redist.$OSArch.exe" - $ProgressPreference = 'SilentlyContinue' - Invoke-WebRequest $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force) - Write-host "-> Installing VC_redist.$OSArch.exe..." - Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait - Remove-Item $Installer -ErrorAction Ignore - Write-host "MS Visual C++ 2015-2022 installed successfully" -ForegroundColor Green - } - catch { - Write-host "MS Visual C++ 2015-2022 installation failed." -ForegroundColor Red - Start-Sleep 3 - } - } - else { - Write-host "-> MS Visual C++ 2015-2022 will not be installed." -ForegroundColor Magenta - } - } - else { - Write-Host "Prerequisites checked. OK" -ForegroundColor Green - } + Write-Host -Object "-> Downloading VC_redist.$OSArch.exe..." + $SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe" + $Installer = $WingetUpdatePath + "\VC_redist.$OSArch.exe" + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force) + Write-Host -Object "-> Installing VC_redist.$OSArch.exe..." + Start-Process -FilePath $Installer -ArgumentList '/quiet /norestart' -Wait + Remove-Item $Installer -ErrorAction Ignore + Write-Host -Object 'MS Visual C++ 2015-2022 installed successfully' -ForegroundColor Green + } + catch + { + Write-Host -Object 'MS Visual C++ 2015-2022 installation failed.' -ForegroundColor Red + Start-Sleep -Seconds 3 + } + } + else + { + Write-Host -Object '-> MS Visual C++ 2015-2022 will not be installed.' -ForegroundColor Magenta + } + } + else + { + Write-Host -Object 'Prerequisites checked. OK' -ForegroundColor Green + } } -function Install-WinGet { +function Install-WinGet +{ + Write-Host -Object "`nChecking if Winget is installed" -ForegroundColor Yellow - Write-Host "`nChecking if Winget is installed" -ForegroundColor Yellow + #Check Package Install + $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { + $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' + } - #Check Package Install - $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" } + #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 + If ([Version]$TestWinGet.Version -ge '2023.808.2243.0') + { + Write-Host -Object 'Winget is Installed' -ForegroundColor Green + } + Else + { + Write-Host -Object '-> Winget is not installed:' - #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 - If ([Version]$TestWinGet.Version -ge "2023.808.2243.0") { + #Check if $WingetUpdatePath exist + if (!(Test-Path $WingetUpdatePath)) + { + $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath + } - Write-Host "Winget is Installed" -ForegroundColor Green + #Downloading and Installing Dependencies in SYSTEM context + if (!(Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7')) + { + Write-Host -Object '-> Downloading Microsoft.UI.Xaml.2.7...' + $UiXamlUrl = 'https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.0' + $UiXamlZip = "$WingetUpdatePath\Microsoft.UI.XAML.2.7.zip" + Invoke-RestMethod -Uri $UiXamlUrl -OutFile $UiXamlZip + Expand-Archive -Path $UiXamlZip -DestinationPath "$WingetUpdatePath\extracted" -Force + try + { + Write-Host -Object '-> Installing Microsoft.UI.Xaml.2.7...' + $null = Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\extracted\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx" -SkipLicense + Write-Host -Object 'Microsoft.UI.Xaml.2.7 installed successfully' -ForegroundColor Green + } + catch + { + Write-Host -Object 'Failed to intall Wicrosoft.UI.Xaml.2.7...' -ForegroundColor Red + } + Remove-Item -Path $UiXamlZip -Force + Remove-Item -Path "$WingetUpdatePath\extracted" -Force -Recurse + } - } - Else { + if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop')) + { + Write-Host -Object '-> Downloading Microsoft.VCLibs.140.00.UWPDesktop...' + $VCLibsUrl = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx' + $VCLibsFile = "$WingetUpdatePath\Microsoft.VCLibs.x64.14.00.Desktop.appx" + Invoke-RestMethod -Uri $VCLibsUrl -OutFile $VCLibsFile + try + { + Write-Host -Object '-> Installing Microsoft.VCLibs.140.00.UWPDesktop...' + $null = Add-AppxProvisionedPackage -Online -PackagePath $VCLibsFile -SkipLicense + Write-Host -Object 'Microsoft.VCLibs.140.00.UWPDesktop installed successfully' -ForegroundColor Green + } + catch + { + Write-Host -Object 'Failed to intall Microsoft.VCLibs.140.00.UWPDesktop...' -ForegroundColor Red + } + Remove-Item -Path $VCLibsFile -Force + } - Write-Host "-> Winget is not installed:" + #Download WinGet MSIXBundle + Write-Host -Object '-> Downloading Winget MSIXBundle for App Installer...' + $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' + $WebClient = New-Object -TypeName System.Net.WebClient + $WebClient.DownloadFile($WinGetURL, "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle") - #Check if $WingetUpdatePath exist - if (!(Test-Path $WingetUpdatePath)) { - New-Item -ItemType Directory -Force -Path $WingetUpdatePath | Out-Null - } - - #Downloading and Installing Dependencies in SYSTEM context - if (!(Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7')) { - Write-Host "-> Downloading Microsoft.UI.Xaml.2.7..." - $UiXamlUrl = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.0" - $UiXamlZip = "$WingetUpdatePath\Microsoft.UI.XAML.2.7.zip" - Invoke-RestMethod -Uri $UiXamlUrl -OutFile $UiXamlZip - Expand-Archive -Path $UiXamlZip -DestinationPath "$WingetUpdatePath\extracted" -Force - try { - Write-Host "-> Installing Microsoft.UI.Xaml.2.7..." - Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\extracted\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx" -SkipLicense | Out-Null - Write-host "Microsoft.UI.Xaml.2.7 installed successfully" -ForegroundColor Green - } - catch { - Write-Host "Failed to intall Wicrosoft.UI.Xaml.2.7..." -ForegroundColor Red - } - Remove-Item -Path $UiXamlZip -Force - Remove-Item -Path "$WingetUpdatePath\extracted" -Force -Recurse - } - - if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop')) { - Write-Host "-> Downloading Microsoft.VCLibs.140.00.UWPDesktop..." - $VCLibsUrl = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx" - $VCLibsFile = "$WingetUpdatePath\Microsoft.VCLibs.x64.14.00.Desktop.appx" - Invoke-RestMethod -Uri $VCLibsUrl -OutFile $VCLibsFile - try { - Write-Host "-> Installing Microsoft.VCLibs.140.00.UWPDesktop..." - Add-AppxProvisionedPackage -Online -PackagePath $VCLibsFile -SkipLicense | Out-Null - Write-host "Microsoft.VCLibs.140.00.UWPDesktop installed successfully" -ForegroundColor Green - } - catch { - Write-Host "Failed to intall Microsoft.VCLibs.140.00.UWPDesktop..." -ForegroundColor Red - } - Remove-Item -Path $VCLibsFile -Force - } - - #Download WinGet MSIXBundle - Write-Host "-> Downloading Winget MSIXBundle for App Installer..." - $WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" - $WebClient = New-Object System.Net.WebClient - $WebClient.DownloadFile($WinGetURL, "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle") - - #Install WinGet MSIXBundle in SYSTEM context - try { - Write-Host "-> Installing Winget MSIXBundle for App Installer..." - Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -SkipLicense | Out-Null - Write-host "Winget MSIXBundle for App Installer installed successfully" -ForegroundColor Green - } - catch { - Write-Host "Failed to intall Winget MSIXBundle for App Installer..." -ForegroundColor Red - } - - #Remove WinGet MSIXBundle - Remove-Item -Path "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue - - } + #Install WinGet MSIXBundle in SYSTEM context + try + { + Write-Host -Object '-> Installing Winget MSIXBundle for App Installer...' + $null = Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -SkipLicense + Write-Host -Object 'Winget MSIXBundle for App Installer installed successfully' -ForegroundColor Green + } + catch + { + Write-Host -Object 'Failed to intall Winget MSIXBundle for App Installer...' -ForegroundColor Red + } + #Remove WinGet MSIXBundle + Remove-Item -Path "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue + } } -function Install-WingetAutoUpdate { +function Install-WingetAutoUpdate +{ + Write-Host -Object "`nInstalling WAU..." -ForegroundColor Yellow - Write-Host "`nInstalling WAU..." -ForegroundColor Yellow + try + { + #Copy files to location (and clean old install) + if (!(Test-Path $WingetUpdatePath)) + { + $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath + } + else + { + if (!$NoClean) + { + Remove-Item -Path "$WingetUpdatePath\*" -Exclude *.log -Recurse -Force + } + else + { + #Keep critical files + Get-ChildItem -Path $WingetUpdatePath -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force + } + } + Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - try { - #Copy files to location (and clean old install) - if (!(Test-Path $WingetUpdatePath)) { - New-Item -ItemType Directory -Force -Path $WingetUpdatePath | Out-Null - } - else { - if (!$NoClean) { - Remove-Item -Path "$WingetUpdatePath\*" -Exclude *.log -Recurse -Force + #White List or Black List apps + if ($UseWhiteList) + { + if (!$NoClean) + { + if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) + { + Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } - else { - #Keep critical files - Get-ChildItem -Path $WingetUpdatePath -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force + else + { + if (!$ListPath) + { + $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue + } } - } - Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } + elseif (!(Test-Path -Path "$WingetUpdatePath\included_apps.txt")) + { + if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) + { + Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } + else + { + if (!$ListPath) + { + $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue + } + } + } + } + else + { + if (!$NoClean) + { + Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } + elseif (!(Test-Path -Path "$WingetUpdatePath\excluded_apps.txt")) + { + Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } + } - #White List or Black List apps - if ($UseWhiteList) { - if (!$NoClean) { - if ((Test-Path "$PSScriptRoot\included_apps.txt")) { - Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - } - else { - if (!$ListPath) { - New-Item -Path $WingetUpdatePath -Name "included_apps.txt" -ItemType "file" -ErrorAction SilentlyContinue | Out-Null - } - } - } - elseif (!(Test-Path "$WingetUpdatePath\included_apps.txt")) { - if ((Test-Path "$PSScriptRoot\included_apps.txt")) { - Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - } - else { - if (!$ListPath) { - New-Item -Path $WingetUpdatePath -Name "included_apps.txt" -ItemType "file" -ErrorAction SilentlyContinue | Out-Null - } - } - } - } - else { - if (!$NoClean) { - Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - } - elseif (!(Test-Path "$WingetUpdatePath\excluded_apps.txt")) { - Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - } - } + # Set dummy regkeys for notification name and icon + $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v DisplayName /t REG_EXPAND_SZ /d 'Application Update' /f + $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v IconUri /t REG_EXPAND_SZ /d %SystemRoot%\system32\@WindowsUpdateToastIcon.png /f - # 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 + $taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($WingetUpdatePath)\winget-upgrade.ps1`"" + $taskTriggers = @() + if ($UpdatesAtLogon) + { + $taskTriggers += New-ScheduledTaskTrigger -AtLogOn + } + if ($UpdatesInterval -eq 'Daily') + { + $taskTriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime + } + elseif ($UpdatesInterval -eq 'BiDaily') + { + $taskTriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime -DaysInterval 2 + } + elseif ($UpdatesInterval -eq 'Weekly') + { + $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 + } + elseif ($UpdatesInterval -eq 'BiWeekly') + { + $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 2 + } + elseif ($UpdatesInterval -eq 'Monthly') + { + $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 4 + } + $taskUserPrincipal = New-ScheduledTaskPrincipal -UserId S-1-5-18 -RunLevel Highest + $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 - # Settings for the scheduled task for Updates - $taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($WingetUpdatePath)\winget-upgrade.ps1`"" - $taskTriggers = @() - if ($UpdatesAtLogon) { - $tasktriggers += New-ScheduledTaskTrigger -AtLogOn - } - if ($UpdatesInterval -eq "Daily") { - $tasktriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime - } - elseif ($UpdatesInterval -eq "BiDaily") { - $tasktriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime -DaysInterval 2 - } - elseif ($UpdatesInterval -eq "Weekly") { - $tasktriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 - } - elseif ($UpdatesInterval -eq "BiWeekly") { - $tasktriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 2 - } - elseif ($UpdatesInterval -eq "Monthly") { - $tasktriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 4 - } - $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 - if ($taskTriggers) { - $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings -Trigger $taskTriggers - } - else { - $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings - } + # Set up the task, and register it + if ($taskTriggers) + { + $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings -Trigger $taskTriggers + } + else + { + $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings + } - Register-ScheduledTask -TaskName 'Winget-AutoUpdate' -InputObject $task -Force | Out-Null + $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate' -InputObject $task -Force - if ($InstallUserContext) { - # Settings for the scheduled task in User context - $taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-upgrade.ps1`"`"" - $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 - $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 + if ($InstallUserContext) + { + # Settings for the scheduled task in User context + $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-upgrade.ps1`"`"" + $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 + $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 - # Set up the task for user apps - $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings - Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force | Out-Null - } + # Set up the task for user apps + $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings + $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force + } - # Settings for the scheduled task for Notifications - $taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-notify.ps1`"`"" - $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 - $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 00:05:00 + # Settings for the scheduled task for Notifications + $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-notify.ps1`"`"" + $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 - Register-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -InputObject $task -Force | Out-Null + # Set up the task, and register it + $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings + $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -InputObject $task -Force - #Set task readable/runnable for all users - $scheduler = New-Object -ComObject "Schedule.Service" - $scheduler.Connect() - $task = $scheduler.GetFolder("").GetTask("Winget-AutoUpdate") - $sec = $task.GetSecurityDescriptor(0xF) - $sec = $sec + '(A;;GRGX;;;AU)' - $task.SetSecurityDescriptor($sec, 0) + #Set task readable/runnable for all users + $scheduler = New-Object -ComObject 'Schedule.Service' + $scheduler.Connect() + $task = $scheduler.GetFolder('').GetTask('Winget-AutoUpdate') + $sec = $task.GetSecurityDescriptor(0xF) + $sec = $sec + '(A;;GRGX;;;AU)' + $task.SetSecurityDescriptor($sec, 0) - # Configure Reg Key - $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - New-Item $regPath -Force | Out-Null - New-ItemProperty $regPath -Name DisplayName -Value "Winget-AutoUpdate (WAU)" -Force | Out-Null - New-ItemProperty $regPath -Name DisplayIcon -Value "C:\Windows\System32\shell32.dll,-16739" -Force | Out-Null - New-ItemProperty $regPath -Name DisplayVersion -Value $WAUVersion -Force | Out-Null - New-ItemProperty $regPath -Name InstallLocation -Value $WingetUpdatePath -Force | Out-Null - New-ItemProperty $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WingetUpdatePath\WAU-Uninstall.ps1`"" -Force | Out-Null - New-ItemProperty $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WingetUpdatePath\WAU-Uninstall.ps1`"" -Force | Out-Null - New-ItemProperty $regPath -Name NoModify -Value 1 -Force | Out-Null - New-ItemProperty $regPath -Name NoRepair -Value 1 -Force | Out-Null - New-ItemProperty $regPath -Name Publisher -Value "Romanitho" -Force | Out-Null - New-ItemProperty $regPath -Name URLInfoAbout -Value "https://github.com/Romanitho/Winget-AutoUpdate" -Force | Out-Null - New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $NotificationLevel -Force | Out-Null - if ($WAUVersion -match "-"){ - New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force | Out-Null - } - else { - New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null - } - New-ItemProperty $regPath -Name WAU_PostUpdateActions -Value 0 -PropertyType DWord -Force | Out-Null - New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $MaxLogFiles -PropertyType DWord -Force | Out-Null - New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $MaxLogSize -PropertyType DWord -Force | Out-Null - if ($DisableWAUAutoUpdate) { - New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force | Out-Null - } - if ($UseWhiteList) { - New-ItemProperty $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force | Out-Null - } - if (!$RunOnMetered) { - New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force | Out-Null - } - if ($ListPath) { - New-ItemProperty $regPath -Name WAU_ListPath -Value $ListPath -Force | Out-Null - } - if ($ModsPath) { - New-ItemProperty $regPath -Name WAU_ModsPath -Value $ModsPath -Force | Out-Null - } - if ($AzureBlobSASURL) { - New-ItemProperty $regPath -Name WAU_AzureBlobSASURL -Value $AzureBlobSASURL -Force | Out-Null - } - if ($BypassListForUsers) { - New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force | Out-Null - } + # Configure Reg Key + $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' + $null = New-Item $regPath -Force + $null = New-ItemProperty $regPath -Name DisplayName -Value 'Winget-AutoUpdate (WAU)' -Force + $null = New-ItemProperty $regPath -Name DisplayIcon -Value 'C:\Windows\System32\shell32.dll,-16739' -Force + $null = New-ItemProperty $regPath -Name DisplayVersion -Value $WAUVersion -Force + $null = New-ItemProperty $regPath -Name InstallLocation -Value $WingetUpdatePath -Force + $null = New-ItemProperty $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WingetUpdatePath\WAU-Uninstall.ps1`"" -Force + $null = New-ItemProperty $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WingetUpdatePath\WAU-Uninstall.ps1`"" -Force + $null = New-ItemProperty $regPath -Name NoModify -Value 1 -Force + $null = New-ItemProperty $regPath -Name NoRepair -Value 1 -Force + $null = New-ItemProperty $regPath -Name Publisher -Value 'Romanitho' -Force + $null = New-ItemProperty $regPath -Name URLInfoAbout -Value 'https://github.com/Romanitho/Winget-AutoUpdate' -Force + $null = New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $NotificationLevel -Force + if ($WAUVersion -match '-') + { + $null = New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force + } + else + { + $null = New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force + } + $null = New-ItemProperty $regPath -Name WAU_PostUpdateActions -Value 0 -PropertyType DWord -Force + $null = New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $MaxLogFiles -PropertyType DWord -Force + $null = New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $MaxLogSize -PropertyType DWord -Force + if ($DisableWAUAutoUpdate) + { + $null = New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force + } + if ($UseWhiteList) + { + $null = New-ItemProperty $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force + } + if (!$RunOnMetered) + { + $null = New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force + } + if ($ListPath) + { + $null = New-ItemProperty $regPath -Name WAU_ListPath -Value $ListPath -Force + } + if ($ModsPath) + { + $null = New-ItemProperty $regPath -Name WAU_ModsPath -Value $ModsPath -Force + } + if ($AzureBlobSASURL) + { + $null = New-ItemProperty $regPath -Name WAU_AzureBlobSASURL -Value $AzureBlobSASURL -Force + } + if ($BypassListForUsers) + { + $null = New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force + } - #Log file and symlink initialization - . "$WingetUpdatePath\functions\Start-Init.ps1" - Start-Init + #Log file and symlink initialization + . "$WingetUpdatePath\functions\Start-Init.ps1" + Start-Init - #Security check - Write-host "`nChecking Mods Directory:" -ForegroundColor Yellow - . "$WingetUpdatePath\functions\Invoke-ModsProtect.ps1" - $Protected = Invoke-ModsProtect "$WingetUpdatePath\mods" - if ($Protected -eq $True) { - Write-Host "The mods directory is now secured!`n" -ForegroundColor Green - } - elseif ($Protected -eq $False) { - Write-Host "The mods directory was already secured!`n" -ForegroundColor Green - } - else { - Write-Host "Error: The mods directory couldn't be verified as secured!`n" -ForegroundColor Red - } + #Security check + Write-Host -Object "`nChecking Mods Directory:" -ForegroundColor Yellow + . "$WingetUpdatePath\functions\Invoke-ModsProtect.ps1" + $Protected = Invoke-ModsProtect "$WingetUpdatePath\mods" + if ($Protected -eq $True) + { + Write-Host -Object "The mods directory is now secured!`n" -ForegroundColor Green + } + elseif ($Protected -eq $false) + { + Write-Host -Object "The mods directory was already secured!`n" -ForegroundColor Green + } + else + { + Write-Host -Object "Error: The mods directory couldn't be verified as secured!`n" -ForegroundColor Red + } - #Create Shortcuts - if ($StartMenuShortcut) { - if (!(Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { - New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" | Out-Null - } - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..." - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" "Open existing WAU logs..." - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" "Help for WAU..." - } + #Create Shortcuts + if ($StartMenuShortcut) + { + if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + { + $null = New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" + } + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' + } - if ($DesktopShortcut) { - Add-Shortcut "wscript.exe" "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..." - } + if ($DesktopShortcut) + { + Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' + } - Write-host "WAU Installation succeeded!" -ForegroundColor Green - Start-sleep 1 + Write-Host -Object 'WAU Installation succeeded!' -ForegroundColor Green + Start-Sleep -Seconds 1 - #Run Winget ? - Start-WingetAutoUpdate - } - catch { - Write-host "WAU Installation failed! Run me with admin rights" -ForegroundColor Red - Start-sleep 1 - return $False - } + #Run Winget ? + Start-WingetAutoUpdate + } + catch + { + Write-Host -Object 'WAU Installation failed! Run me with admin rights' -ForegroundColor Red + Start-Sleep -Seconds 1 + return $false + } } -function Uninstall-WingetAutoUpdate { +function Uninstall-WingetAutoUpdate +{ + Write-Host -Object "`nUninstalling WAU..." -ForegroundColor Yellow - Write-Host "`nUninstalling WAU..." -ForegroundColor Yellow + try + { + #Get registry install location + $InstallLocation = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation - try { - #Get registry install location - $InstallLocation = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\" -Name InstallLocation - - #Check if installed location exists and delete - if (Test-Path ($InstallLocation)) { - - if (!$NoClean) { - Remove-Item $InstallLocation -Force -Recurse - if (Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") { - Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -ErrorAction SilentlyContinue | Out-Null - } - if (Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log") { - Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -ErrorAction SilentlyContinue | Out-Null - } + #Check if installed location exists and delete + if (Test-Path ($InstallLocation)) + { + if (!$NoClean) + { + Remove-Item $InstallLocation -Force -Recurse + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") + { + $null = Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -ErrorAction SilentlyContinue } - else { - #Keep critical files - Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log") + { + $null = Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -ErrorAction SilentlyContinue } - Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - Get-ScheduledTask -TaskName "Winget-AutoUpdate-Notify" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - & reg delete "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /f | Out-Null - & reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" /f | Out-Null + } + else + { + #Keep critical files + Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force + } + Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false + Get-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false + Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false + $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f + $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f - if ((Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { - Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null - } + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + { + $null = Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force + } - if ((Test-Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { - Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null - } + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) + { + $null = Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force + } - Write-host "Uninstallation succeeded!" -ForegroundColor Green - Start-sleep 1 - } - else { - Write-host "$InstallLocation not found! Uninstallation failed!" -ForegroundColor Red - } - } - catch { - Write-host "Uninstallation failed! Run as admin ?" -ForegroundColor Red - Start-sleep 1 - } + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green + Start-Sleep -Seconds 1 + } + else + { + Write-Host -Object "$InstallLocation not found! Uninstallation failed!" -ForegroundColor Red + } + } + catch + { + Write-Host -Object 'Uninstallation failed! Run as admin ?' -ForegroundColor Red + Start-Sleep -Seconds 1 + } } -function Start-WingetAutoUpdate { - #If -DoNotUpdate is true, skip. - if (!($DoNotUpdate)) { - #If -Silent, run Winget-AutoUpdate now - if ($Silent) { +function Start-WingetAutoUpdate +{ + #If -DoNotUpdate is true, skip. + if (!($DoNotUpdate)) + { + #If -Silent, run Winget-AutoUpdate now + if ($Silent) + { + $RunWinget = 1 + } + #Ask for WingetAutoUpdate + else + { + $MsgBoxTitle = 'Winget-AutoUpdate' + $MsgBoxContent = 'Would you like to run Winget-AutoUpdate now?' + $MsgBoxTimeOut = 60 + $MsgBoxReturn = (New-Object -ComObject 'Wscript.Shell').Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) + if ($MsgBoxReturn -ne 7) + { $RunWinget = 1 - } - #Ask for WingetAutoUpdate - else { - $MsgBoxTitle = "Winget-AutoUpdate" - $MsgBoxContent = "Would you like to run Winget-AutoUpdate now?" - $MsgBoxTimeOut = 60 - $MsgBoxReturn = (New-Object -ComObject "Wscript.Shell").Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) - if ($MsgBoxReturn -ne 7) { - $RunWinget = 1 + } + else + { + $RunWinget = 0 + } + } + if ($RunWinget -eq 1) + { + try + { + Write-Host -Object "`nRunning Winget-AutoUpdate..." -ForegroundColor Yellow + Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue + while ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate').State -ne 'Ready') + { + Start-Sleep -Seconds 1 } - else { - $RunWinget = 0 - } - } - if ($RunWinget -eq 1) { - try { - Write-host "`nRunning Winget-AutoUpdate..." -ForegroundColor Yellow - Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue - while ((Get-ScheduledTask -TaskName "Winget-AutoUpdate").State -ne 'Ready') { - Start-Sleep 1 - } - } - catch { - Write-host "Failed to run Winget-AutoUpdate..." -ForegroundColor Red - } - } - } - else { - Write-host "Skip running Winget-AutoUpdate" - } + } + catch + { + Write-Host -Object 'Failed to run Winget-AutoUpdate...' -ForegroundColor Red + } + } + } + else + { + Write-Host -Object 'Skip running Winget-AutoUpdate' + } } -function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) { - $WScriptShell = New-Object -ComObject WScript.Shell - $Shortcut = $WScriptShell.CreateShortcut($Shortcut) - $Shortcut.TargetPath = $Target - $Shortcut.Arguments = $Arguments - $Shortcut.IconLocation = $Icon - $Shortcut.Description = $Description - $Shortcut.Save() +function Add-Shortcut +{ + [CmdletBinding()] + param + ( + $Target, + + $Shortcut, + + $Arguments, + + $Icon, + + $Description + ) + $WScriptShell = New-Object -ComObject WScript.Shell + $Shortcut = $WScriptShell.CreateShortcut($Shortcut) + $Shortcut.TargetPath = $Target + $Shortcut.Arguments = $Arguments + $Shortcut.IconLocation = $Icon + $Shortcut.Description = $Description + $Shortcut.Save() } <# APP INFO #> -$WAUVersion = Get-Content "$PSScriptRoot\Winget-AutoUpdate\Version.txt" -ErrorAction SilentlyContinue +$WAUVersion = Get-Content -Path "$PSScriptRoot\Winget-AutoUpdate\Version.txt" -ErrorAction SilentlyContinue <# MAIN #> #If running as a 32-bit process on an x64 system, re-launch as a 64-bit process -if ("$env:PROCESSOR_ARCHITEW6432" -ne "ARM64") { - if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe") { - Start-Process "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -Wait -NoNewWindow -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command $($MyInvocation.line)" - Exit $lastexitcode - } +if ("$env:PROCESSOR_ARCHITEW6432" -ne 'ARM64') +{ + if (Test-Path -Path "$($env:windir)\SysNative\WindowsPowerShell\v1.0\powershell.exe") + { + Start-Process -FilePath "$($env:windir)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -Wait -NoNewWindow -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command $($MyInvocation.line)" + Exit $lastexitcode + } } -Write-Host "`n" -Write-Host "`t 888 888 d8888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 o 888 d88888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 d8b 888 d88P888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 d888b 888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 888d88888b888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 88888P Y88888 d88P 888 888 888" -ForegroundColor Cyan -Write-Host "`t 8888P Y8888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 888P Y888 d88P 888 Y8888888P`n" -ForegroundColor Magenta -Write-Host "`t Winget-AutoUpdate $WAUVersion`n" -ForegroundColor Cyan -Write-Host "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta -Write-Host "`t________________________________________________________`n`n" +Write-Host -Object "`n" +Write-Host -Object "`t 888 888 d8888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 o 888 d88888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 d8b 888 d88P888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 d888b 888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888d88888b888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 88888P Y88888 d88P 888 888 888" -ForegroundColor Cyan +Write-Host -Object "`t 8888P Y8888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888P Y888 d88P 888 Y8888888P`n" -ForegroundColor Magenta +Write-Host -Object "`t Winget-AutoUpdate $WAUVersion`n" -ForegroundColor Cyan +Write-Host -Object "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta +Write-Host -Object "`t________________________________________________________`n`n" -if (!$Uninstall) { - Write-host "Installing WAU to $WingetUpdatePath\" - Install-Prerequisites - Install-WinGet - Install-WingetAutoUpdate +if (!$Uninstall) +{ + Write-Host -Object "Installing WAU to $WingetUpdatePath\" + Install-Prerequisites + Install-WinGet + Install-WingetAutoUpdate } -else { - Write-Host "Uninstalling WAU..." - Uninstall-WingetAutoUpdate +else +{ + Write-Host -Object 'Uninstalling WAU...' + Uninstall-WingetAutoUpdate } -Remove-Item "$WingetUpdatePath\Version.txt" -Force -Write-host "`nEnd of process." -ForegroundColor Cyan -Start-Sleep 3 +Remove-Item -Path "$WingetUpdatePath\Version.txt" -Force +Write-Host -Object "`nEnd of process." -ForegroundColor Cyan +Start-Sleep -Seconds 3 diff --git a/Winget-AutoUpdate/User-Run.ps1 b/Winget-AutoUpdate/User-Run.ps1 index 176fb26..bec2dea 100644 --- a/Winget-AutoUpdate/User-Run.ps1 +++ b/Winget-AutoUpdate/User-Run.ps1 @@ -1,32 +1,34 @@ <# -.SYNOPSIS -Handle user interaction from shortcuts and show a Toast notification + .SYNOPSIS + Handle user interaction from shortcuts and show a Toast notification -.DESCRIPTION -Act on shortcut run (DEFAULT: Check for updated Apps) + .DESCRIPTION + Act on shortcut run (DEFAULT: Check for updated Apps) -.PARAMETER Logs -Open the Log file from Winget-AutoUpdate installation location + .PARAMETER Logs + Open the Log file from Winget-AutoUpdate installation location -.PARAMETER Help -Open the Web Help page -https://github.com/Romanitho/Winget-AutoUpdate + .PARAMETER Help + Open the Web Help page + https://github.com/Romanitho/Winget-AutoUpdate -.EXAMPLE -.\user-run.ps1 -Logs + .EXAMPLE + .\user-run.ps1 -Logs #> [CmdletBinding()] param( - [Parameter(Mandatory = $False)] [Switch] $Logs = $false, - [Parameter(Mandatory = $False)] [Switch] $Help = $false + [Switch] $Logs = $False, + [Switch] $Help = $False ) -function Test-WAUisRunning { - If (((Get-ScheduledTask -TaskName 'Winget-AutoUpdate').State -eq 'Running') -or ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext').State -eq 'Running')) { - Return $True - } +function Test-WAUisRunning +{ + If (((Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue).State -eq 'Running') -or ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue).State -eq 'Running')) + { + Return $True + } } <# MAIN #> @@ -42,61 +44,72 @@ $Script:WorkingDir = $PSScriptRoot Get-NotifLocale #Set common variables -$OnClickAction = "$WorkingDir\logs\updates.log" +$OnClickAction = ('{0}\logs\updates.log' -f $WorkingDir) $Button1Text = $NotifLocale.local.outputs.output[11].message -if ($Logs) { - if (Test-Path "$WorkingDir\logs\updates.log") { - Invoke-Item "$WorkingDir\logs\updates.log" - } - else { - #Not available yet - $Message = $NotifLocale.local.outputs.output[5].message - $MessageType = "warning" - Start-NotifTask -Message $Message -MessageType $MessageType -UserRun - } +if ($Logs) +{ + if (Test-Path -Path ('{0}\logs\updates.log' -f $WorkingDir)) + { + Invoke-Item -Path ('{0}\logs\updates.log' -f $WorkingDir) + } + else + { + #Not available yet + $Message = $NotifLocale.local.outputs.output[5].message + $MessageType = 'warning' + Start-NotifTask -Message $Message -MessageType $MessageType -UserRun + } } -elseif ($Help) { - Start-Process "https://github.com/Romanitho/Winget-AutoUpdate" +elseif ($Help) +{ + Start-Process -FilePath 'https://github.com/Romanitho/Winget-AutoUpdate' } -else { - try { - #Check if WAU is currently running - if (Test-WAUisRunning) { - $Message = $NotifLocale.local.outputs.output[8].message - $MessageType = "warning" - Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun - break - } - #Run scheduled task - Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction Stop | Start-ScheduledTask -ErrorAction Stop - #Starting check - Send notification - $Message = $NotifLocale.local.outputs.output[6].message - $MessageType = "info" - Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun - #Sleep until the task is done - While (Test-WAUisRunning) { - Start-Sleep 3 - } +else +{ + try + { + # Check if WAU is currently running + if (Test-WAUisRunning) + { + $Message = $NotifLocale.local.outputs.output[8].message + $MessageType = 'warning' + Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun + break + } + # Run scheduled task + Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction Stop | Start-ScheduledTask -ErrorAction Stop + # Starting check - Send notification + $Message = $NotifLocale.local.outputs.output[6].message + $MessageType = 'info' + Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun + # Sleep until the task is done + While (Test-WAUisRunning) + { + Start-Sleep -Seconds 3 + } - #Test if there was a list_/winget_error - if (Test-Path "$WorkingDir\logs\error.txt") { - $MessageType = "error" - $Critical = Get-Content "$WorkingDir\logs\error.txt" -Raw - $Critical = $Critical.Trim() - $Critical = $Critical.Substring(0, [Math]::Min($Critical.Length, 50)) - $Message = "Critical:`n$Critical..." - } - else { - $MessageType = "success" - $Message = $NotifLocale.local.outputs.output[9].message - } - Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun - } - catch { - #Check failed - Just send notification - $Message = $NotifLocale.local.outputs.output[7].message - $MessageType = "error" - Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun - } + # Test if there was a list_/winget_error + if (Test-Path -Path ('{0}\logs\error.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + { + $MessageType = 'error' + $Critical = Get-Content -Path ('{0}\logs\error.txt' -f $WorkingDir) -Raw + $Critical = $Critical.Trim() + $Critical = $Critical.Substring(0, [Math]::Min($Critical.Length, 50)) + $Message = ("Critical:`n{0}..." -f $Critical) + } + else + { + $MessageType = 'success' + $Message = $NotifLocale.local.outputs.output[9].message + } + Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun + } + catch + { + # Check failed - Just send notification + $Message = $NotifLocale.local.outputs.output[7].message + $MessageType = 'error' + Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun + } } diff --git a/Winget-AutoUpdate/WAU-Uninstall.ps1 b/Winget-AutoUpdate/WAU-Uninstall.ps1 index ff10d8d..c715a9a 100644 --- a/Winget-AutoUpdate/WAU-Uninstall.ps1 +++ b/Winget-AutoUpdate/WAU-Uninstall.ps1 @@ -1,85 +1,96 @@ <# -.SYNOPSIS -Uninstall Winget-AutoUpdate + .SYNOPSIS + Uninstall Winget-AutoUpdate -.DESCRIPTION -Uninstalls Winget-AutoUpdate (DEFAULT: clean old install) -https://github.com/Romanitho/Winget-AutoUpdate + .DESCRIPTION + Uninstalls Winget-AutoUpdate (DEFAULT: clean old install) + https://github.com/Romanitho/Winget-AutoUpdate -.PARAMETER NoClean -Uninstall Winget-AutoUpdate (keep critical files) + .PARAMETER NoClean + Uninstall Winget-AutoUpdate (keep critical files) -.EXAMPLE -.\WAU-Uninstall.ps1 -NoClean + .EXAMPLE + .\WAU-Uninstall.ps1 -NoClean #> - [CmdletBinding()] param( - [Parameter(Mandatory = $False)] [Switch] $NoClean = $false + [Switch] $NoClean = $false ) -Write-Host "`n" -Write-Host "`t 888 888 d8888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 o 888 d88888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 d8b 888 d88P888 888 888" -ForegroundColor Magenta -Write-Host "`t 888 d888b 888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 888d88888b888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 88888P Y88888 d88P 888 888 888" -ForegroundColor Cyan -Write-Host "`t 8888P Y8888 d88P 888 888 888" -ForegroundColor Magenta -Write-Host "`t 888P Y888 d88P 888 Y8888888P`n" -ForegroundColor Magenta -Write-Host "`t Winget-AutoUpdate`n" -ForegroundColor Cyan -Write-Host "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta -Write-Host "`t________________________________________________________`n`n" +Write-Host -Object "`n" +Write-Host -Object "`t 888 888 d8888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 o 888 d88888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 d8b 888 d88P888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888 d888b 888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888d88888b888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 88888P Y88888 d88P 888 888 888" -ForegroundColor Cyan +Write-Host -Object "`t 8888P Y8888 d88P 888 888 888" -ForegroundColor Magenta +Write-Host -Object "`t 888P Y888 d88P 888 Y8888888P`n" -ForegroundColor Magenta +Write-Host -Object "`t Winget-AutoUpdate`n" -ForegroundColor Cyan +Write-Host -Object "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta +Write-Host -Object "`t________________________________________________________`n`n" -try { - Write-host "Uninstalling WAU..." -ForegroundColor Yellow - #Get registry install location - $InstallLocation = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\" -Name InstallLocation +try +{ + Write-Host -Object 'Uninstalling WAU...' -ForegroundColor Yellow - #Check if installed location exists and delete - if (Test-Path ($InstallLocation)) { + # Get registry install location + $InstallLocation = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation) - if (!$NoClean) { - Remove-Item "$InstallLocation\*" -Force -Recurse -Exclude "*.log" - } - else { - #Keep critical files - Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force - } - Get-ScheduledTask -TaskName "Winget-AutoUpdate" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - Get-ScheduledTask -TaskName "Winget-AutoUpdate-Notify" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - & reg delete "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /f | Out-Null - & reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" /f | Out-Null - if (Test-Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate") { - & reg delete "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" /f | Out-Null - } + # Check if installed location exists and delete + if (Test-Path -Path ($InstallLocation)) + { + if (!$NoClean) + { + $null = (Remove-Item -Path ('{0}\*' -f $InstallLocation) -Force -Confirm:$false -Recurse -Exclude '*.log') + } + else + { + # Keep critical files + $null = (Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue) + } + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false) + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false) + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false) + $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f + $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f + + if (Test-Path -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' -ErrorAction SilentlyContinue) + { + $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f + } - if ((Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { - Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null - } + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + { + $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) + } - if ((Test-Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { - Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null - } + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) + { + $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) + } - #Remove Intune Logs if they are existing - if (Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") { - Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -ErrorAction SilentlyContinue | Out-Null - } - if (Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log") { - Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -ErrorAction SilentlyContinue | Out-Null - } + # Remove Intune Logs if they are existing + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") + { + $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -Confirm:$false -ErrorAction SilentlyContinue) + } + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue) + { + $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -Confirm:$false -ErrorAction SilentlyContinue) + } - Write-host "Uninstallation succeeded!" -ForegroundColor Green - } - else { - Write-host "$InstallLocation not found! Uninstallation failed!" -ForegroundColor Red - } + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green + } + else + { + Write-Host -Object ('{0} not found! Uninstallation failed!' -f $InstallLocation) -ForegroundColor Red + } } -catch { - Write-host "`nUninstallation failed! Run as admin ?" -ForegroundColor Red +catch +{ + Write-Host -Object "`nUninstallation failed! Run as admin ?" -ForegroundColor Red } -Start-sleep 2 +Start-Sleep -Seconds 2 diff --git a/Winget-AutoUpdate/Winget-Notify.ps1 b/Winget-AutoUpdate/Winget-Notify.ps1 index de22ef7..e6036cf 100644 --- a/Winget-AutoUpdate/Winget-Notify.ps1 +++ b/Winget-AutoUpdate/Winget-Notify.ps1 @@ -1,24 +1,29 @@ -#Send Notify Script +# Send Notify Script -#get xml notif config -$WAUinstalledPath = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\" -Name InstallLocation -[xml]$NotifConf = Get-Content "$WAUinstalledPath\config\notif.xml" -Encoding UTF8 -ErrorAction SilentlyContinue -if (!($NotifConf)) { - break +# get xml notif config +$WAUinstalledPath = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation) +[xml]$NotifConf = (Get-Content -Path "$WAUinstalledPath\config\notif.xml" -Encoding UTF8 -ErrorAction SilentlyContinue) + +if (!($NotifConf)) +{ + break } -#Load Assemblies -[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null -[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null +# Load Assemblies +$null = (Add-Type -AssemblyName Windows.Data) +$null = (Add-Type -AssemblyName Windows.UI) -#Prepare XML +$null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] +$null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] + +# Prepare XML $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New() $ToastXml.LoadXml($NotifConf.OuterXml) -#Specify Launcher App ID -$LauncherID = "Windows.SystemToast.Winget.Notification" +# Specify Launcher App ID +$LauncherID = 'Windows.SystemToast.Winget.Notification' -#Prepare and Create Toast -$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXML) +# Prepare and Create Toast +$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) $ToastMessage.Tag = $NotifConf.toast.tag [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) diff --git a/Winget-AutoUpdate/Winget-Upgrade.ps1 b/Winget-AutoUpdate/Winget-Upgrade.ps1 index 25cfbc7..f36eb8e 100644 --- a/Winget-AutoUpdate/Winget-Upgrade.ps1 +++ b/Winget-AutoUpdate/Winget-Upgrade.ps1 @@ -1,60 +1,60 @@ <# LOAD FUNCTIONS #> -#Get the Working Dir +# Get the Working Dir $Script:WorkingDir = $PSScriptRoot -#Get Functions -Get-ChildItem "$WorkingDir\functions" | ForEach-Object { . $_.FullName } +# Get Functions +Get-ChildItem -Path "$WorkingDir\functions" | ForEach-Object { . $_.FullName } <# MAIN #> -#Check if running account is system or interactive logon -$Script:IsSystem = [System.Security.Principal.WindowsIdentity]::GetCurrent().IsSystem +# Check if running account is system or interactive logon +$Script:IsSystem = [Security.Principal.WindowsIdentity]::GetCurrent().IsSystem -#Run log initialisation function +# Run log initialisation function Start-Init -#Get WAU Configurations -$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" +# Get WAU Configurations +$Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') #Log running context and more... if ($IsSystem) { - Write-ToLog "Running in System context" + Write-ToLog 'Running in System context' #Get and set Domain/Local Policies (GPO) $ActivateGPOManagement, $ChangedSettings = Get-Policies if ($ActivateGPOManagement) { - Write-ToLog "Activated WAU GPO Management detected, comparing..." + Write-ToLog 'Activated WAU GPO Management detected, comparing...' if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { - Write-ToLog "Changed settings detected and applied" "Yellow" + Write-ToLog 'Changed settings detected and applied' 'Yellow' } else { - Write-ToLog "No Changed settings detected" "Yellow" + Write-ToLog 'No Changed settings detected' 'Yellow' } } # Maximum number of log files to keep. Default is 3. Setting MaxLogFiles to 0 will keep all log files. $MaxLogFiles = $WAUConfig.WAU_MaxLogFiles if ($null -eq $MaxLogFiles) { - [int32] $MaxLogFiles = 3 + [int] $MaxLogFiles = 3 } else { - [int32] $MaxLogFiles = $MaxLogFiles + [int] $MaxLogFiles = $MaxLogFiles } # Maximum size of log file. $MaxLogSize = $WAUConfig.WAU_MaxLogSize if (!$MaxLogSize) { - [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB + [long] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB } else { - [int64] $MaxLogSize = $MaxLogSize + [long] $MaxLogSize = $MaxLogSize } #LogRotation if System $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize if ($LogRotate -eq $False) { - Write-ToLog "An Exception occured during Log Rotation..." + Write-ToLog 'An Exception occured during Log Rotation...' } #Run post update actions if necessary if run as System @@ -66,12 +66,12 @@ if ($IsSystem) { Add-ScopeMachine $SettingsPath } else { - Write-ToLog "Running in User context" + Write-ToLog 'Running in User context' } #Get Notif Locale function $LocaleDisplayName = Get-NotifLocale -Write-ToLog "Notification Level: $($WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" "Cyan" +Write-ToLog "Notification Level: $($WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" 'Cyan' #Check network connectivity if (Test-Network) { @@ -87,61 +87,61 @@ if (Test-Network) { $WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate #If yes then check WAU update if run as System if ($WAUDisableAutoUpdate -eq 1) { - Write-ToLog "WAU AutoUpdate is Disabled." "Gray" + Write-ToLog 'WAU AutoUpdate is Disabled.' 'Gray' } else { - Write-ToLog "WAU AutoUpdate is Enabled." "Green" + Write-ToLog 'WAU AutoUpdate is Enabled.' 'Green' #Get Available Version $Script:WAUAvailableVersion = Get-WAUAvailableVersion #Compare - if ([version]$WAUAvailableVersion.Replace("-", ".") -ne [version]$WAUCurrentVersion.Replace("-", ".")) { + if ([version]$WAUAvailableVersion.Replace('-', '.') -ne [version]$WAUCurrentVersion.Replace('-', '.')) { #If new version is available, update it - Write-ToLog "WAU Available version: $WAUAvailableVersion" "Yellow" + Write-ToLog "WAU Available version: $WAUAvailableVersion" 'Yellow' Update-WAU } else { - Write-ToLog "WAU is up to date." "Green" + Write-ToLog 'WAU is up to date.' 'Green' } } #Delete previous list_/winget_error (if they exist) if run as System - if (Test-Path "$WorkingDir\logs\error.txt") { - Remove-Item "$WorkingDir\logs\error.txt" -Force + if (Test-Path -Path "$WorkingDir\logs\error.txt") { + Remove-Item -Path "$WorkingDir\logs\error.txt" -Force } #Get External ListPath if run as System if ($WAUConfig.WAU_ListPath) { - $ListPathClean = $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/")) + $ListPathClean = $($WAUConfig.WAU_ListPath.TrimEnd(' ', '\', '/')) Write-ToLog "WAU uses External Lists from: $ListPathClean" - if ($ListPathClean -ne "GPO") { - $NewList = Test-ListPath $ListPathClean $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(" ", "\") + if ($ListPathClean -ne 'GPO') { + $NewList = Test-ListPath $ListPathClean $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(' ', '\') if ($ReachNoPath) { - Write-ToLog "Couldn't reach/find/compare/copy from $ListPathClean..." "Red" - if ($ListPathClean -notlike "http*") { + Write-ToLog "Couldn't reach/find/compare/copy from $ListPathClean..." 'Red' + if ($ListPathClean -notlike 'http*') { if (Test-Path -Path "$ListPathClean" -PathType Leaf) { - Write-ToLog "PATH must end with a Directory, not a File..." "Red" + Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' } } else { - if ($ListPathClean -match "_apps.txt") { - Write-ToLog "PATH must end with a Directory, not a File..." "Red" + if ($ListPathClean -match '_apps.txt') { + Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' } } $Script:ReachNoPath = $False } if ($NewList) { - Write-ToLog "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))" "Yellow" + Write-ToLog "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))" 'Yellow' } else { - if ($WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\included_apps.txt")) { - Write-ToLog "List (white) is up to date." "Green" + if ($WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\included_apps.txt")) { + Write-ToLog 'List (white) is up to date.' 'Green' } - elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\excluded_apps.txt")) { - Write-ToLog "List (black) is up to date." "Green" + elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\excluded_apps.txt")) { + Write-ToLog 'List (black) is up to date.' 'Green' } else { - Write-ToLog "Critical: White/Black List doesn't exist, exiting..." "Red" - New-Item "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist" -Force + Write-ToLog "Critical: White/Black List doesn't exist, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist" -Force Exit 1 } } @@ -150,62 +150,62 @@ if (Test-Network) { #Get External ModsPath if run as System if ($WAUConfig.WAU_ModsPath) { - $ModsPathClean = $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/")) + $ModsPathClean = $($WAUConfig.WAU_ModsPath.TrimEnd(' ', '\', '/')) Write-ToLog "WAU uses External Mods from: $ModsPathClean" if ($WAUConfig.WAU_AzureBlobSASURL) { - $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(" ", "\") $WAUConfig.WAU_AzureBlobSASURL.TrimEnd(" ") + $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') $WAUConfig.WAU_AzureBlobSASURL.TrimEnd(' ') } else { - $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(" ", "\") + $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') } if ($ReachNoPath) { - Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." "Red" + Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." 'Red' $Script:ReachNoPath = $False } if ($NewMods -gt 0) { - Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Yellow" + Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Yellow' } else { - if (Test-Path "$WorkingDir\mods\*.ps1") { - Write-ToLog "Mods are up to date." "Green" + if (Test-Path -Path "$WorkingDir\mods\*.ps1") { + Write-ToLog 'Mods are up to date.' 'Green' } else { - Write-ToLog "No Mods are implemented..." "Yellow" + Write-ToLog 'No Mods are implemented...' 'Yellow' } } if ($DeletedMods -gt 0) { - Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Red" + Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Red' } } #Test if _WAU-mods.ps1 exist: Mods for WAU (if Network is active/any Winget is installed/running as SYSTEM) $Mods = "$WorkingDir\mods" - if (Test-Path "$Mods\_WAU-mods.ps1") { - Write-ToLog "Running Mods for WAU..." "Yellow" + if (Test-Path -Path "$Mods\_WAU-mods.ps1") { + Write-ToLog 'Running Mods for WAU...' 'Yellow' & "$Mods\_WAU-mods.ps1" $ModsExitCode = $LASTEXITCODE #If _WAU-mods.ps1 has ExitCode 1 - Re-run WAU if ($ModsExitCode -eq 1) { - Write-ToLog "Re-run WAU" - Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" + Write-ToLog 'Re-run WAU' + Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" Exit } } } - if ($($WAUConfig.WAU_ListPath) -eq "GPO") { + if ($($WAUConfig.WAU_ListPath) -eq 'GPO') { $Script:GPOList = $True } #Get White or Black list if ($WAUConfig.WAU_UseWhiteList -eq 1) { - Write-ToLog "WAU uses White List config" + Write-ToLog 'WAU uses White List config' $toUpdate = Get-IncludedApps $UseWhiteList = $true } else { - Write-ToLog "WAU uses Black List config" + Write-ToLog 'WAU uses Black List config' $toSkip = Get-ExcludedApps } @@ -214,8 +214,8 @@ if (Test-Network) { if ($UseWhiteList) { $WhiteList = $toUpdate.GetUpperBound(0) if ($null -eq $WhiteList) { - Write-ToLog "Critical: Whitelist doesn't exist in GPO, exiting..." "Red" - New-Item "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force + Write-ToLog "Critical: Whitelist doesn't exist in GPO, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force Exit 1 } $toUpdate = $toUpdate.Data @@ -223,8 +223,8 @@ if (Test-Network) { else { $BlackList = $toSkip.GetUpperBound(0) if ($null -eq $BlackList) { - Write-ToLog "Critical: Blacklist doesn't exist in GPO, exiting..." "Red" - New-Item "$WorkingDir\logs\error.txt" -Value "Blacklist doesn't exist in GPO" -Force + Write-ToLog "Critical: Blacklist doesn't exist in GPO, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "Blacklist doesn't exist in GPO" -Force Exit 1 } $toSkip = $toSkip.Data @@ -232,12 +232,12 @@ if (Test-Network) { } #Get outdated Winget packages - Write-ToLog "Checking application updates on Winget Repository..." "yellow" + Write-ToLog 'Checking application updates on Winget Repository...' 'yellow' $outdated = Get-WingetOutdatedApps #If something unusual happened - if ($outdated -like "An unusual*") { - Write-ToLog "$outdated" "cyan" + if ($outdated -like 'An unusual*') { + Write-ToLog "$outdated" 'cyan' $outdated = $False } @@ -256,7 +256,7 @@ if (Test-Network) { #Trick under user context when -BypassListForUsers is used if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq 1) { - Write-ToLog "Bypass system list in user context is Enabled." + Write-ToLog 'Bypass system list in user context is Enabled.' $UseWhiteList = $false $toSkip = $null } @@ -265,16 +265,16 @@ if (Test-Network) { if ($UseWhiteList) { #For each app, notify and update foreach ($app in $outdated) { - if (($toUpdate -contains $app.Id) -and $($app.Version) -ne "Unknown") { + if (($toUpdate -contains $app.Id) -and $($app.Version) -ne 'Unknown') { Update-App $app } #if current app version is unknown - elseif ($($app.Version) -eq "Unknown") { - Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" + elseif ($($app.Version) -eq 'Unknown') { + Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' } #if app is in "excluded list" else { - Write-ToLog "$($app.Name) : Skipped upgrade because it is not in the included app list" "Gray" + Write-ToLog "$($app.Name) : Skipped upgrade because it is not in the included app list" 'Gray' } } } @@ -282,27 +282,27 @@ if (Test-Network) { else { #For each app, notify and update foreach ($app in $outdated) { - if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne "Unknown") { + if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne 'Unknown') { Update-App $app } #if current app version is unknown - elseif ($($app.Version) -eq "Unknown") { - Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" + elseif ($($app.Version) -eq 'Unknown') { + Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' } #if app is in "excluded list" else { - Write-ToLog "$($app.Name) : Skipped upgrade because it is in the excluded app list" "Gray" + Write-ToLog "$($app.Name) : Skipped upgrade because it is in the excluded app list" 'Gray' } } } if ($InstallOK -gt 0) { - Write-ToLog "$InstallOK apps updated ! No more update." "Green" + Write-ToLog "$InstallOK apps updated ! No more update." 'Green' } } if ($InstallOK -eq 0 -or !$InstallOK) { - Write-ToLog "No new update." "Green" + Write-ToLog 'No new update.' 'Green' } #Check if any user is logged on if System and run User task (if installed) @@ -310,36 +310,36 @@ if (Test-Network) { #User check routine from: https://stackoverflow.com/questions/23219718/powershell-script-to-see-currently-logged-in-users-domain-and-machine-status $explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue) If ($explorerprocesses.Count -eq 0) { - Write-ToLog "No explorer process found / Nobody interactively logged on..." + Write-ToLog 'No explorer process found / Nobody interactively logged on...' } Else { #Run WAU in user context if the user task exist - $UserScheduledTask = Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue + $UserScheduledTask = Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue if ($UserScheduledTask) { #Get Winget system apps to excape them befor running user context - Write-ToLog "User logged on, get a list of installed Winget apps in System context..." + Write-ToLog 'User logged on, get a list of installed Winget apps in System context...' Get-WingetSystemApps #Run user context scheduled task - Write-ToLog "Starting WAU in User context" - Start-ScheduledTask $UserScheduledTask.TaskName -ErrorAction SilentlyContinue + Write-ToLog 'Starting WAU in User context' + Start-ScheduledTask -TaskName $UserScheduledTask.TaskName -ErrorAction SilentlyContinue Exit 0 } elseif (!$UserScheduledTask) { - Write-ToLog "User context execution not installed..." + Write-ToLog 'User context execution not installed...' } } } } else { - Write-ToLog "Critical: Winget not installed or detected, exiting..." "red" - New-Item "$WorkingDir\logs\error.txt" -Value "Winget not installed or detected" -Force - Write-ToLog "End of process!" "Cyan" + Write-ToLog 'Critical: Winget not installed or detected, exiting...' 'red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value 'Winget not installed or detected' -Force + Write-ToLog 'End of process!' 'Cyan' Exit 1 } } #End -Write-ToLog "End of process!" "Cyan" -Start-Sleep 3 +Write-ToLog 'End of process!' 'Cyan' +Start-Sleep -Seconds 3 diff --git a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 index 44bb7e4..5ff4832 100644 --- a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 +++ b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 @@ -1,20 +1,38 @@ -#Function to configure the prefered scope option as Machine -function Add-ScopeMachine ($SettingsPath) { +# Function to configure the prefered scope option as Machine +function Add-ScopeMachine +{ + [CmdletBinding()] + param + ( + [string]$SettingsPath + ) + + if (Test-Path -Path $SettingsPath -ErrorAction SilentlyContinue) + { + $ConfigFile = (Get-Content -Path $SettingsPath -ErrorAction SilentlyContinue | Where-Object -FilterScript { + ($_ -notmatch '//') + } | ConvertFrom-Json) + } - if (Test-Path $SettingsPath) { - $ConfigFile = Get-Content -Path $SettingsPath | Where-Object { $_ -notmatch '//' } | ConvertFrom-Json - } - if (!$ConfigFile) { - $ConfigFile = @{} - } - if ($ConfigFile.installBehavior.preferences.scope) { - $ConfigFile.installBehavior.preferences.scope = "Machine" - } - else { - $Scope = New-Object PSObject -Property $(@{scope = "Machine" }) - $Preference = New-Object PSObject -Property $(@{preferences = $Scope }) - Add-Member -InputObject $ConfigFile -MemberType NoteProperty -Name 'installBehavior' -Value $Preference -Force - } - $ConfigFile | ConvertTo-Json | Out-File $SettingsPath -Encoding utf8 -Force + if (!$ConfigFile) + { + $ConfigFile = @{} + } + if ($ConfigFile.installBehavior.preferences.scope) + { + $ConfigFile.installBehavior.preferences.scope = 'Machine' + } + else + { + $Scope = (New-Object -TypeName PSObject -Property $(@{ + scope = 'Machine' + })) + $Preference = (New-Object -TypeName PSObject -Property $(@{ + preferences = $Scope + })) + $null = (Add-Member -InputObject $ConfigFile -MemberType NoteProperty -Name 'installBehavior' -Value $Preference -Force) + } + + $null = ($ConfigFile | ConvertTo-Json | Out-File -FilePath $SettingsPath -Encoding utf8 -Force -Confirm:$false) } diff --git a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 index 98b6e77..e050281 100644 --- a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 +++ b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 @@ -1,10 +1,21 @@ -#Function to create shortcuts -function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) { - $WScriptShell = New-Object -ComObject WScript.Shell - $Shortcut = $WScriptShell.CreateShortcut($Shortcut) - $Shortcut.TargetPath = $Target - $Shortcut.Arguments = $Arguments - $Shortcut.IconLocation = $Icon - $Shortcut.Description = $Description - $Shortcut.Save() +# Function to create shortcuts +function Add-Shortcut +{ + [CmdletBinding()] + param + ( + [string]$Target, + [string]$Shortcut, + [string]$Arguments, + [string]$Icon, + [string]$Description + ) + + $WScriptShell = (New-Object -ComObject WScript.Shell) + $Shortcut = $WScriptShell.CreateShortcut($Shortcut) + $Shortcut.TargetPath = $Target + $Shortcut.Arguments = $Arguments + $Shortcut.IconLocation = $Icon + $Shortcut.Description = $Description + $Shortcut.Save() } diff --git a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 index e96b66d..c676e26 100644 --- a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 +++ b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 @@ -1,27 +1,39 @@ -Function Confirm-Installation ($AppName, $AppVer){ +Function Confirm-Installation +{ + # Set json export file + + [CmdletBinding()] + param + ( + [string]$AppName, + [string]$AppVer + ) - #Set json export file - $JsonFile = "$WorkingDir\Config\InstalledApps.json" + $JsonFile = ('{0}\Config\InstalledApps.json' -f $WorkingDir) - #Get installed apps and version in json file - & $Winget export -s winget -o $JsonFile --include-versions | Out-Null + # Get installed apps and version in json file + $null = (& $Winget export -s winget -o $JsonFile --include-versions) - #Get json content - $Json = Get-Content $JsonFile -Raw | ConvertFrom-Json + # Get json content + $Json = (Get-Content -Path $JsonFile -Raw | ConvertFrom-Json) - #Get apps and version in hashtable - $Packages = $Json.Sources.Packages + # Get apps and version in hashtable + $Packages = $Json.Sources.Packages - #Remove json file - Remove-Item $JsonFile -Force + # Remove json file + $null = (Remove-Item -Path $JsonFile -Force -Confirm:$false -ErrorAction SilentlyContinue) - # Search for specific app and version - $Apps = $Packages | Where-Object { $_.PackageIdentifier -eq $AppName -and $_.Version -like "$AppVer*"} + # Search for specific app and version + $Apps = $Packages | Where-Object -FilterScript { + ($_.PackageIdentifier -eq $AppName -and $_.Version -like ('{0}*' -f $AppVer)) + } - if ($Apps){ - return $true - } - else{ - return $false - } -} \ No newline at end of file + if ($Apps) + { + return $true + } + else + { + return $false + } +} diff --git a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 index e6f7d54..b8da39a 100644 --- a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 +++ b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 @@ -1,50 +1,58 @@ -#Function to get AZCopy, if it doesn't exist and update it, if it does +# Function to get AZCopy, if it doesn't exist and update it, if it does -Function Get-AZCopy ($WingetUpdatePath) { +Function Get-AZCopy +{ + [CmdletBinding()] + param + ( + [string]$WingetUpdatePath + ) - $AZCopyLink = (Invoke-WebRequest -Uri https://aka.ms/downloadazcopy-v10-windows -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue).headers.location - $AZCopyVersionRegex = [regex]::new("(\d+\.\d+\.\d+)") - $AZCopyLatestVersion = $AZCopyVersionRegex.Match($AZCopyLink).Value + $AZCopyLink = (Invoke-WebRequest -Uri https://aka.ms/downloadazcopy-v10-windows -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue).headers.location + $AZCopyVersionRegex = [regex]::new('(\d+\.\d+\.\d+)') + $AZCopyLatestVersion = $AZCopyVersionRegex.Match($AZCopyLink).Value - if ($null -eq $AZCopyLatestVersion -or "" -eq $AZCopyLatestVersion) { - $AZCopyLatestVersion = "0.0.0" - } + if ($null -eq $AZCopyLatestVersion -or '' -eq $AZCopyLatestVersion) + { + $AZCopyLatestVersion = '0.0.0' + } - if (Test-Path -Path "$WingetUpdatePath\azcopy.exe" -PathType Leaf) { - $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v - $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value - Write-ToLog "AZCopy version $AZCopyCurrentVersion found" - } - else { - Write-ToLog "AZCopy not already installed" - $AZCopyCurrentVersion = "0.0.0" - } + if (Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf -ErrorAction SilentlyContinue) + { + $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v + $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value + Write-ToLog -LogMsg ('AZCopy version {0} found' -f $AZCopyCurrentVersion) + } + else + { + Write-ToLog -LogMsg 'AZCopy not already installed' + $AZCopyCurrentVersion = '0.0.0' + } - if (([version] $AZCopyCurrentVersion) -lt ([version] $AZCopyLatestVersion)) { - Write-ToLog "Installing version $AZCopyLatestVersion of AZCopy" - Invoke-WebRequest -Uri $AZCopyLink -UseBasicParsing -OutFile "$WingetUpdatePath\azcopyv10.zip" - Write-ToLog "Extracting AZCopy zip file" + if (([version] $AZCopyCurrentVersion) -lt ([version] $AZCopyLatestVersion)) + { + Write-ToLog -LogMsg ('Installing version {0} of AZCopy' -f $AZCopyLatestVersion) + $null = (Invoke-WebRequest -Uri $AZCopyLink -UseBasicParsing -OutFile ('{0}\azcopyv10.zip' -f $WingetUpdatePath)) + Write-ToLog -LogMsg 'Extracting AZCopy zip file' + $null = (Expand-Archive -Path ('{0}\azcopyv10.zip' -f $WingetUpdatePath) -DestinationPath $WingetUpdatePath -Force -Confirm:$false) + $AZCopyPathSearch = (Resolve-Path -Path ('{0}\azcopy_*' -f $WingetUpdatePath)) - Expand-archive -Path "$WingetUpdatePath\azcopyv10.zip" -Destinationpath "$WingetUpdatePath" -Force + if ($AZCopyPathSearch -is [array]) + { + $AZCopyEXEPath = $AZCopyPathSearch[$AZCopyPathSearch.Length - 1] + } + else + { + $AZCopyEXEPath = $AZCopyPathSearch + } - $AZCopyPathSearch = Resolve-Path -path "$WingetUpdatePath\azcopy_*" - - if ($AZCopyPathSearch -is [array]) { - $AZCopyEXEPath = $AZCopyPathSearch[$AZCopyPathSearch.Length - 1] - } - else { - $AZCopyEXEPath = $AZCopyPathSearch - } - - Write-ToLog "Copying 'azcopy.exe' to main folder" - Copy-Item "$AZCopyEXEPath\azcopy.exe" -Destination "$WingetUpdatePath\" - - Write-ToLog "Removing temporary AZCopy files" - Remove-Item -Path $AZCopyEXEPath -Recurse - Remove-Item -Path "$WingetUpdatePath\azcopyv10.zip" - - $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v - $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value - Write-ToLog "AZCopy version $AZCopyCurrentVersion installed" - } -} \ No newline at end of file + Write-ToLog -LogMsg "Copying 'azcopy.exe' to main folder" + $null = (Copy-Item -Path ('{0}\azcopy.exe' -f $AZCopyEXEPath) -Destination ('{0}\' -f $WingetUpdatePath) -Force -Confirm:$false) + Write-ToLog -LogMsg 'Removing temporary AZCopy files' + $null = (Remove-Item -Path $AZCopyEXEPath -Recurse -Force -Confirm:$false) + $null = (Remove-Item -Path ('{0}\azcopyv10.zip' -f $WingetUpdatePath) -Force -Confirm:$false) + $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v + $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value + Write-ToLog -LogMsg ('AZCopy version {0} installed' -f $AZCopyCurrentVersion) + } +} diff --git a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 index 747a818..e6b32fd 100644 --- a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 +++ b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 @@ -1,12 +1,18 @@ -#Get the winget App Information +# Get the winget App Information -Function Get-AppInfo ($AppID) { - #Get AppID Info - $String = & $winget show $AppID --accept-source-agreements -s winget | Out-String +Function Get-AppInfo +{ + # Get AppID Info + [CmdletBinding()] + param + ( + [string]$AppID + ) - #Search for Release Note info - $ReleaseNote = [regex]::match($String, "(?<=Release Notes Url: )(.*)(?=\n)").Groups[0].Value + $String = (& $winget show $AppID --accept-source-agreements -s winget | Out-String) + # Search for Release Note info + $ReleaseNote = [regex]::match($String, '(?<=Release Notes Url: )(.*)(?=\n)').Groups[0].Value - #Return Release Note - return $ReleaseNote + # Return Release Note + return $ReleaseNote } diff --git a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 index 0212e5c..63f42b8 100644 --- a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 @@ -1,31 +1,31 @@ #Function to get the Block List apps -function Get-ExcludedApps { +function Get-ExcludedApps +{ + if ($GPOList) + { + if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList' -ErrorAction SilentlyContinue) + { + $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList\' - if ($GPOList) { + $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList').Property - if (Test-Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList") { - - $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList\' - - $ValueNames = (Get-Item -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList").Property - - foreach ($ValueName in $ValueNames) { - $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) - [PSCustomObject]@{ - Value = $ValueName - Data = $AppIDs.Trim() - } + foreach ($ValueName in $ValueNames) + { + $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) + [PSCustomObject]@{ + Value = $ValueName + Data = $AppIDs.Trim() } + } + } - } - return $AppIDs - - } - elseif (Test-Path "$WorkingDir\excluded_apps.txt") { - - return (Get-Content -Path "$WorkingDir\excluded_apps.txt").Trim() | Where-Object { $_.length -gt 0 } - - } - + return $AppIDs + } + elseif (Test-Path -Path ('{0}\excluded_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + { + return (Get-Content -Path ('{0}\excluded_apps.txt' -f $WorkingDir)).Trim() | Where-Object -FilterScript { + $_.length -gt 0 + } + } } diff --git a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 index ae2a8ad..09e9d79 100644 --- a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 @@ -1,31 +1,30 @@ -#Function to get the allow List apps +# Function to get the allow List apps -function Get-IncludedApps { +function Get-IncludedApps +{ + if ($GPOList) + { + if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList' -ErrorAction SilentlyContinue) + { + $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList\' + $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList').Property - if ($GPOList) { - - if (Test-Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList") { - - $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList\' - - $ValueNames = (Get-Item -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList").Property - - foreach ($ValueName in $ValueNames) { - $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) - [PSCustomObject]@{ - Value = $ValueName - Data = $AppIDs.Trim() - } + foreach ($ValueName in $ValueNames) + { + $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) + [PSCustomObject]@{ + Value = $ValueName + Data = $AppIDs.Trim() } - - } - return $AppIDs - - } - elseif (Test-Path "$WorkingDir\included_apps.txt") { - - return (Get-Content -Path "$WorkingDir\included_apps.txt").Trim() | Where-Object { $_.length -gt 0 } - - } - + } + } + + return $AppIDs + } + elseif (Test-Path -Path ('{0}\included_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + { + return (Get-Content -Path ('{0}\included_apps.txt' -f $WorkingDir)).Trim() | Where-Object -FilterScript { + $_.length -gt 0 + } + } } diff --git a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 index f0bd3a2..63254bd 100644 --- a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 +++ b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 @@ -2,27 +2,27 @@ Function Get-NotifLocale { - #Get OS locale + # Get OS locale $OSLocale = (Get-UICulture).Parent - #Test if OS locale notif file exists - $TestOSLocalPath = "$WorkingDir\locale\$($OSLocale.Name).xml" + # Test if OS locale notif file exists + $TestOSLocalPath = ('{0}\locale\{1}.xml' -f $WorkingDir, $OSLocale.Name) - #Set OS Local if file exists - if (Test-Path $TestOSLocalPath) { + # Set OS Local if file exists + if (Test-Path -Path $TestOSLocalPath -ErrorAction SilentlyContinue) { $LocaleDisplayName = $OSLocale.DisplayName $LocaleFile = $TestOSLocalPath } - #Set English if file doesn't exist else { - $LocaleDisplayName = "English" - $LocaleFile = "$WorkingDir\locale\en.xml" + # Set English if file doesn't exist + $LocaleDisplayName = 'English' + $LocaleFile = ('{0}\locale\en.xml' -f $WorkingDir) } - #Get locale XML file content - [xml]$Script:NotifLocale = Get-Content $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue + # Get locale XML file content + [xml]$Script:NotifLocale = (Get-Content -Path $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue) - #Rerturn langague display name + # Rerturn langague display name Return $LocaleDisplayName } diff --git a/Winget-AutoUpdate/functions/Get-Policies.ps1 b/Winget-AutoUpdate/functions/Get-Policies.ps1 index 0200341..ab71cd1 100644 --- a/Winget-AutoUpdate/functions/Get-Policies.ps1 +++ b/Winget-AutoUpdate/functions/Get-Policies.ps1 @@ -1,364 +1,470 @@ -#Function to get the Domain/Local Policies (GPO) +# Function to get the Domain/Local Policies (GPO) -Function Get-Policies { - #Get WAU Policies and set the Configurations Registry Accordingly - $WAUPolicies = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate" -ErrorAction SilentlyContinue - if ($WAUPolicies) { - if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) { - $ChangedSettings = 0 - $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) { - New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value $($WAUPolicies.WAU_BypassListForUsers) -PropertyType DWord -Force | Out-Null - $ChangedSettings++ +Function Get-Policies +{ + # Get WAU Policies and set the Configurations Registry Accordingly + $WAUPolicies = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate' -ErrorAction SilentlyContinue) + + if ($WAUPolicies) + { + if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) + { + $ChangedSettings = 0 + $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' + + if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Value $($WAUPolicies.WAU_BypassListForUsers) -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUConfig.WAU_BypassListForUsers) -or $($WAUConfig.WAU_BypassListForUsers) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUConfig.WAU_DisableAutoUpdate) -or $($WAUConfig.WAU_DisableAutoUpdate) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_DoNotRunOnMetered) -and !$($WAUConfig.WAU_DoNotRunOnMetered)) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUConfig.WAU_UseWhiteList) -or $($WAUConfig.WAU_UseWhiteList) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_ModsPath) -and $($WAUConfig.WAU_ModsPath)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + if ($null -ne $($WAUPolicies.WAU_AzureBlobSASURL) -and ($($WAUPolicies.WAU_AzureBlobSASURL) -ne $($WAUConfig.WAU_AzureBlobSASURL))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_AzureBlobSASURL -Value $($WAUPolicies.WAU_AzureBlobSASURL.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_AzureBlobSASURL) -and $($WAUConfig.WAU_AzureBlobSASURL)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_AzureBlobSASURL -Force -ErrorAction SilentlyContinue -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne 'Full') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value 'Full' -Force -Confirm:$false) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $($WAUPolicies.WAU_UpdatesAtTime) -Force -Confirm:$false) + $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + { + $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) + $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) + $Boundary = $PreStartBoundary + $($WAUPolicies.WAU_UpdatesAtTime) + $PostStartBoundary + $definition.Triggers.Item($triggerId).StartBoundary = $Boundary + break + } } - elseif ($null -eq $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUConfig.WAU_BypassListForUsers) -or $($WAUConfig.WAU_BypassListForUsers) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtTime) -and $($WAUConfig.WAU_UpdatesAtTime) -ne '06:00:00') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value '06:00:00' -Force -Confirm:$false) + $Script:WAUConfig = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + { + $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) + $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) + $Boundary = $PreStartBoundary + '06:00:00' + $PostStartBoundary + $definition.Triggers.Item($triggerId).StartBoundary = $Boundary + break + } } - if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) { - New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUConfig.WAU_DisableAutoUpdate) -or $($WAUConfig.WAU_DisableAutoUpdate) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesInterval -Value $($WAUPolicies.WAU_UpdatesInterval) -Force -Confirm:$false) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + { + $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) + $definition.Triggers.Remove($triggerId) + $triggerId -= 1 + } } - if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) { - New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_DoNotRunOnMetered) -and !$($WAUConfig.WAU_DoNotRunOnMetered)) { - New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force | Out-Null - $ChangedSettings++ + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) + + if (!$($WAUConfig.WAU_UpdatesAtTime)) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) + $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) { - New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force | Out-Null - $ChangedSettings++ + if ($($WAUPolicies.WAU_UpdatesInterval) -ne 'Never') + { + #Count Triggers (correctly) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + $null = $definition.Triggers.Count + switch ($($WAUPolicies.WAU_UpdatesInterval)) { + 'Daily' + { + $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) + break + } + 'BiDaily' + { + $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) -DaysInterval 2 + break + } + 'Weekly' + { + $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 + break + } + 'BiWeekly' + { + $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 2 + break + } + 'Monthly' + { + $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 4 + break + } + } + if ($definition.Triggers.Count -gt 0) + { + $triggers = @() + $triggers += (Get-ScheduledTask -TaskName 'Winget-AutoUpdate').Triggers + $triggers += $tasktrigger + $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) + } + else + { + $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $tasktrigger) + } } - elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) { - New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null - $ChangedSettings++ + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UpdatesInterval) -and $($WAUConfig.WAU_UpdatesInterval) -ne 'Daily') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesInterval -Value 'Daily' -Force -Confirm:$false) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + { + $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) + $definition.Triggers.Remove($triggerId) + $triggerId -= 1 + } } - if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) { - New-ItemProperty $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUConfig.WAU_UseWhiteList) -or $($WAUConfig.WAU_UseWhiteList) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) + + if (!$($WAUConfig.WAU_UpdatesAtTime)) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) + $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) { - New-ItemProperty $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(" ", "\", "/")) -Force | Out-Null - $ChangedSettings++ + $tasktrigger = (New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime)) + + # Count Triggers (correctly) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + $null = $definition.Triggers.Count + + if ($definition.Triggers.Count -gt 0) + { + $triggers = @() + $triggers += (Get-ScheduledTask -TaskName 'Winget-AutoUpdate').Triggers + $triggers += $tasktrigger + $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) } - elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) { - Remove-ItemProperty $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ + else + { + $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $tasktrigger) + } + $ChangedSettings++ + } + + if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) + { + if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force -Confirm:$false) + $triggers = @() + $triggers += (Get-ScheduledTask -TaskName 'Winget-AutoUpdate').Triggers + # Count Triggers (correctly) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + $triggerLogon = $false + + foreach ($trigger in $definition.Triggers) + { + if ($trigger.Type -eq '9') + { + $triggerLogon = $true + break + } + } + if (!$triggerLogon) + { + $triggers += New-ScheduledTaskTrigger -AtLogOn + $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) + } + } + else + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force -Confirm:$false) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + $null = $definition.Triggers.Count + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if ($definition.Triggers.Item($triggerId).Type -eq '9') + { + $definition.Triggers.Remove($triggerId) + $triggerId -= 1 + } + } + + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) } - if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) { - New-ItemProperty $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(" ", "\", "/")) -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_ModsPath) -and $($WAUConfig.WAU_ModsPath)) { - Remove-ItemProperty $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ - } - if ($null -ne $($WAUPolicies.WAU_AzureBlobSASURL) -and ($($WAUPolicies.WAU_AzureBlobSASURL) -ne $($WAUConfig.WAU_AzureBlobSASURL))) { - New-ItemProperty $regPath -Name WAU_AzureBlobSASURL -Value $($WAUPolicies.WAU_AzureBlobSASURL.TrimEnd(" ", "\", "/")) -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_AzureBlobSASURL) -and $($WAUConfig.WAU_AzureBlobSASURL)) { - Remove-ItemProperty $regPath -Name WAU_AzureBlobSASURL -Force -ErrorAction SilentlyContinue | Out-Null - $ChangedSettings++ + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Force -ErrorAction SilentlyContinue -Confirm:$false) + $service = (New-Object -ComObject Schedule.Service) + $service.Connect($env:COMPUTERNAME) + $folder = $service.GetFolder('\') + $task = $folder.GetTask('Winget-AutoUpdate') + $definition = $task.Definition + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + { + if ($definition.Triggers.Item($triggerId).Type -eq '9') + { + $definition.Triggers.Remove($triggerId) + $triggerId -= 1 + } } - if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) { - New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne "Full") { - New-ItemProperty $regPath -Name WAU_NotificationLevel -Value "Full" -Force | Out-Null - $ChangedSettings++ - } + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) + $ChangedSettings++ + } - if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) { - New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $($WAUPolicies.WAU_UpdatesAtTime) -Force | Out-Null - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) { - $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) - $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) - $Boundary = $PreStartBoundary + $($WAUPolicies.WAU_UpdatesAtTime) + $PostStartBoundary - $definition.Triggers.Item($triggerId).StartBoundary = $Boundary - break - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtTime) -and $($WAUConfig.WAU_UpdatesAtTime) -ne "06:00:00") { - New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value "06:00:00" -Force | Out-Null - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) { - $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) - $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) - $Boundary = $PreStartBoundary + "06:00:00" + $PostStartBoundary - $definition.Triggers.Item($triggerId).StartBoundary = $Boundary - break - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null - $ChangedSettings++ - } + if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UserContext -Value $($WAUPolicies.WAU_UserContext) -PropertyType DWord -Force -Confirm:$false) - if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) { - New-ItemProperty $regPath -Name WAU_UpdatesInterval -Value $($WAUPolicies.WAU_UpdatesInterval) -Force | Out-Null - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) { - $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) - $definition.Triggers.Remove($triggerId) - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null + if ($WAUPolicies.WAU_UserContext -eq 1) + { + # Settings for the scheduled task in User context + $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\winget-upgrade.ps1`"`"" + $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 + $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 + # Set up the task for user apps + $task = (New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings) + $null = (Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force) + } + else + { + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) + } + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_UserContext) -and ($($WAUConfig.WAU_UserContext) -or $($WAUConfig.WAU_UserContext) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_UserContext -Force -ErrorAction SilentlyContinue -Confirm:$false) + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) + $ChangedSettings++ + } - if (!$($WAUConfig.WAU_UpdatesAtTime)) { - New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force | Out-Null - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - } + if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_DesktopShortcut -Value $($WAUPolicies.WAU_DesktopShortcut) -PropertyType DWord -Force -Confirm:$false) - if ($($WAUPolicies.WAU_UpdatesInterval) -ne "Never") { - #Count Triggers (correctly) - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - $definition.Triggers.Count | Out-Null - switch ($($WAUPolicies.WAU_UpdatesInterval)) { - "Daily" { $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime); break } - "BiDaily" { $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) -DaysInterval 2; break } - "Weekly" { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2; break } - "BiWeekly" { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 2; break } - "Monthly" { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 4; break } - } - if ($definition.Triggers.Count -gt 0) { - $triggers = @() - $triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers - $triggers += $tasktrigger - Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers - } - else { - Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger - } - } - $ChangedSettings++ + if ($WAUPolicies.WAU_DesktopShortcut -eq 1) + { + Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesInterval) -and $($WAUConfig.WAU_UpdatesInterval) -ne "Daily") { - New-ItemProperty $regPath -Name WAU_UpdatesInterval -Value "Daily" -Force | Out-Null - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) { - $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) - $definition.Triggers.Remove($triggerId) - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null + else + { + $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) + } + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUConfig.WAU_DesktopShortcut) -or $($WAUConfig.WAU_DesktopShortcut) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_DesktopShortcut -Force -Confirm:$false -ErrorAction SilentlyContinue) + $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) + $ChangedSettings++ + } - if (!$($WAUConfig.WAU_UpdatesAtTime)) { - New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force | Out-Null - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - } + if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_StartMenuShortcut -Value $($WAUPolicies.WAU_StartMenuShortcut) -PropertyType DWord -Force -Confirm:$false) - $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) + if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) + { + if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + { + $null = (New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Confirm:$false) + } - #Count Triggers (correctly) - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - $definition.Triggers.Count | Out-Null - if ($definition.Triggers.Count -gt 0) { - $triggers = @() - $triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers - $triggers += $tasktrigger - Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers - } - else { - Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger - } - $ChangedSettings++ + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' } + else + { + $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) + } + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUConfig.WAU_StartMenuShortcut) -or $($WAUConfig.WAU_StartMenuShortcut) -eq 0)) + { + $null = (Remove-ItemProperty -Path $regPath -Name WAU_StartMenuShortcut -Force -ErrorAction SilentlyContinue -Confirm:$false) + $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) + $ChangedSettings++ + } - if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) { - if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) { - New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null - $triggers = @() - $triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers - #Count Triggers (correctly) - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - $triggerLogon = $false - foreach ($trigger in $definition.Triggers) { - if ($trigger.Type -eq "9") { - $triggerLogon = $true - break - } - } - if (!$triggerLogon) { - $triggers += New-ScheduledTaskTrigger -AtLogon - Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers - } - } - else { - New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - $definition.Triggers.Count | Out-Null - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if ($definition.Triggers.Item($triggerId).Type -eq "9") { - $definition.Triggers.Remove($triggerId) - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null - } - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Force -ErrorAction SilentlyContinue | Out-Null - $service = New-Object -ComObject Schedule.Service - $service.Connect($env:COMPUTERNAME) - $folder = $service.GetFolder('\') - $task = $folder.GetTask("Winget-AutoUpdate") - $definition = $task.Definition - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if ($definition.Triggers.Item($triggerId).Type -eq "9") { - $definition.Triggers.Remove($triggerId) - $triggerId -= 1 - } - } - $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null - $ChangedSettings++ - } + if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value $($WAUPolicies.WAU_MaxLogFiles.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_MaxLogFiles) -and $($WAUConfig.WAU_MaxLogFiles) -ne 3) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -Force -Confirm:$false) + $ChangedSettings++ + } - if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) { - New-ItemProperty $regPath -Name WAU_UserContext -Value $($WAUPolicies.WAU_UserContext) -PropertyType DWord -Force | Out-Null - if ($WAUPolicies.WAU_UserContext -eq 1) { - # Settings for the scheduled task in User context - $taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\winget-upgrade.ps1`"`"" - $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 - $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 + if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value $($WAUPolicies.WAU_MaxLogSize.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) + $ChangedSettings++ + } + elseif ($null -eq $($WAUPolicies.WAU_MaxLogSize) -and $($WAUConfig.WAU_MaxLogSize) -ne 1048576) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -Force -Confirm:$false) + $ChangedSettings++ + } - # Set up the task for user apps - $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings - Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force - } - else { - Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - } - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_UserContext) -and ($($WAUConfig.WAU_UserContext) -or $($WAUConfig.WAU_UserContext) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_UserContext -Force -ErrorAction SilentlyContinue | Out-Null - Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False - $ChangedSettings++ - } + # Get WAU Configurations after Policies change + $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') + } + } - if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) { - New-ItemProperty $regPath -Name WAU_DesktopShortcut -Value $($WAUPolicies.WAU_DesktopShortcut) -PropertyType DWord -Force | Out-Null - if ($WAUPolicies.WAU_DesktopShortcut -eq 1) { - Add-Shortcut "wscript.exe" "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..." - } - else { - Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null - } - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUConfig.WAU_DesktopShortcut) -or $($WAUConfig.WAU_DesktopShortcut) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_DesktopShortcut -Force -ErrorAction SilentlyContinue | Out-Null - Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null - $ChangedSettings++ - } - - if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) { - New-ItemProperty $regPath -Name WAU_StartMenuShortcut -Value $($WAUPolicies.WAU_StartMenuShortcut) -PropertyType DWord -Force | Out-Null - if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) { - if (!(Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { - New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" | Out-Null - } - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..." - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" "Open existing WAU logs..." - Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" "Help for WAU..." - } - else { - Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null - } - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUConfig.WAU_StartMenuShortcut) -or $($WAUConfig.WAU_StartMenuShortcut) -eq 0)) { - Remove-ItemProperty $regPath -Name WAU_StartMenuShortcut -Force -ErrorAction SilentlyContinue | Out-Null - Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null - $ChangedSettings++ - } - - if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) { - New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $($WAUPolicies.WAU_MaxLogFiles.TrimEnd(" ", "\", "/")) -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_MaxLogFiles) -and $($WAUConfig.WAU_MaxLogFiles) -ne 3) { - New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value 3 -Force | Out-Null - $ChangedSettings++ - } - - if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) { - New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $($WAUPolicies.WAU_MaxLogSize.TrimEnd(" ", "\", "/")) -Force | Out-Null - $ChangedSettings++ - } - elseif ($null -eq $($WAUPolicies.WAU_MaxLogSize) -and $($WAUConfig.WAU_MaxLogSize) -ne 1048576) { - New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -Force | Out-Null - $ChangedSettings++ - } - - #Get WAU Configurations after Policies change - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - } - } - Return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings + Return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings } diff --git a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 index c2241ab..5bb5091 100644 --- a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 +++ b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 @@ -1,25 +1,22 @@ -#Function to get the latest WAU available version on Github +# Function to get the latest WAU available version on Github -function Get-WAUAvailableVersion { +function Get-WAUAvailableVersion +{ + # Get Github latest version + if ($WAUConfig.WAU_UpdatePrerelease -eq 1) + { + # Log + Write-ToLog -LogMsg 'WAU AutoUpdate Pre-release versions is Enabled' -LogColor 'Cyan' - #Get Github latest version - if ($WAUConfig.WAU_UpdatePrerelease -eq 1) { - - #Log - Write-ToLog "WAU AutoUpdate Pre-release versions is Enabled" "Cyan" - - #Get latest pre-release info - $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases' - - } - else { - - #Get latest stable info - $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases/latest' - - } - - #Return version - return ((Invoke-WebRequest $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace("v", "") + # Get latest pre-release info + $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases' + } + else + { + # Get latest stable info + $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases/latest' + } + # Return version + return ((Invoke-WebRequest -Uri $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace('v', '') } diff --git a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 index e0be4e4..eec9904 100644 --- a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 @@ -1,40 +1,42 @@ -#Function to get the winget command regarding execution context (User, System...) +# Function to get the winget command regarding execution context (User, System...) Function Get-WingetCmd { - #Get WinGet Path (if Admin context) + # Get WinGet Path (if Admin context) # Includes Workaround for ARM64 (removed X64 and replaces it with a wildcard) - $ResolveWingetPath = Resolve-Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe" | Sort-Object { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } + $ResolveWingetPath = (Resolve-Path -Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe" | Sort-Object -Property { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') }) if ($ResolveWingetPath) { - #If multiple version, pick last one + # If multiple version, pick last one $WingetPath = $ResolveWingetPath[-1].Path } #If running under System or Admin context obtain Winget from Program Files - if((([System.Security.Principal.WindowsIdentity]::GetCurrent().User) -eq "S-1-5-18") -or ($WingetPath)){ - if (Test-Path "$WingetPath\winget.exe") { - $Script:Winget = "$WingetPath\winget.exe" + if((([Security.Principal.WindowsIdentity]::GetCurrent().User) -eq 'S-1-5-18') -or ($WingetPath)){ + if (Test-Path -Path ('{0}\winget.exe' -f $WingetPath) -ErrorAction SilentlyContinue) { + $Script:Winget = ('{0}\winget.exe' -f $WingetPath) } }else{ #Get Winget Location in User context - $WingetCmd = Get-Command winget.exe -ErrorAction SilentlyContinue + $WingetCmd = (Get-Command -Name winget.exe -ErrorAction SilentlyContinue) + if ($WingetCmd) { $Script:Winget = $WingetCmd.Source } } If(!($Script:Winget)){ - Write-ToLog "Winget not installed or detected !" "Red" + Write-ToLog 'Winget not installed or detected !' 'Red' + return $false } - #Run winget to list apps and accept source agrements (necessary on first run) - & $Winget list --accept-source-agreements -s winget | Out-Null + # Run winget to list apps and accept source agrements (necessary on first run) + $null = (& $Winget list --accept-source-agreements -s winget) - #Log Winget installed version + # Log Winget installed version $WingetVer = & $Winget --version - Write-ToLog "Winget Version: $WingetVer" + Write-ToLog ('Winget Version: {0}' -f $WingetVer) return $true diff --git a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 index 59eaffa..62242b0 100644 --- a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 @@ -1,76 +1,92 @@ -#Function to get the outdated app list, in formatted array +# Function to get the outdated app list, in formatted array -function Get-WingetOutdatedApps { - class Software { - [string]$Name - [string]$Id - [string]$Version - [string]$AvailableVersion - } +function Get-WingetOutdatedApps +{ + class Software { + [string]$Name + [string]$Id + [string]$Version + [string]$AvailableVersion + } - #Get list of available upgrades on winget format - $upgradeResult = & $Winget upgrade --source winget | Out-String + # Get list of available upgrades on winget format + $upgradeResult = (& $Winget upgrade --source winget | Out-String) - #Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) - if (!($upgradeResult -match "-----")) { - return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult" - } + # Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) + if (!($upgradeResult -match '-----')) + { + return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult" + } - #Split winget output to lines - $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object { $_ } + # Split winget output to lines + $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object -FilterScript { + $_ + } - # Find the line that starts with "------" - $fl = 0 - while (-not $lines[$fl].StartsWith("-----")) { - $fl++ - } + # Find the line that starts with "------" + $fl = 0 + while (-not $lines[$fl].StartsWith('-----')) + { + $fl++ + } - #Get header line - $fl = $fl - 1 + # Get header line + $fl = $fl - 1 - #Get header titles [without remove seperator] - $index = $lines[$fl] -split '(?<=\s)(?!\s)' + # Get header titles [without remove seperator] + $index = $lines[$fl] -split '(?<=\s)(?!\s)' - # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] - $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length - $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length - $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] + $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length + $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length + $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length - # Now cycle in real package and split accordingly - $upgradeList = @() - For ($i = $fl + 2; $i -lt $lines.Length; $i++) { - $line = $lines[$i] -replace "[\u2026]", " " #Fix "..." in long names - if ($line.StartsWith("-----")) { - #Get header line - $fl = $i - 1 + # Now cycle in real package and split accordingly + $upgradeList = @() - #Get header titles [without remove seperator] - $index = $lines[$fl] -split '(?<=\s)(?!\s)' + For ($i = $fl + 2; $i -lt $lines.Length; $i++) + { + $line = $lines[$i] -replace '[\u2026]', ' ' #Fix "..." in long names - # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] - $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length - $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length - $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length - } - #(Alphanumeric | Literal . | Alphanumeric) - the only unique thing in common for lines with applications - if ($line -match "\w\.\w") { - $software = [Software]::new() - #Manage non latin characters - $nameDeclination = $($line.Substring(0, $idStart) -replace '[\u4e00-\u9fa5]', '**').Length - $line.Substring(0, $idStart).Length - $software.Name = $line.Substring(0, $idStart - $nameDeclination).TrimEnd() - $software.Id = $line.Substring($idStart - $nameDeclination, $versionStart - $idStart).TrimEnd() - $software.Version = $line.Substring($versionStart - $nameDeclination, $availableStart - $versionStart).TrimEnd() - $software.AvailableVersion = $line.Substring($availableStart - $nameDeclination).TrimEnd() - #add formated soft to list - $upgradeList += $software - } - } + if ($line.StartsWith('-----')) + { + # Get header line + $fl = $i - 1 - #If current user is not system, remove system apps from list - if ($IsSystem -eq $false) { - $SystemApps = Get-Content -Path "$WorkingDir\winget_system_apps.txt" - $upgradeList = $upgradeList | Where-Object { $SystemApps -notcontains $_.Id } - } + # Get header titles [without remove seperator] + $index = $lines[$fl] -split '(?<=\s)(?!\s)' - return $upgradeList | Sort-Object { Get-Random } + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] + $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length + $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length + $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length + } + + # (Alphanumeric | Literal . | Alphanumeric) - the only unique thing in common for lines with applications + if ($line -match '\w\.\w') + { + $software = [Software]::new() + # Manage non latin characters + $nameDeclination = $($line.Substring(0, $idStart) -replace '[\u4e00-\u9fa5]', '**').Length - $line.Substring(0, $idStart).Length + $software.Name = $line.Substring(0, $idStart - $nameDeclination).TrimEnd() + $software.Id = $line.Substring($idStart - $nameDeclination, $versionStart - $idStart).TrimEnd() + $software.Version = $line.Substring($versionStart - $nameDeclination, $availableStart - $versionStart).TrimEnd() + $software.AvailableVersion = $line.Substring($availableStart - $nameDeclination).TrimEnd() + # add formated soft to list + $upgradeList += $software + } + } + + # If current user is not system, remove system apps from list + if ($IsSystem -eq $false) + { + $SystemApps = Get-Content -Path ('{0}\winget_system_apps.txt' -f $WorkingDir) + $upgradeList = $upgradeList | Where-Object -FilterScript { + $SystemApps -notcontains $_.Id + } + } + + return $upgradeList | Sort-Object -Property { + Get-Random + } } diff --git a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 index 8f653ea..0d1bedf 100644 --- a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 @@ -1,18 +1,17 @@ -function Get-WingetSystemApps { +function Get-WingetSystemApps +{ + # Json File, where to export system installed apps + $jsonFile = ('{0}\winget_system_apps.txt' -f $WorkingDir) - #Json File, where to export system installed apps - $jsonFile = "$WorkingDir\winget_system_apps.txt" + # Get list of installed Winget apps to json file + $null = (& $Winget export -o $jsonFile --accept-source-agreements -s winget) - #Get list of installed Winget apps to json file - & $Winget export -o $jsonFile --accept-source-agreements -s winget | Out-Null + # Convert json file to txt file with app ids + $InstalledApps = (Get-Content -Path $jsonFile | ConvertFrom-Json) - #Convert json file to txt file with app ids - $InstalledApps = get-content $jsonFile | ConvertFrom-Json - - #Save app list - Set-Content $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile - - #Sort app list - Get-Content $jsonFile | Sort-Object | Set-Content $jsonFile + # Save app list + $null = (Set-Content -Value $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) + # Sort app list + $null = (Get-Content -Path $jsonFile | Sort-Object | Set-Content -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) } diff --git a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 index 82edf17..86c40b7 100644 --- a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 @@ -1,95 +1,115 @@ -#Function to rotate the logs +# Function to rotate the logs -function Invoke-LogRotation ($LogFile, $MaxLogFiles, $MaxLogSize) { - <# - .SYNOPSIS - Handle log rotation. - .DESCRIPTION - Invoke-LogRotation handles log rotation - .NOTES - Author: Øyvind Kallstad (Minimized and changed for WAU 12.01.2023 by Göran Axel Johannesson) - URL: https://www.powershellgallery.com/packages/Communary.Logger/1.1 - Date: 21.11.2014 - Version: 1.0 - #> +function Invoke-LogRotation +{ + <# + .SYNOPSIS + Handle log rotation. + .DESCRIPTION + Invoke-LogRotation handles log rotation + .NOTES + Author: Øyvind Kallstad (Minimized and changed for WAU 12.01.2023 by Göran Axel Johannesson) + URL: https://www.powershellgallery.com/packages/Communary.Logger/1.1 + Date: 21.11.2014 + Version: 1.0 + #> + param + ( + [string]$LogFile, + [int]$MaxLogFiles, + [int]$MaxLogSize + ) + + try + { + # get current size of log file + $currentSize = (Get-Item -Path $LogFile).Length - try { - # get current size of log file - $currentSize = (Get-Item $LogFile).Length + # get log name + $logFileName = (Split-Path -Path $LogFile -Leaf) + $logFilePath = (Split-Path -Path $LogFile) + $logFileNameWithoutExtension = [IO.Path]::GetFileNameWithoutExtension($logFileName) + $logFileNameExtension = [IO.Path]::GetExtension($logFileName) - # get log name - $logFileName = Split-Path $LogFile -Leaf - $logFilePath = Split-Path $LogFile - $logFileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($logFileName) - $logFileNameExtension = [System.IO.Path]::GetExtension($logFileName) + # if MaxLogFiles is 1 just keep the original one and let it grow + if (-not($MaxLogFiles -eq 1)) + { + if ($currentSize -ge $MaxLogSize) + { + # construct name of archived log file + $newLogFileName = $logFileNameWithoutExtension + (Get-Date -Format 'yyyyMMddHHmmss').ToString() + $logFileNameExtension - # if MaxLogFiles is 1 just keep the original one and let it grow - if (-not($MaxLogFiles -eq 1)) { - if ($currentSize -ge $MaxLogSize) { + # copy old log file to new using the archived name constructed above + $null = (Copy-Item -Path $LogFile -Destination (Join-Path -Path (Split-Path -Path $LogFile) -ChildPath $newLogFileName)) - # construct name of archived log file - $newLogFileName = $logFileNameWithoutExtension + (Get-Date -Format 'yyyyMMddHHmmss').ToString() + $logFileNameExtension - - # copy old log file to new using the archived name constructed above - Copy-Item -Path $LogFile -Destination (Join-Path (Split-Path $LogFile) $newLogFileName) - - # Create a new log file - try { - Remove-Item -Path $LogFile -Force - New-Item -ItemType File -Path $LogFile -Force - #Set ACL for users on logfile - $NewAcl = Get-Acl -Path $LogFile - $identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11 - $fileSystemRights = "Modify" - $type = "Allow" - $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type - $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList - $NewAcl.SetAccessRule($fileSystemAccessRule) - Set-Acl -Path $LogFile -AclObject $NewAcl - } - catch { - Return $False - } - - # if MaxLogFiles is 0 don't delete any old archived log files - if (-not($MaxLogFiles -eq 0)) { - - # set filter to search for archived log files - $archivedLogFileFilter = $logFileNameWithoutExtension + '??????????????' + $logFileNameExtension - - # get archived log files - $oldLogFiles = Get-Item -Path "$(Join-Path -Path $logFilePath -ChildPath $archivedLogFileFilter)" - - if ([bool]$oldLogFiles) { - # compare found log files to MaxLogFiles parameter of the log object, and delete oldest until we are - # back to the correct number - if (($oldLogFiles.Count + 1) -gt $MaxLogFiles) { - [int]$numTooMany = (($oldLogFiles.Count) + 1) - $MaxLogFiles - $oldLogFiles | Sort-Object 'LastWriteTime' | Select-Object -First $numTooMany | Remove-Item - } - } - } - - #Log Header - $Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################" - $Log | out-file -filepath $LogFile -Append - Write-ToLog "Running in System context" - if ($ActivateGPOManagement) { - Write-ToLog "Activated WAU GPO Management detected, comparing..." - if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { - Write-ToLog "Changed settings detected and applied" "Yellow" - } - else { - Write-ToLog "No Changed settings detected" "Yellow" - } - } - Write-ToLog "Max Log Size reached: $MaxLogSize bytes - Rotated Logs" - - Return $True + # Create a new log file + try + { + $null = (Remove-Item -Path $LogFile -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-Item -ItemType File -Path $LogFile -Force -Confirm:$False -ErrorAction SilentlyContinue) + # Set ACL for users on logfile + $NewAcl = (Get-Acl -Path $LogFile) + $identity = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList S-1-5-11) + $fileSystemRights = 'Modify' + $type = 'Allow' + $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type + $fileSystemAccessRule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList) + $NewAcl.SetAccessRule($fileSystemAccessRule) + $null = (Set-Acl -Path $LogFile -AclObject $NewAcl) } - } - } - catch { - Return $False - } + catch + { + Return $False + } + + # if MaxLogFiles is 0 don't delete any old archived log files + if (-not($MaxLogFiles -eq 0)) + { + # set filter to search for archived log files + $archivedLogFileFilter = $logFileNameWithoutExtension + '??????????????' + $logFileNameExtension + + # get archived log files + $oldLogFiles = (Get-Item -Path "$(Join-Path -Path $logFilePath -ChildPath $archivedLogFileFilter)") + + if ([bool]$oldLogFiles) + { + # compare found log files to MaxLogFiles parameter of the log object, and delete oldest until we are + # back to the correct number + if (($oldLogFiles.Count + 1) -gt $MaxLogFiles) + { + [int]$numTooMany = (($oldLogFiles.Count) + 1) - $MaxLogFiles + $null = ($oldLogFiles | Sort-Object -Property 'LastWriteTime' | Select-Object -First $numTooMany | Remove-Item -Force -Confirm:$False -ErrorAction SilentlyContinue) + } + } + } + + # Log Header + $Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-Culture).DateTimeFormat.ShortDatePattern)`n##################################################" + $null = ($Log | Out-File -FilePath $LogFile -Append -Force) + Write-ToLog -LogMsg 'Running in System context' + + if ($ActivateGPOManagement) + { + Write-ToLog -LogMsg 'Activated WAU GPO Management detected, comparing...' + + if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) + { + Write-ToLog -LogMsg 'Changed settings detected and applied' -LogColor 'Yellow' + } + else + { + Write-ToLog -LogMsg 'No Changed settings detected' -LogColor 'Yellow' + } + } + + Write-ToLog -LogMsg ('Max Log Size reached: {0} bytes - Rotated Logs' -f $MaxLogSize) + + Return $True + } + } + } + catch + { + Return $False + } } diff --git a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 index 1b56707..1d33a33 100644 --- a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 @@ -1,65 +1,81 @@ -#Function to check if the mods directory is secured. -#Security: Mods directory must be protected (Users could create scripts of their own - then they'll run in System Context)! -#Check if Local Users have write rights in Mods directory or not (and take action if necessary): +# Function to check if the mods directory is secured. +# Security: Mods directory must be protected (Users could create scripts of their own - then they'll run in System Context)! +# Check if Local Users have write rights in Mods directory or not (and take action if necessary): -function Invoke-ModsProtect ($ModsPath) { - try { - $directory = Get-Item -Path $ModsPath -ErrorAction SilentlyContinue - $acl = Get-Acl -Path $directory.FullName - #Local Users - S-1-5-32-545 - $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-545") - #Translate SID to Locale Name - $ntAccount = $userSID.Translate([System.Security.Principal.NTAccount]) - $userName = $ntAccount.Value - $userRights = [System.Security.AccessControl.FileSystemRights]"Write" +function Invoke-ModsProtect +{ + [CmdletBinding()] + param + ( + [string]$ModsPath + ) - $hasWriteAccess = $False + try + { + $directory = (Get-Item -Path $ModsPath -ErrorAction SilentlyContinue) + $acl = (Get-Acl -Path $directory.FullName) + # Local Users - S-1-5-32-545 + $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-545')) + # Translate SID to Locale Name + $ntAccount = $userSID.Translate([Security.Principal.NTAccount]) + $userName = $ntAccount.Value + $userRights = [Security.AccessControl.FileSystemRights]'Write' + $hasWriteAccess = $False - foreach ($access in $acl.Access) { - if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) { - $hasWriteAccess = $True - break - } - } + foreach ($access in $acl.Access) + { + if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) + { + $hasWriteAccess = $True + break + } + } - if ($hasWriteAccess) { - #Disable inheritance - $acl.SetAccessRuleProtection($True, $True) - # Remove any existing rules - $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } - #SYSTEM Full - S-1-5-18 - $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-18") - $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSID, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") - $acl.SetAccessRule($rule) - # Save the updated ACL - Set-Acl -Path $directory.FullName -AclObject $acl + if ($hasWriteAccess) + { + # Disable inheritance + $acl.SetAccessRuleProtection($True, $True) - #Administrators Full - S-1-5-32-544 - $acl = Get-Acl -Path $directory.FullName - $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544") - $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSID, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") - $acl.SetAccessRule($rule) - Set-Acl -Path $directory.FullName -AclObject $acl + # Remove any existing rules + $acl.Access | ForEach-Object -Process { + $acl.RemoveAccessRule($_) + } - #Local Users ReadAndExecute - S-1-5-32-545 S-1-5-11 - $acl = Get-Acl -Path $directory.FullName - $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-545") - $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSID, "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow") - $acl.SetAccessRule($rule) - Set-Acl -Path $directory.FullName -AclObject $acl + # SYSTEM Full - S-1-5-18 + $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-18')) + $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) + $acl.SetAccessRule($rule) + # Save the updated ACL + $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - #Authenticated Users ReadAndExecute - S-1-5-11 - $acl = Get-Acl -Path $directory.FullName - $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-11") - $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSID, "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow") - $acl.SetAccessRule($rule) - Set-Acl -Path $directory.FullName -AclObject $acl + # Administrators Full - S-1-5-32-544 + $acl = (Get-Acl -Path $directory.FullName) + $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-544')) + $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) + $acl.SetAccessRule($rule) + $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - return $True - } - return $False - } - catch { - return "Error" - } -} \ No newline at end of file + # Local Users ReadAndExecute - S-1-5-32-545 S-1-5-11 + $acl = (Get-Acl -Path $directory.FullName) + $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-545')) + $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) + $acl.SetAccessRule($rule) + $null = (Set-Acl -Path $directory.FullName -AclObject $acl) + + # Authenticated Users ReadAndExecute - S-1-5-11 + $acl = (Get-Acl -Path $directory.FullName) + $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-11')) + $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) + $acl.SetAccessRule($rule) + $null = (Set-Acl -Path $directory.FullName -AclObject $acl) + + return $True + } + + return $False + } + catch + { + return 'Error' + } +} diff --git a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 index 2637718..558e769 100644 --- a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 @@ -1,231 +1,289 @@ -#Function to make actions after WAU update +# Function to make actions after WAU update -function Invoke-PostUpdateActions { +function Invoke-PostUpdateActions +{ + # log + Write-ToLog -LogMsg 'Running Post Update actions:' -LogColor 'yellow' - #log - Write-ToLog "Running Post Update actions:" "yellow" + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ErrorAction SilentlyContinue)) + { + Write-ToLog -LogMsg '-> Creating SymLink for log file in Intune Management Extension log folder' -LogColor 'yellow' + $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue + } + + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) + { + Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow + $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -Confirm:$False -ErrorAction SilentlyContinue) + } - #Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink - if ((Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) { - Write-ToLog "-> Creating SymLink for log file in Intune Management Extension log folder" "yellow" - New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue | Out-Null - } - #Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink - if ((Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and (Test-Path "$WorkingDir\logs\install.log") -and !(Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log")) { - Write-host "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow - New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value "$WorkingDir\logs\install.log" -Force -ErrorAction SilentlyContinue | Out-Null - } + Write-ToLog -LogMsg '-> Checking prerequisites...' -LogColor 'yellow' - Write-ToLog "-> Checking prerequisites..." "yellow" + # Check if Visual C++ 2019 or 2022 installed + $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' + $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' + $path = (Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue | Where-Object -FilterScript { + $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 + }) - #Check if Visual C++ 2019 or 2022 installed - $Visual2019 = "Microsoft Visual C++ 2015-2019 Redistributable*" - $Visual2022 = "Microsoft Visual C++ 2015-2022 Redistributable*" - $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 } + # If not installed, install + if (!($path)) + { + try + { + if ((Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -like '*64*') + { + $OSArch = 'x64' + } + else + { + $OSArch = 'x86' + } + + Write-ToLog -LogMsg ('-> Downloading VC_redist.{0}.exe...' -f $OSArch) + $SourceURL = ('https://aka.ms/vs/17/release/VC_redist.{0}.exe' -f $OSArch) + $Installer = ('{0}\VC_redist.{1}.exe' -f $WAUConfig.InstallLocation, $OSArch) + $ProgressPreference = 'SilentlyContinue' + $null = (Invoke-WebRequest -Uri $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force)) + Write-ToLog -LogMsg ('-> Installing VC_redist.{0}.exe...' -f $OSArch) + Start-Process -FilePath $Installer -ArgumentList '/quiet /norestart' -Wait + Remove-Item -Path $Installer -ErrorAction Ignore + Write-ToLog -LogMsg '-> MS Visual C++ 2015-2022 installed successfully' -LogColor 'green' + } + catch + { + Write-ToLog -LogMsg '-> MS Visual C++ 2015-2022 installation failed.' -LogColor 'red' + } + } + else + { + Write-ToLog -LogMsg '-> Prerequisites checked. OK' -LogColor 'green' + } - #If not installed, install - if (!($path)) { - try { - if ((Get-CimInStance Win32_OperatingSystem).OSArchitecture -like "*64*") { - $OSArch = "x64" - } - else { - $OSArch = "x86" - } - Write-ToLog "-> Downloading VC_redist.$OSArch.exe..." - $SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe" - $Installer = "$($WAUConfig.InstallLocation)\VC_redist.$OSArch.exe" - $ProgressPreference = 'SilentlyContinue' - Invoke-WebRequest $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force) - Write-ToLog "-> Installing VC_redist.$OSArch.exe..." - Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait - Remove-Item $Installer -ErrorAction Ignore - Write-ToLog "-> MS Visual C++ 2015-2022 installed successfully" "green" - } - catch { - Write-ToLog "-> MS Visual C++ 2015-2022 installation failed." "red" - } - } - else { - Write-ToLog "-> Prerequisites checked. OK" "green" - } + # Check Package Install + Write-ToLog -LogMsg '-> Checking if Winget is installed/up to date' -LogColor 'yellow' + $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { + $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' + } - #Check Package Install - Write-ToLog "-> Checking if Winget is installed/up to date" "yellow" - $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" } + # Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 + If ([Version]$TestWinGet.Version -ge '2023.808.2243.0') + { + Write-ToLog -LogMsg '-> WinGet is Installed/up to date' -LogColor 'green' + } + Else + { + # Download WinGet MSIXBundle + Write-ToLog -LogMsg '-> Not installed/up to date. Downloading WinGet...' + $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' + $WebClient = New-Object -TypeName System.Net.WebClient + $WebClient.DownloadFile($WinGetURL, ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation)) - #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 - If ([Version]$TestWinGet.Version -ge "2023.808.2243.0") { + # Install WinGet MSIXBundle + try + { + Write-ToLog -LogMsg '-> Installing Winget MSIXBundle for App Installer...' + $null = Add-AppxProvisionedPackage -Online -PackagePath ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -SkipLicense + Write-ToLog -LogMsg '-> Installed Winget MSIXBundle for App Installer' -LogColor 'green' + } + catch + { + Write-ToLog -LogMsg '-> Failed to intall Winget MSIXBundle for App Installer...' -LogColor 'red' + } - Write-ToLog "-> WinGet is Installed/up to date" "green" + # Remove WinGet MSIXBundle + Remove-Item -Path ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -Force -Confirm:$False -ErrorAction Continue + } - } - Else { + # Reset Winget Sources + $ResolveWingetPath = Resolve-Path -Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object -Property { + [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') + } - #Download WinGet MSIXBundle - Write-ToLog "-> Not installed/up to date. Downloading WinGet..." - $WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" - $WebClient = New-Object System.Net.WebClient - $WebClient.DownloadFile($WinGetURL, "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle") + if ($ResolveWingetPath) + { + # If multiple version, pick last one + $WingetPath = $ResolveWingetPath[-1].Path + & $WingetPath source reset --force - #Install WinGet MSIXBundle - try { - Write-ToLog "-> Installing Winget MSIXBundle for App Installer..." - Add-AppxProvisionedPackage -Online -PackagePath "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -SkipLicense | Out-Null - Write-ToLog "-> Installed Winget MSIXBundle for App Installer" "green" - } - catch { - Write-ToLog "-> Failed to intall Winget MSIXBundle for App Installer..." "red" - } + # log + Write-ToLog -LogMsg '-> Winget sources reseted.' -LogColor 'green' + } - #Remove WinGet MSIXBundle - Remove-Item -Path "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue + # Create WAU Regkey if not present + $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' - } + if (!(Test-Path -Path $regPath -ErrorAction SilentlyContinue)) + { + $null = (New-Item -Path $regPath -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name DisplayName -Value 'Winget-AutoUpdate (WAU)' -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name DisplayIcon -Value 'C:\Windows\System32\shell32.dll,-16739' -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name NoModify -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name NoRepair -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name Publisher -Value 'Romanitho' -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name URLInfoAbout -Value 'https://github.com/Romanitho/Winget-AutoUpdate' -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name InstallLocation -Value $WorkingDir -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - #Reset Winget Sources - $ResolveWingetPath = Resolve-Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } - if ($ResolveWingetPath) { - #If multiple version, pick last one - $WingetPath = $ResolveWingetPath[-1].Path - & $WingetPath source reset --force + #log + Write-ToLog -LogMsg ('-> {0} created.' -f $regPath) -LogColor 'green' + } - #log - Write-ToLog "-> Winget sources reseted." "green" - } + # Fix Notif where WAU_NotificationLevel is not set + $regNotif = Get-ItemProperty -Path $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue - #Create WAU Regkey if not present - $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" - if (!(test-path $regPath)) { - New-Item $regPath -Force - New-ItemProperty $regPath -Name DisplayName -Value "Winget-AutoUpdate (WAU)" -Force - New-ItemProperty $regPath -Name DisplayIcon -Value "C:\Windows\System32\shell32.dll,-16739" -Force - New-ItemProperty $regPath -Name NoModify -Value 1 -Force - New-ItemProperty $regPath -Name NoRepair -Value 1 -Force - New-ItemProperty $regPath -Name Publisher -Value "Romanitho" -Force - New-ItemProperty $regPath -Name URLInfoAbout -Value "https://github.com/Romanitho/Winget-AutoUpdate" -Force - New-ItemProperty $regPath -Name InstallLocation -Value $WorkingDir -Force - New-ItemProperty $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force - New-ItemProperty $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force - New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force + if (!$regNotif) + { + New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value Full -Force - #log - Write-ToLog "-> $regPath created." "green" - } - #Fix Notif where WAU_NotificationLevel is not set - $regNotif = Get-ItemProperty $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue - if (!$regNotif) { - New-ItemProperty $regPath -Name WAU_NotificationLevel -Value Full -Force + # log + Write-ToLog -LogMsg "-> Notification level setting was missing. Fixed with 'Full' option." + } - #log - Write-ToLog "-> Notification level setting was missing. Fixed with 'Full' option." - } + # Set WAU_MaxLogFiles/WAU_MaxLogSize if not set + $MaxLogFiles = Get-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue - #Set WAU_MaxLogFiles/WAU_MaxLogSize if not set - $MaxLogFiles = Get-ItemProperty $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue - if (!$MaxLogFiles) { - New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value 3 -PropertyType DWord -Force | Out-Null - New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force | Out-Null + if (!$MaxLogFiles) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - #log - Write-ToLog "-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB)." - } + # log + Write-ToLog -LogMsg '-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB).' + } - #Set WAU_ListPath if not set - $ListPath = Get-ItemProperty $regPath -Name WAU_ListPath -ErrorAction SilentlyContinue - if (!$ListPath) { - New-ItemProperty $regPath -Name WAU_ListPath -Force | Out-Null + # Set WAU_ListPath if not set + $ListPath = Get-ItemProperty -Path $regPath -Name WAU_ListPath -ErrorAction SilentlyContinue - #log - Write-ToLog "-> ListPath setting was missing. Fixed with empty string." - } + if (!$ListPath) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - #Set WAU_ModsPath if not set - $ModsPath = Get-ItemProperty $regPath -Name WAU_ModsPath -ErrorAction SilentlyContinue - if (!$ModsPath) { - New-ItemProperty $regPath -Name WAU_ModsPath -Force | Out-Null + # log + Write-ToLog -LogMsg '-> ListPath setting was missing. Fixed with empty string.' + } - #log - Write-ToLog "-> ModsPath setting was missing. Fixed with empty string." - } + # Set WAU_ModsPath if not set + $ModsPath = (Get-ItemProperty -Path $regPath -Name WAU_ModsPath -ErrorAction SilentlyContinue) - #Security check - Write-ToLog "-> Checking Mods Directory:" "yellow" - $Protected = Invoke-ModsProtect "$($WAUConfig.InstallLocation)\mods" - if ($Protected -eq $True) { - Write-ToLog "-> The mods directory is now secured!" "green" - } - elseif ($Protected -eq $False) { - Write-ToLog "-> The mods directory was already secured!" "green" - } - else { - Write-ToLog "-> Error: The mods directory couldn't be verified as secured!" "red" - } + if (!$ModsPath) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - #Convert about.xml if exists (old WAU versions) to reg - $WAUAboutPath = "$WorkingDir\config\about.xml" - if (test-path $WAUAboutPath) { - [xml]$About = Get-Content $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue - New-ItemProperty $regPath -Name DisplayVersion -Value $About.app.version -Force + # log + Write-ToLog -LogMsg '-> ModsPath setting was missing. Fixed with empty string.' + } - #Remove file once converted - Remove-Item $WAUAboutPath -Force -Confirm:$false + # Security check + Write-ToLog -LogMsg '-> Checking Mods Directory:' -LogColor 'yellow' + $Protected = Invoke-ModsProtect ('{0}\mods' -f $WAUConfig.InstallLocation) - #log - Write-ToLog "-> $WAUAboutPath converted." "green" - } + if ($Protected -eq $True) + { + Write-ToLog -LogMsg '-> The mods directory is now secured!' -LogColor 'green' + } + elseif ($Protected -eq $False) + { + Write-ToLog -LogMsg '-> The mods directory was already secured!' -LogColor 'green' + } + else + { + Write-ToLog -LogMsg "-> Error: The mods directory couldn't be verified as secured!" -LogColor 'red' + } - #Convert config.xml if exists (previous WAU versions) to reg - $WAUConfigPath = "$WorkingDir\config\config.xml" - if (test-path $WAUConfigPath) { - [xml]$Config = Get-Content $WAUConfigPath -Encoding UTF8 -ErrorAction SilentlyContinue - if ($Config.app.WAUautoupdate -eq "False") { New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force } - if ($Config.app.NotificationLevel) { New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $Config.app.NotificationLevel -Force } - if ($Config.app.UseWAUWhiteList -eq "True") { New-ItemProperty $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force } - if ($Config.app.WAUprerelease -eq "True") { New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force } + # Convert about.xml if exists (old WAU versions) to reg + $WAUAboutPath = ('{0}\config\about.xml' -f $WorkingDir) - #Remove file once converted - Remove-Item $WAUConfigPath -Force -Confirm:$false + if (Test-Path -Path $WAUAboutPath -ErrorAction SilentlyContinue) + { + [xml]$About = Get-Content -Path $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue + $null = (New-ItemProperty -Path $regPath -Name DisplayVersion -Value $About.app.version -Force -Confirm:$False -ErrorAction SilentlyContinue) - #log - Write-ToLog "-> $WAUConfigPath converted." "green" - } + # Remove file once converted + $null = (Remove-Item -Path $WAUAboutPath -Force -Confirm:$False) - #Remove old functions / files - $FileNames = @( - "$WorkingDir\functions\Get-WAUConfig.ps1", - "$WorkingDir\functions\Get-WAUCurrentVersion.ps1", - "$WorkingDir\functions\Get-WAUUpdateStatus.ps1", - "$WorkingDir\functions\Write-Log.ps1", - "$WorkingDir\Version.txt" - ) - foreach ($FileName in $FileNames) { - if (Test-Path $FileName) { - Remove-Item $FileName -Force -Confirm:$false + #log + Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUAboutPath) -LogColor 'green' + } - #log - Write-ToLog "-> $FileName removed." "green" - } - } + # Convert config.xml if exists (previous WAU versions) to reg + $WAUConfigPath = ('{0}\config\config.xml' -f $WorkingDir) - #Remove old registry key - $RegistryKeys = @( - "VersionMajor", - "VersionMinor" - ) - foreach ($RegistryKey in $RegistryKeys) { - if (Get-ItemProperty -Path $regPath -Name $RegistryKey -ErrorAction SilentlyContinue) { - Remove-ItemProperty -Path $regPath -Name $RegistryKey - } - } + if (Test-Path -Path $WAUConfigPath -ErrorAction SilentlyContinue) + { + [xml]$Config = (Get-Content -Path $WAUConfigPath -Encoding UTF8 -ErrorAction SilentlyContinue) - #Reset WAU_UpdatePostActions Value - $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 0 -Force + if ($Config.app.WAUautoupdate -eq 'False') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) + } - #Get updated WAU Config - $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" + if ($Config.app.NotificationLevel) + { + $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $Config.app.NotificationLevel -Force -Confirm:$False -ErrorAction SilentlyContinue) + } - #log - Write-ToLog "Post Update actions finished" "green" + if ($Config.app.UseWAUWhiteList -eq 'True') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) + } + if ($Config.app.WAUprerelease -eq 'True') + { + $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) + } + + # Remove file once converted + $null = (Remove-Item -Path $WAUConfigPath -Force -Confirm:$False) + + # log + Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUConfigPath) -LogColor 'green' + } + + # Remove old functions / files + $FileNames = @( + ('{0}\functions\Get-WAUConfig.ps1' -f $WorkingDir), + ('{0}\functions\Get-WAUCurrentVersion.ps1' -f $WorkingDir), + ('{0}\functions\Get-WAUUpdateStatus.ps1' -f $WorkingDir), + ('{0}\functions\Write-Log.ps1' -f $WorkingDir), + ('{0}\Version.txt' -f $WorkingDir) + ) + + foreach ($FileName in $FileNames) + { + if (Test-Path -Path $FileName -ErrorAction SilentlyContinue) + { + $null = (Remove-Item -Path $FileName -Force -Confirm:$False -ErrorAction SilentlyContinue) + + # log + Write-ToLog -LogMsg ('-> {0} removed.' -f $FileName) -LogColor 'green' + } + } + + # Remove old registry key + $RegistryKeys = @( + 'VersionMajor', + 'VersionMinor' + ) + + foreach ($RegistryKey in $RegistryKeys) + { + if (Get-ItemProperty -Path $regPath -Name $RegistryKey -ErrorAction SilentlyContinue) + { + $null = (Remove-ItemProperty -Path $regPath -Name $RegistryKey -Force -Confirm:$False -ErrorAction SilentlyContinue) + } + } + + # Reset WAU_UpdatePostActions Value + $null = ($WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 0 -Force -Confirm:$False -ErrorAction SilentlyContinue) + + # Get updated WAU Config + $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') + + # log + Write-ToLog -LogMsg 'Post Update actions finished' -LogColor 'green' } diff --git a/Winget-AutoUpdate/functions/Start-Init.ps1 b/Winget-AutoUpdate/functions/Start-Init.ps1 index b937ceb..c0e713b 100644 --- a/Winget-AutoUpdate/functions/Start-Init.ps1 +++ b/Winget-AutoUpdate/functions/Start-Init.ps1 @@ -1,65 +1,71 @@ # Initialisation -function Start-Init { +function Start-Init +{ + # Config console output encoding + [Console]::OutputEncoding = [Text.Encoding]::UTF8 - #Config console output encoding - [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 + # Workaround for ARM64 (Access Denied / Win32 internal Server error) + $Script:ProgressPreference = 'SilentlyContinue' + $caller = ((Get-ChildItem -Path $MyInvocation.PSCommandPath).Name) - # Workaround for ARM64 (Access Denied / Win32 internal Server error) - $Script:ProgressPreference = 'SilentlyContinue' + if ($caller -eq 'Winget-Upgrade.ps1') + { + # Log Header + $Log = "`n##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-Culture).DateTimeFormat.ShortDatePattern)`n##################################################" + $Log | Write-Host + # Logs initialisation + $Script:LogFile = ('{0}\logs\updates.log' -f $WorkingDir) + } + elseif ($caller -eq 'Winget-AutoUpdate-Install.ps1') + { + $Script:LogFile = ('{0}\logs\updates.log' -f $WingetUpdatePath) + } - $caller = Get-ChildItem $MyInvocation.PSCommandPath | Select-Object -Expand Name - if ($caller -eq "Winget-Upgrade.ps1") { - #Log Header - $Log = "`n##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################" - $Log | Write-host - #Logs initialisation - $Script:LogFile = "$WorkingDir\logs\updates.log" - } - elseif ($caller -eq "Winget-AutoUpdate-Install.ps1") { - $Script:LogFile = "$WingetUpdatePath\logs\updates.log" - } + if (!(Test-Path -Path $LogFile -ErrorAction SilentlyContinue)) + { + # Create file if doesn't exist + $null = (New-Item -ItemType File -Path $LogFile -Force -Confirm:$false) + # Set ACL for users on logfile + $NewAcl = (Get-Acl -Path $LogFile) + $identity = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList S-1-5-11) + $fileSystemRights = 'Modify' + $type = 'Allow' + $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type + $fileSystemAccessRule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList) + $NewAcl.SetAccessRule($fileSystemAccessRule) + Set-Acl -Path $LogFile -AclObject $NewAcl + } + elseif ((Test-Path -Path $LogFile -ErrorAction SilentlyContinue) -and ($caller -eq 'Winget-AutoUpdate-Install.ps1')) + { + #Set ACL for users on logfile + $NewAcl = (Get-Acl -Path $LogFile) + $identity = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList S-1-5-11) + $fileSystemRights = 'Modify' + $type = 'Allow' + $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type + $fileSystemAccessRule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList) + $NewAcl.SetAccessRule($fileSystemAccessRule) + $null = (Set-Acl -Path $LogFile -AclObject $NewAcl) + } - if (!(Test-Path $LogFile)) { - #Create file if doesn't exist - New-Item -ItemType File -Path $LogFile -Force | Out-Null + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) + { + Write-Host -Object "`nCreating SymLink for log file (WAU-updates) in Intune Management Extension log folder" -ForegroundColor Yellow + $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue + } - #Set ACL for users on logfile - $NewAcl = Get-Acl -Path $LogFile - $identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11 - $fileSystemRights = "Modify" - $type = "Allow" - $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type - $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList - $NewAcl.SetAccessRule($fileSystemAccessRule) - Set-Acl -Path $LogFile -AclObject $NewAcl - } - elseif ((Test-Path $LogFile) -and ($caller -eq "Winget-AutoUpdate-Install.ps1")) { - #Set ACL for users on logfile - $NewAcl = Get-Acl -Path $LogFile - $identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11 - $fileSystemRights = "Modify" - $type = "Allow" - $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type - $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList - $NewAcl.SetAccessRule($fileSystemAccessRule) - Set-Acl -Path $LogFile -AclObject $NewAcl - } - - #Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink - if ((Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) { - Write-host "`nCreating SymLink for log file (WAU-updates) in Intune Management Extension log folder" -ForegroundColor Yellow - New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue | Out-Null - } - #Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink - if ((Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and (Test-Path "$WorkingDir\logs\install.log") -and !(Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log")) { - Write-host "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow - New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value "$WorkingDir\logs\install.log" -Force -ErrorAction SilentlyContinue | Out-Null - } - - if ($caller -eq "Winget-Upgrade.ps1") { - #Log file - $Log | out-file -filepath $LogFile -Append - } + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) + { + Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow + $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -ErrorAction SilentlyContinue) + } + if ($caller -eq 'Winget-Upgrade.ps1') + { + # Log file + $Log | Out-File -FilePath $LogFile -Append -Force + } } diff --git a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 index 6ffae41..8abb674 100644 --- a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 +++ b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 @@ -1,175 +1,184 @@ -#Function to send the notifications to user +# Function to send the notifications to user -function Start-NotifTask { +function Start-NotifTask +{ + [CmdletBinding()] + param( + [String]$Title = 'Winget-AutoUpdate', + [String]$Message, + [String]$MessageType, + [String]$Balise = 'WAU', + [String]$OnClickAction, + [String]$Body, + [String]$Button1Text, + [String]$Button1Action, + [Switch]$ButtonDismiss = $false, + [Switch]$UserRun = $false + ) - param( - [String]$Title = "Winget-AutoUpdate", - [String]$Message, - [String]$MessageType, - [String]$Balise = "WAU", - [String]$OnClickAction, - [String]$Body, - [String]$Button1Text, - [String]$Button1Action, - [Switch]$ButtonDismiss = $false, - [Switch]$UserRun = $false - ) + if (($WAUConfig.WAU_NotificationLevel -eq 'Full') -or ($WAUConfig.WAU_NotificationLevel -eq 'SuccessOnly' -and $MessageType -eq 'Success') -or ($UserRun)) + { + # XML Toast template creation + [xml]$ToastTemplate = New-Object -TypeName system.Xml.XmlDocument + $ToastTemplate.LoadXml("") - if (($WAUConfig.WAU_NotificationLevel -eq "Full") -or ($WAUConfig.WAU_NotificationLevel -eq "SuccessOnly" -and $MessageType -eq "Success") -or ($UserRun)) { + # Creation of visual node + $XMLvisual = $ToastTemplate.CreateElement('visual') - # XML Toast template creation - [xml]$ToastTemplate = New-Object system.Xml.XmlDocument - $ToastTemplate.LoadXml("") + # Creation of a binding node + $XMLbinding = $ToastTemplate.CreateElement('binding') + $null = $XMLvisual.AppendChild($XMLbinding) + $XMLbindingAtt1 = ($ToastTemplate.CreateAttribute('template')) + $XMLbindingAtt1.Value = 'ToastGeneric' + $null = $XMLbinding.Attributes.Append($XMLbindingAtt1) - # Creation of visual node - $XMLvisual = $ToastTemplate.CreateElement("visual") + $XMLimagepath = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) + if (Test-Path -Path $XMLimagepath -ErrorAction SilentlyContinue) + { + # Creation of a image node + $XMLimage = $ToastTemplate.CreateElement('image') + $null = $XMLbinding.AppendChild($XMLimage) + $XMLimageAtt1 = $ToastTemplate.CreateAttribute('placement') + $XMLimageAtt1.Value = 'appLogoOverride' + $null = $XMLimage.Attributes.Append($XMLimageAtt1) + $XMLimageAtt2 = $ToastTemplate.CreateAttribute('src') + $XMLimageAtt2.Value = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) + $null = $XMLimage.Attributes.Append($XMLimageAtt2) + } - # Creation of a binding node - $XMLbinding = $ToastTemplate.CreateElement("binding") - $XMLvisual.AppendChild($XMLbinding) | Out-Null - $XMLbindingAtt1 = ($ToastTemplate.CreateAttribute("template")) - $XMLbindingAtt1.Value = "ToastGeneric" - $XMLbinding.Attributes.Append($XMLbindingAtt1) | Out-Null + if ($Title) + { + # Creation of a text node + $XMLtitle = $ToastTemplate.CreateElement('text') + $XMLtitleText = $ToastTemplate.CreateTextNode($Title) + $null = $XMLtitle.AppendChild($XMLtitleText) + $null = $XMLbinding.AppendChild($XMLtitle) + } - $XMLimagepath = "$WorkingDir\icons\$MessageType.png" - if (Test-Path $XMLimagepath) { - # Creation of a image node - $XMLimage = $ToastTemplate.CreateElement("image") - $XMLbinding.AppendChild($XMLimage) | Out-Null - $XMLimageAtt1 = $ToastTemplate.CreateAttribute("placement") - $XMLimageAtt1.Value = "appLogoOverride" - $XMLimage.Attributes.Append($XMLimageAtt1) | Out-Null - $XMLimageAtt2 = $ToastTemplate.CreateAttribute("src") - $XMLimageAtt2.Value = "$WorkingDir\icons\$MessageType.png" - $XMLimage.Attributes.Append($XMLimageAtt2) | Out-Null - } + if ($Message) + { + # Creation of a text node + $XMLtext = $ToastTemplate.CreateElement('text') + $XMLtextText = $ToastTemplate.CreateTextNode($Message) + $null = $XMLtext.AppendChild($XMLtextText) + $null = $XMLbinding.AppendChild($XMLtext) + } - if ($Title) { - # Creation of a text node - $XMLtitle = $ToastTemplate.CreateElement("text") - $XMLtitleText = $ToastTemplate.CreateTextNode($Title) - $XMLtitle.AppendChild($XMLtitleText) | Out-Null - $XMLbinding.AppendChild($XMLtitle) | Out-Null - } + if ($Body) + { + # Creation of a group node + $XMLgroup = $ToastTemplate.CreateElement('group') + $null = $XMLbinding.AppendChild($XMLgroup) - if ($Message) { - # Creation of a text node - $XMLtext = $ToastTemplate.CreateElement("text") - $XMLtextText = $ToastTemplate.CreateTextNode($Message) - $XMLtext.AppendChild($XMLtextText) | Out-Null - $XMLbinding.AppendChild($XMLtext) | Out-Null - } + # Creation of a subgroup node + $XMLsubgroup = $ToastTemplate.CreateElement('subgroup') + $null = $XMLgroup.AppendChild($XMLsubgroup) - if ($Body) { - # Creation of a group node - $XMLgroup = $ToastTemplate.CreateElement("group") - $XMLbinding.AppendChild($XMLgroup) | Out-Null + # Creation of a text node + $XMLcontent = $ToastTemplate.CreateElement('text') + $XMLcontentText = $ToastTemplate.CreateTextNode($Body) + $null = $XMLcontent.AppendChild($XMLcontentText) + $null = $XMLsubgroup.AppendChild($XMLcontent) + $XMLcontentAtt1 = $ToastTemplate.CreateAttribute('hint-style') + $XMLcontentAtt1.Value = 'body' + $null = $XMLcontent.Attributes.Append($XMLcontentAtt1) + $XMLcontentAtt2 = $ToastTemplate.CreateAttribute('hint-wrap') + $XMLcontentAtt2.Value = 'true' + $null = $XMLcontent.Attributes.Append($XMLcontentAtt2) + } - # Creation of a subgroup node - $XMLsubgroup = $ToastTemplate.CreateElement("subgroup") - $XMLgroup.AppendChild($XMLsubgroup) | Out-Null + # Creation of actions node + $XMLactions = $ToastTemplate.CreateElement('actions') - # Creation of a text node - $XMLcontent = $ToastTemplate.CreateElement("text") - $XMLcontentText = $ToastTemplate.CreateTextNode($Body) - $XMLcontent.AppendChild($XMLcontentText) | Out-Null - $XMLsubgroup.AppendChild($XMLcontent) | Out-Null - $XMLcontentAtt1 = $ToastTemplate.CreateAttribute("hint-style") - $XMLcontentAtt1.Value = "body" - $XMLcontent.Attributes.Append($XMLcontentAtt1) | Out-Null - $XMLcontentAtt2 = $ToastTemplate.CreateAttribute("hint-wrap") - $XMLcontentAtt2.Value = "true" - $XMLcontent.Attributes.Append($XMLcontentAtt2) | Out-Null - } + if ($Button1Text) + { + # Creation of action node + $XMLaction = $ToastTemplate.CreateElement('action') + $null = $XMLactions.AppendChild($XMLaction) + $XMLactionAtt1 = $ToastTemplate.CreateAttribute('content') + $XMLactionAtt1.Value = $Button1Text + $null = $XMLaction.Attributes.Append($XMLactionAtt1) + if ($Button1Action) + { + $XMLactionAtt2 = $ToastTemplate.CreateAttribute('arguments') + $XMLactionAtt2.Value = $Button1Action + $null = $XMLaction.Attributes.Append($XMLactionAtt2) + $XMLactionAtt3 = $ToastTemplate.CreateAttribute('activationType') + $XMLactionAtt3.Value = 'Protocol' + $null = $XMLaction.Attributes.Append($XMLactionAtt3) + } + } - # Creation of actions node - $XMLactions = $ToastTemplate.CreateElement("actions") + if ($ButtonDismiss) + { + # Creation of action node + $XMLaction = $ToastTemplate.CreateElement('action') + $null = $XMLactions.AppendChild($XMLaction) + $XMLactionAtt1 = $ToastTemplate.CreateAttribute('content') + $XMLactionAtt1.Value = '' + $null = $XMLaction.Attributes.Append($XMLactionAtt1) + $XMLactionAtt2 = $ToastTemplate.CreateAttribute('arguments') + $XMLactionAtt2.Value = 'dismiss' + $null = $XMLaction.Attributes.Append($XMLactionAtt2) + $XMLactionAtt3 = $ToastTemplate.CreateAttribute('activationType') + $XMLactionAtt3.Value = 'system' + $null = $XMLaction.Attributes.Append($XMLactionAtt3) + } - if ($Button1Text) { - # Creation of action node - $XMLaction = $ToastTemplate.CreateElement("action") - $XMLactions.AppendChild($XMLaction) | Out-Null - $XMLactionAtt1 = $ToastTemplate.CreateAttribute("content") - $XMLactionAtt1.Value = $Button1Text - $XMLaction.Attributes.Append($XMLactionAtt1) | Out-Null - if ($Button1Action) { - $XMLactionAtt2 = $ToastTemplate.CreateAttribute("arguments") - $XMLactionAtt2.Value = $Button1Action - $XMLaction.Attributes.Append($XMLactionAtt2) | Out-Null - $XMLactionAtt3 = $ToastTemplate.CreateAttribute("activationType") - $XMLactionAtt3.Value = "Protocol" - $XMLaction.Attributes.Append($XMLactionAtt3) | Out-Null - } - } + # Creation of tag node + $XMLtag = $ToastTemplate.CreateElement('tag') + $XMLtagText = $ToastTemplate.CreateTextNode($Balise) + $null = $XMLtag.AppendChild($XMLtagText) - if ($ButtonDismiss) { - # Creation of action node - $XMLaction = $ToastTemplate.CreateElement("action") - $XMLactions.AppendChild($XMLaction) | Out-Null - $XMLactionAtt1 = $ToastTemplate.CreateAttribute("content") - $XMLactionAtt1.Value = "" - $XMLaction.Attributes.Append($XMLactionAtt1) | Out-Null - $XMLactionAtt2 = $ToastTemplate.CreateAttribute("arguments") - $XMLactionAtt2.Value = "dismiss" - $XMLaction.Attributes.Append($XMLactionAtt2) | Out-Null - $XMLactionAtt3 = $ToastTemplate.CreateAttribute("activationType") - $XMLactionAtt3.Value = "system" - $XMLaction.Attributes.Append($XMLactionAtt3) | Out-Null - } + # Add the visual node to the xml + $null = $ToastTemplate.LastChild.AppendChild($XMLvisual) + $null = $ToastTemplate.LastChild.AppendChild($XMLactions) + $null = $ToastTemplate.LastChild.AppendChild($XMLtag) - # Creation of tag node - $XMLtag = $ToastTemplate.CreateElement("tag") - $XMLtagText = $ToastTemplate.CreateTextNode($Balise) - $XMLtag.AppendChild($XMLtagText) | Out-Null + if ($OnClickAction) + { + $null = $ToastTemplate.toast.SetAttribute('activationType', 'Protocol') + $null = $ToastTemplate.toast.SetAttribute('launch', $OnClickAction) + } - # Add the visual node to the xml - $ToastTemplate.LastChild.AppendChild($XMLvisual) | Out-Null - $ToastTemplate.LastChild.AppendChild($XMLactions) | Out-Null - $ToastTemplate.LastChild.AppendChild($XMLtag) | Out-Null + # if not "Interactive" user, run as system + if ($IsSystem) + { + # Save XML to File + $ToastTemplateLocation = ('{0}\config\' -f $WAUConfig.InstallLocation) + if (!(Test-Path -Path $ToastTemplateLocation -ErrorAction SilentlyContinue)) + { + $null = (New-Item -ItemType Directory -Force -Confirm:$false -Path $ToastTemplateLocation) + } + + $ToastTemplate.Save(('{0}\notif.xml' -f $ToastTemplateLocation)) - if ($OnClickAction) { - $ToastTemplate.toast.SetAttribute("activationType", "Protocol") | Out-Null - $ToastTemplate.toast.SetAttribute("launch", $OnClickAction) | Out-Null - } + # Run Notify scheduled task to notify conneted users + $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue) + } + else + { + #else, run as connected user + # Load Assemblies + $null = (Add-Type -AssemblyName Windows.UI) + $null = (Add-Type -AssemblyName Windows.Data) + $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] + $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] - #if not "Interactive" user, run as system - if ($IsSystem) { + # Prepare XML + $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New() + $ToastXml.LoadXml($ToastTemplate.OuterXml) - #Save XML to File - $ToastTemplateLocation = "$($WAUConfig.InstallLocation)\config\" - if (!(Test-Path $ToastTemplateLocation)) { - New-Item -ItemType Directory -Force -Path $ToastTemplateLocation - } - $ToastTemplate.Save("$ToastTemplateLocation\notif.xml") + # Specify Launcher App ID + $LauncherID = 'Windows.SystemToast.Winget.Notification' - #Run Notify scheduled task to notify conneted users - Get-ScheduledTask -TaskName "Winget-AutoUpdate-Notify" -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue - - } - #else, run as connected user - else { - - #Load Assemblies - [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null - [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null - - #Prepare XML - $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New() - $ToastXml.LoadXml($ToastTemplate.OuterXml) - - #Specify Launcher App ID - $LauncherID = "Windows.SystemToast.Winget.Notification" - - #Prepare and Create Toast - $ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) - $ToastMessage.Tag = $ToastTemplate.toast.tag - [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) - - } - - #Wait for notification to display - Start-Sleep 3 - - } + # Prepare and Create Toast + $ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) + $ToastMessage.Tag = $ToastTemplate.toast.tag + [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) + } + # Wait for notification to display + Start-Sleep -Seconds 3 + } } diff --git a/Winget-AutoUpdate/functions/Test-ListPath.ps1 b/Winget-AutoUpdate/functions/Test-ListPath.ps1 index 2ec3d7b..210a1cc 100644 --- a/Winget-AutoUpdate/functions/Test-ListPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ListPath.ps1 @@ -1,83 +1,118 @@ -#Function to check Block/Allow List External Path +# Function to check Block/Allow List External Path -function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) { - # URL, UNC or Local Path - if ($UseWhiteList) { - $ListType = "included_apps.txt" - } - else { - $ListType = "excluded_apps.txt" - } +function Test-ListPath +{ + # URL, UNC or Local Path + [CmdletBinding()] + param + ( + [string]$ListPath, + [string]$UseWhiteList, + [string]$WingetUpdatePath + ) + + if ($UseWhiteList) + { + $ListType = 'included_apps.txt' + } + else + { + $ListType = 'excluded_apps.txt' + } - # Get local and external list paths - $LocalList = -join ($WingetUpdatePath, "\", $ListType) - $ExternalList = -join ($ListPath, "\", $ListType) + # Get local and external list paths + $LocalList = -join ($WingetUpdatePath, '\', $ListType) + $ExternalList = -join ($ListPath, '\', $ListType) - # Check if a list exists - if (Test-Path "$LocalList") { - $dateLocal = (Get-Item "$LocalList").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - } + # Check if a list exists + if (Test-Path -Path $LocalList -ErrorAction SilentlyContinue) + { + $dateLocal = (Get-Item -Path $LocalList).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } - # If path is URL - if ($ListPath -like "http*") { - $ExternalList = -join ($ListPath, "/", $ListType) - $wc = New-Object System.Net.WebClient - try { - $wc.OpenRead("$ExternalList").Close() | Out-Null - $dateExternal = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss") - if ($dateExternal -gt $dateLocal) { - try { - $wc.DownloadFile($ExternalList, $LocalList) - } - catch { - $Script:ReachNoPath = $True - return $False - } - return $true + # If path is URL + if ($ListPath -like 'http*') + { + $ExternalList = -join ($ListPath, '/', $ListType) + $wc = (New-Object -TypeName System.Net.WebClient) + + try + { + $null = $wc.OpenRead($ExternalList).Close() + $dateExternal = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') + + if ($dateExternal -gt $dateLocal) + { + try + { + $wc.DownloadFile($ExternalList, $LocalList) } - } - catch { - try { - $content = $wc.DownloadString("$ExternalList") - if ($null -ne $content -and $content -match "\w\.\w") { - $wc.DownloadFile($ExternalList, $LocalList) - return $true - } - else { - $Script:ReachNoPath = $True - return $False - } + catch + { + $Script:ReachNoPath = $True + return $False } - catch { - $Script:ReachNoPath = $True - return $False + return $True + } + } + catch + { + try + { + $content = $wc.DownloadString(('{0}' -f $ExternalList)) + + if ($null -ne $content -and $content -match '\w\.\w') + { + $wc.DownloadFile($ExternalList, $LocalList) + return $True } - } - } - # If path is UNC or local - else { - if (Test-Path -Path $ExternalList) { - try { - $dateExternal = (Get-Item "$ExternalList").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") + else + { + $Script:ReachNoPath = $True + return $False } - catch { - $Script:ReachNoPath = $True - return $False - } - if ($dateExternal -gt $dateLocal) { - try { - Copy-Item $ExternalList -Destination $LocalList -Force - } - catch { - $Script:ReachNoPath = $True - return $False - } - return $True - } - } - else { + } + catch + { $Script:ReachNoPath = $True - } - return $False - } + return $False + } + } + } + else + { + # If path is UNC or local + if (Test-Path -Path $ExternalList) + { + try + { + $dateExternal = (Get-Item -Path ('{0}' -f $ExternalList)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } + catch + { + $Script:ReachNoPath = $True + return $False + } + + if ($dateExternal -gt $dateLocal) + { + try + { + Copy-Item -Path $ExternalList -Destination $LocalList -Force + } + catch + { + $Script:ReachNoPath = $True + return $False + } + return $True + } + } + else + { + $Script:ReachNoPath = $True + } + + return $False + } } diff --git a/Winget-AutoUpdate/functions/Test-Mods.ps1 b/Winget-AutoUpdate/functions/Test-Mods.ps1 index f46d4da..03e53c1 100644 --- a/Winget-AutoUpdate/functions/Test-Mods.ps1 +++ b/Winget-AutoUpdate/functions/Test-Mods.ps1 @@ -1,34 +1,49 @@ -#Function to check if modification exists within 'mods' directory +# Function to check if modification exists within 'mods' directory -function Test-Mods ($app) { +function Test-Mods +{ + # Takes care of a null situation + [CmdletBinding()] + param + ( + [string]$app + ) - #Takes care of a null situation - $ModsPreInstall = $null - $ModsOverride = $null - $ModsUpgrade = $null - $ModsInstall = $null - $ModsInstalled = $null - - $Mods = "$WorkingDir\mods" - if (Test-Path "$Mods\$app-*") { - if (Test-Path "$Mods\$app-preinstall.ps1") { - $ModsPreInstall = "$Mods\$app-preinstall.ps1" - } - if (Test-Path "$Mods\$app-override.txt") { - $ModsOverride = Get-Content "$Mods\$app-override.txt" -Raw - } - if (Test-Path "$Mods\$app-install.ps1") { - $ModsInstall = "$Mods\$app-install.ps1" - $ModsUpgrade = "$Mods\$app-install.ps1" - } - if (Test-Path "$Mods\$app-upgrade.ps1") { - $ModsUpgrade = "$Mods\$app-upgrade.ps1" - } - if (Test-Path "$Mods\$app-installed.ps1") { - $ModsInstalled = "$Mods\$app-installed.ps1" - } - } - - return $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled + $ModsPreInstall = $null + $ModsOverride = $null + $ModsUpgrade = $null + $ModsInstall = $null + $ModsInstalled = $null + $Mods = ('{0}\mods' -f $WorkingDir) + + if (Test-Path -Path ('{0}\{1}-*' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + if (Test-Path -Path ('{0}\{1}-preinstall.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + $ModsPreInstall = ('{0}\{1}-preinstall.ps1' -f $Mods, $app) + } + + if (Test-Path -Path ('{0}\{1}-override.txt' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + $ModsOverride = Get-Content -Path ('{0}\{1}-override.txt' -f $Mods, $app) -Raw + } + + if (Test-Path -Path ('{0}\{1}-install.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + $ModsInstall = ('{0}\{1}-install.ps1' -f $Mods, $app) + $ModsUpgrade = ('{0}\{1}-install.ps1' -f $Mods, $app) + } + + if (Test-Path -Path ('{0}\{1}-upgrade.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + $ModsUpgrade = ('{0}\{1}-upgrade.ps1' -f $Mods, $app) + } + + if (Test-Path -Path ('{0}\{1}-installed.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + { + $ModsInstalled = ('{0}\{1}-installed.ps1' -f $Mods, $app) + } + } + return $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled } diff --git a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 index 9f468b1..3be0e88 100644 --- a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 @@ -1,233 +1,307 @@ #Function to check mods External Path -function Test-ModsPath ($ModsPath, $WingetUpdatePath, $AzureBlobSASURL) { - # URL, UNC or Local Path - # Get local and external Mods paths - $LocalMods = -join ($WingetUpdatePath, "\", "mods") - $ExternalMods = "$ModsPath" +function Test-ModsPath +{ + # URL, UNC or Local Path + # Get local and external Mods paths + + [CmdletBinding()] + param + ( + [string]$ModsPath, + [string]$WingetUpdatePath, + [string]$AzureBlobSASURL + ) + $LocalMods = -join ($WingetUpdatePath, '\', 'mods') + $ExternalMods = $ModsPath - #Get File Names Locally - $InternalModsNames = Get-ChildItem -Path $LocalMods -Name -Recurse -Include *.ps1, *.txt - $InternalBinsNames = Get-ChildItem -Path $LocalMods"\bins" -Name -Recurse -Include *.exe + # Get File Names Locally + $InternalModsNames = (Get-ChildItem -Path $LocalMods -Name -Recurse -Include *.ps1, *.txt -ErrorAction SilentlyContinue) + $InternalBinsNames = (Get-ChildItem -Path $LocalMods"\bins" -Name -Recurse -Include *.exe -ErrorAction SilentlyContinue) - # If path is URL - if ($ExternalMods -like "http*") { - # enable TLS 1.2 and TLS 1.1 protocols - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Tls11 - #Get Index of $ExternalMods (or index page with href listing of all the Mods) - try { - $WebResponse = Invoke-WebRequest -Uri $ExternalMods -UseBasicParsing - } - catch { - $Script:ReachNoPath = $True - return $False - } + # If path is URL + if ($ExternalMods -like 'http*') + { + # enable TLS 1.2 and TLS 1.1 protocols + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Tls11 + # Get Index of $ExternalMods (or index page with href listing of all the Mods) + try + { + $WebResponse = (Invoke-WebRequest -Uri $ExternalMods -UseBasicParsing) + } + catch + { + $Script:ReachNoPath = $True - #Check for bins, download if newer. Delete if not external - $ExternalBins = "$ModsPath/bins" - if ($WebResponse -match "bins/") { - $BinResponse = Invoke-WebRequest -Uri $ExternalBins -UseBasicParsing - # Collect the external list of href links - $BinLinks = $BinResponse.Links | Select-Object -ExpandProperty HREF - #If there's a directory path in the HREF:s, delete it (IIS) - $CleanBinLinks = $BinLinks -replace "/.*/", "" - #Modify strings to HREF:s - $index = 0 - foreach ($Bin in $CleanBinLinks) { - if ($Bin) { - $CleanBinLinks[$index] = ' ' + $Bin + '' - } - $index++ - } - #Delete Local Bins that don't exist Externally - $index = 0 - $CleanLinks = $BinLinks -replace "/.*/", "" - foreach ($Bin in $InternalBinsNames) { - If ($CleanLinks -notcontains "$Bin") { - Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null - } - $index++ - } - $CleanBinLinks = $BinLinks -replace "/.*/", "" - $Bin = "" - #Loop through all links - $wc = New-Object System.Net.WebClient - $CleanBinLinks | ForEach-Object { - #Check for .exe in listing/HREF:s in an index page pointing to .exe - if ($_ -like "*.exe") { - $dateExternalBin = "" - $dateLocalBin = "" - $wc.OpenRead("$ExternalBins/$_").Close() | Out-Null - $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss") - if (Test-Path -Path $LocalMods"\bins\"$_) { - $dateLocalBin = (Get-Item "$LocalMods\bins\$_").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - } - if ($dateExternalBin -gt $dateLocalBin) { - $SaveBin = Join-Path -Path "$LocalMods\bins" -ChildPath $_ - Invoke-WebRequest -Uri "$ExternalBins/$_" -OutFile $SaveBin.Replace("%20", " ") -UseBasicParsing - } - } - } - } + return $False + } - # Collect the external list of href links - $ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF - - #If there's a directory path in the HREF:s, delete it (IIS) - $CleanLinks = $ModLinks -replace "/.*/", "" - - #Modify strings to HREF:s - $index = 0 - foreach ($Mod in $CleanLinks) { - if ($Mod) { - $CleanLinks[$index] = ' ' + $Mod + '' + # Check for bins, download if newer. Delete if not external + $ExternalBins = ('{0}/bins' -f $ModsPath) + + if ($WebResponse -match 'bins/') + { + $BinResponse = Invoke-WebRequest -Uri $ExternalBins -UseBasicParsing + # Collect the external list of href links + $BinLinks = $BinResponse.Links | Select-Object -ExpandProperty HREF + # If there's a directory path in the HREF:s, delete it (IIS) + $CleanBinLinks = $BinLinks -replace '/.*/', '' + # Modify strings to HREF:s + $index = 0 + + foreach ($Bin in $CleanBinLinks) + { + if ($Bin) + { + $CleanBinLinks[$index] = ' ' + $Bin + '' } $index++ - } + } + + # Delete Local Bins that don't exist Externally + $index = 0 + $CleanLinks = $BinLinks -replace '/.*/', '' - #Delete Local Mods that don't exist Externally - $DeletedMods = 0 - $index = 0 - $CleanLinks = $ModLinks -replace "/.*/", "" - foreach ($Mod in $InternalModsNames) { - If ($CleanLinks -notcontains "$Mod") { - Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null - $DeletedMods++ + foreach ($Bin in $InternalBinsNames) + { + If ($CleanLinks -notcontains $Bin) + { + $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) } + $index++ - } + } - $CleanLinks = $ModLinks -replace "/.*/", "" + $CleanBinLinks = $BinLinks -replace '/.*/', '' + $Bin = '' + # Loop through all links + $wc = New-Object -TypeName System.Net.WebClient + $CleanBinLinks | ForEach-Object -Process { + # Check for .exe in listing/HREF:s in an index page pointing to .exe + if ($_ -like '*.exe') + { + $dateExternalBin = '' + $dateLocalBin = '' + $null = $wc.OpenRead(('{0}/{1}' -f $ExternalBins, $_)).Close() + $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - #Loop through all links - $wc = New-Object System.Net.WebClient - $CleanLinks | ForEach-Object { - #Check for .ps1/.txt in listing/HREF:s in an index page pointing to .ps1/.txt - if (($_ -like "*.ps1") -or ($_ -like "*.txt")) { - try { - $dateExternalMod = "" - $dateLocalMod = "" - $wc.OpenRead("$ExternalMods/$_").Close() | Out-Null - $dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss") - if (Test-Path -Path $LocalMods"\"$_) { - $dateLocalMod = (Get-Item "$LocalMods\$_").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - } + if (Test-Path -Path $LocalMods"\bins\"$_) + { + $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } - if ($dateExternalMod -gt $dateLocalMod) { - try { - $SaveMod = Join-Path -Path "$LocalMods\" -ChildPath $_ - $Mod = '{0}/{1}' -f $ModsPath.TrimEnd('/'), $_ - Invoke-WebRequest -Uri "$Mod" -OutFile $SaveMod -UseBasicParsing - $ModsUpdated++ - } - catch { - $Script:ReachNoPath = $True - } - } - } - catch { - if (($_ -like "*.ps1") -or ($_ -like "*.txt")) { - $Script:ReachNoPath = $True - } - } + if ($dateExternalBin -gt $dateLocalBin) + { + $SaveBin = Join-Path -Path ('{0}\bins' -f $LocalMods) -ChildPath $_ + Invoke-WebRequest -Uri ('{0}/{1}' -f $ExternalBins, $_) -OutFile $SaveBin.Replace('%20', ' ') -UseBasicParsing + } } - } - return $ModsUpdated, $DeletedMods - } - # If Path is Azure Blob - elseif ($ExternalMods -like "AzureBlob") { - Write-ToLog "Azure Blob Storage set as mod source" - Write-ToLog "Checking AZCopy" - Get-AZCopy $WingetUpdatePath - #Safety check to make sure we really do have azcopy.exe and a Blob URL - if ((Test-Path -Path "$WingetUpdatePath\azcopy.exe" -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) { - Write-ToLog "Syncing Blob storage with local storage" + } + } - $AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync "$AzureBlobSASURL" "$LocalMods" --from-to BlobLocal --delete-destination=true - $AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine) + # Collect the external list of href links + $ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF + # If there's a directory path in the HREF:s, delete it (IIS) + $CleanLinks = $ModLinks -replace '/.*/', '' + # Modify strings to HREF:s + $index = 0 - foreach ( $_ in $AZCopyOutputLines) { - $AZCopySyncAdditionsRegex = [regex]::new("(?<=Number of Copy Transfers Completed:\s+)\d+") - $AZCopySyncDeletionsRegex = [regex]::new("(?<=Number of Deletions at Destination:\s+)\d+") - $AZCopySyncErrorRegex = [regex]::new("^Cannot perform sync due to error:") + foreach ($Mod in $CleanLinks) + { + if ($Mod) + { + $CleanLinks[$index] = ' ' + $Mod + '' + } + $index++ + } - $AZCopyAdditions = [int] $AZCopySyncAdditionsRegex.Match($_).Value - $AZCopyDeletions = [int] $AZCopySyncDeletionsRegex.Match($_).Value + # Delete Local Mods that don't exist Externally + $DeletedMods = 0 + $index = 0 + $CleanLinks = $ModLinks -replace '/.*/', '' - if ($AZCopyAdditions -ne 0) { - $ModsUpdated = $AZCopyAdditions - } + foreach ($Mod in $InternalModsNames) + { + If ($CleanLinks -notcontains $Mod) + { + $null = (Remove-Item -Path $LocalMods\$Mod -Force -Confirm:$False -ErrorAction SilentlyContinue) + $DeletedMods++ + } + $index++ + } - if ($AZCopyDeletions -ne 0) { - $DeletedMods = $AZCopyDeletions - } + $CleanLinks = $ModLinks -replace '/.*/', '' - if ($AZCopySyncErrorRegex.Match($_).Value) { - Write-ToLog "AZCopy Sync Error! $_" - } + # Loop through all links + + $CleanLinks | ForEach-Object -Process { + # Check for .ps1/.txt in listing/HREF:s in an index page pointing to .ps1/.txt + if (($_ -like '*.ps1') -or ($_ -like '*.txt')) + { + try + { + $dateExternalMod = '' + $dateLocalMod = '' + $null = $wc.OpenRead(('{0}/{1}' -f $ExternalMods, $_)).Close() + $dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') + + if (Test-Path -Path $LocalMods"\"$_) + { + $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } + + if ($dateExternalMod -gt $dateLocalMod) + { + try + { + $SaveMod = Join-Path -Path ('{0}\' -f $LocalMods) -ChildPath $_ + $Mod = '{0}/{1}' -f $ModsPath.TrimEnd('/'), $_ + $null = (Invoke-WebRequest -Uri $Mod -OutFile $SaveMod -UseBasicParsing) + $ModsUpdated++ + } + catch + { + $Script:ReachNoPath = $True + } + } } - } - else { - Write-ToLog "Error 'azcopy.exe' or SAS Token not found!" - } - - return $ModsUpdated, $DeletedMods - } - # If path is UNC or local - else { - $ExternalBins = "$ModsPath\bins" - if (Test-Path -Path $ExternalBins"\*.exe") { - $ExternalBinsNames = Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe - #Delete Local Bins that don't exist Externally - foreach ($Bin in $InternalBinsNames) { - If ($Bin -notin $ExternalBinsNames ) { - Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null - } + catch + { + if (($_ -like '*.ps1') -or ($_ -like '*.txt')) + { + $Script:ReachNoPath = $True + } } - #Copy newer external bins - foreach ($Bin in $ExternalBinsNames) { - $dateExternalBin = "" - $dateLocalBin = "" - if (Test-Path -Path $LocalMods"\bins\"$Bin) { - $dateLocalBin = (Get-Item "$LocalMods\bins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - } - $dateExternalBin = (Get-Item "$ExternalBins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - if ($dateExternalBin -gt $dateLocalBin) { - Copy-Item $ExternalBins\$Bin -Destination $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null - } - } - } + } + } + return $ModsUpdated, $DeletedMods + } + # If Path is Azure Blob + elseif ($ExternalMods -like 'AzureBlob') + { + Write-ToLog -LogMsg 'Azure Blob Storage set as mod source' + Write-ToLog -LogMsg 'Checking AZCopy' + Get-AZCopy $WingetUpdatePath - if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) { - #Get File Names Externally - $ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt + # Safety check to make sure we really do have azcopy.exe and a Blob URL + if ((Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) + { + Write-ToLog -LogMsg 'Syncing Blob storage with local storage' - #Delete Local Mods that don't exist Externally - $DeletedMods = 0 - foreach ($Mod in $InternalModsNames) { - If ($Mod -notin $ExternalModsNames ) { - Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null - $DeletedMods++ - } + $AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync $AzureBlobSASURL $LocalMods --from-to BlobLocal --delete-destination=true + $AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine) + + foreach ( $_ in $AZCopyOutputLines) + { + $AZCopySyncAdditionsRegex = [regex]::new('(?<=Number of Copy Transfers Completed:\s+)\d+') + $AZCopySyncDeletionsRegex = [regex]::new('(?<=Number of Deletions at Destination:\s+)\d+') + $AZCopySyncErrorRegex = [regex]::new('^Cannot perform sync due to error:') + + $AZCopyAdditions = [int] $AZCopySyncAdditionsRegex.Match($_).Value + $AZCopyDeletions = [int] $AZCopySyncDeletionsRegex.Match($_).Value + + if ($AZCopyAdditions -ne 0) + { + $ModsUpdated = $AZCopyAdditions } - #Copy newer external mods - foreach ($Mod in $ExternalModsNames) { - $dateExternalMod = "" - $dateLocalMod = "" - if (Test-Path -Path $LocalMods"\"$Mod) { - $dateLocalMod = (Get-Item "$LocalMods\$Mod").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - } - $dateExternalMod = (Get-Item "$ExternalMods\$Mod").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") - if ($dateExternalMod -gt $dateLocalMod) { - Copy-Item $ExternalMods\$Mod -Destination $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null - $ModsUpdated++ - } + if ($AZCopyDeletions -ne 0) + { + $DeletedMods = $AZCopyDeletions } - } - else { - $Script:ReachNoPath = $True - } - return $ModsUpdated, $DeletedMods - } + + if ($AZCopySyncErrorRegex.Match($_).Value) + { + Write-ToLog -LogMsg ('AZCopy Sync Error! {0}' -f $_) + } + } + } + else + { + Write-ToLog -LogMsg "Error 'azcopy.exe' or SAS Token not found!" + } + + return $ModsUpdated, $DeletedMods + } + else + { + # If path is UNC or local + $ExternalBins = ('{0}\bins' -f $ModsPath) + + if (Test-Path -Path $ExternalBins"\*.exe") + { + $ExternalBinsNames = (Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe) + + # Delete Local Bins that don't exist Externally + foreach ($Bin in $InternalBinsNames) + { + If ($Bin -notin $ExternalBinsNames ) + { + $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) + } + } + + # Copy newer external bins + foreach ($Bin in $ExternalBinsNames) + { + $dateExternalBin = '' + $dateLocalBin = '' + + if (Test-Path -Path $LocalMods"\bins\"$Bin) + { + $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } + + $dateExternalBin = (Get-Item -Path ('{0}\{1}' -f $ExternalBins, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + + if ($dateExternalBin -gt $dateLocalBin) + { + $null = Copy-Item -Path $ExternalBins\$Bin -Destination $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue + } + } + } + + if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) + { + # Get File Names Externally + $ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt + + # Delete Local Mods that don't exist Externally + $DeletedMods = 0 + + foreach ($Mod in $InternalModsNames) + { + If ($Mod -notin $ExternalModsNames ) + { + $null = Remove-Item -Path $LocalMods\$Mod -Force -ErrorAction SilentlyContinue + $DeletedMods++ + } + } + + # Copy newer external mods + foreach ($Mod in $ExternalModsNames) + { + $dateExternalMod = '' + $dateLocalMod = '' + if (Test-Path -Path $LocalMods"\"$Mod) + { + $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + } + + $dateExternalMod = (Get-Item -Path ('{0}\{1}' -f $ExternalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') + + if ($dateExternalMod -gt $dateLocalMod) + { + $null = Copy-Item -Path $ExternalMods\$Mod -Destination $LocalMods\$Mod -Force -ErrorAction SilentlyContinue + $ModsUpdated++ + } + } + } + else + { + $Script:ReachNoPath = $True + } + + return $ModsUpdated, $DeletedMods + } } diff --git a/Winget-AutoUpdate/functions/Test-Network.ps1 b/Winget-AutoUpdate/functions/Test-Network.ps1 index 9910d26..7a50781 100644 --- a/Winget-AutoUpdate/functions/Test-Network.ps1 +++ b/Winget-AutoUpdate/functions/Test-Network.ps1 @@ -1,82 +1,77 @@ -#Function to check the connectivity +# Function to check the connectivity -function Test-Network { +function Test-Network +{ + #Init + + $timeout = 0 - #Init - $timeout = 0 + # Test connectivity during 30 min then timeout + Write-ToLog -LogMsg 'Checking internet connection...' -LogColor 'Yellow' + While ($timeout -lt 1800) + { + $URLtoTest = 'https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE' + $URLcontent = ((Invoke-WebRequest -Uri $URLtoTest -UseBasicParsing).content) - #Test connectivity during 30 min then timeout - Write-ToLog "Checking internet connection..." "Yellow" - While ($timeout -lt 1800) { + if ($URLcontent -like '*MIT License*') + { + Write-ToLog -LogMsg 'Connected !' -LogColor 'Green' - $URLtoTest = "https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE" - $URLcontent = ((Invoke-WebRequest -URI $URLtoTest -UseBasicParsing).content) + # Check for metered connection + $null = (Add-Type -AssemblyName Windows.Networking) + $null = [Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime] + $cost = [Windows.Networking.Connectivity.NetworkInformation]::GetInternetConnectionProfile().GetConnectionCost() - if ($URLcontent -like "*MIT License*") { - - Write-ToLog "Connected !" "Green" - - #Check for metered connection - [void][Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime] - $cost = [Windows.Networking.Connectivity.NetworkInformation]::GetInternetConnectionProfile().GetConnectionCost() - - if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne "Unrestricted")) { - - Write-ToLog "Metered connection detected." "Yellow" - - if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) { - - Write-ToLog "WAU is configured to bypass update checking on metered connection" - return $false - - } - else { - - Write-ToLog "WAU is configured to force update checking on metered connection" - return $true - - } + if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne 'Unrestricted')) + { + Write-ToLog -LogMsg 'Metered connection detected.' -LogColor 'Yellow' + if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) + { + Write-ToLog -LogMsg 'WAU is configured to bypass update checking on metered connection' + return $false } - else { - - return $true - + else + { + Write-ToLog -LogMsg 'WAU is configured to force update checking on metered connection' + return $true } + } + else + { + return $true + } + } + else + { + Start-Sleep -Seconds 10 + $timeout += 10 - } - else { + # Send Warning Notif if no connection for 5 min + if ($timeout -eq 300) + { + # Log + Write-ToLog -LogMsg "Notify 'No connection' sent." -LogColor 'Yellow' - Start-Sleep 10 - $timeout += 10 + # Notif + $Title = $NotifLocale.local.outputs.output[0].title + $Message = $NotifLocale.local.outputs.output[0].message + $MessageType = 'warning' + $Balise = 'Connection' + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise + } + } + } - #Send Warning Notif if no connection for 5 min - if ($timeout -eq 300) { - #Log - Write-ToLog "Notify 'No connection' sent." "Yellow" + # Send Timeout Notif if no connection for 30 min + Write-ToLog -LogMsg 'Timeout. No internet connection !' -LogColor 'Red' - #Notif - $Title = $NotifLocale.local.outputs.output[0].title - $Message = $NotifLocale.local.outputs.output[0].message - $MessageType = "warning" - $Balise = "Connection" - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise - } - - } - - } - - #Send Timeout Notif if no connection for 30 min - Write-ToLog "Timeout. No internet connection !" "Red" - - #Notif - $Title = $NotifLocale.local.outputs.output[1].title - $Message = $NotifLocale.local.outputs.output[1].message - $MessageType = "error" - $Balise = "Connection" - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise - - return $false + # Notif + $Title = $NotifLocale.local.outputs.output[1].title + $Message = $NotifLocale.local.outputs.output[1].message + $MessageType = 'error' + $Balise = 'Connection' + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise + return $false } diff --git a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 index bb1d52e..fb4235b 100644 --- a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 +++ b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 @@ -1,25 +1,34 @@ -#Function to check if there is a Pending Reboot +# Function to check if there is a Pending Reboot -function Test-PendingReboot { +function Test-PendingReboot +{ + $Computer = $env:COMPUTERNAME + $PendingReboot = $false - $Computer = $env:COMPUTERNAME - $PendingReboot = $false + $HKLM = [UInt32] '0x80000002' + $WMI_Reg = [WMIClass] ('\\{0}\root\default:StdRegProv' -f $Computer) - $HKLM = [UInt32] "0x80000002" - $WMI_Reg = [WMIClass] "\\$Computer\root\default:StdRegProv" + if ($WMI_Reg) + { + if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\')).sNames -contains 'RebootPending') + { + $PendingReboot = $true + } + if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\')).sNames -contains 'RebootRequired') + { + $PendingReboot = $true + } - if ($WMI_Reg) { - if (($WMI_Reg.EnumKey($HKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\")).sNames -contains 'RebootPending') { $PendingReboot = $true } - if (($WMI_Reg.EnumKey($HKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\")).sNames -contains 'RebootRequired') { $PendingReboot = $true } - - #Checking for SCCM namespace - $SCCM_Namespace = Get-WmiObject -Namespace ROOT\CCM\ClientSDK -List -ComputerName $Computer -ErrorAction Ignore - if ($SCCM_Namespace) { - if (([WmiClass]"\\$Computer\ROOT\CCM\ClientSDK:CCM_ClientUtilities").DetermineIfRebootPending().RebootPending -eq $true) { $PendingReboot = $true } - } - - } - - return $PendingReboot + # Checking for SCCM namespace + $SCCM_Namespace = Get-WmiObject -Namespace ROOT\CCM\ClientSDK -List -ComputerName $Computer -ErrorAction Ignore + if ($SCCM_Namespace) + { + if (([WmiClass]('\\{0}\ROOT\CCM\ClientSDK:CCM_ClientUtilities' -f $Computer)).DetermineIfRebootPending().RebootPending -eq $true) + { + $PendingReboot = $true + } + } + } + return $PendingReboot } diff --git a/Winget-AutoUpdate/functions/Update-App.ps1 b/Winget-AutoUpdate/functions/Update-App.ps1 index 7006b10..d9c3b49 100644 --- a/Winget-AutoUpdate/functions/Update-App.ps1 +++ b/Winget-AutoUpdate/functions/Update-App.ps1 @@ -1,123 +1,137 @@ -#Function to update an App +# Function to update an App -Function Update-App ($app) { +Function Update-App +{ + # Get App Info + [CmdletBinding()] + param + ( + $app + ) + $ReleaseNoteURL = Get-AppInfo $app.Id + if ($ReleaseNoteURL) + { + $Button1Text = $NotifLocale.local.outputs.output[10].message + } - #Get App Info - $ReleaseNoteURL = Get-AppInfo $app.Id - if ($ReleaseNoteURL) { - $Button1Text = $NotifLocale.local.outputs.output[10].message - } + # Send available update notification + Write-ToLog -LogMsg ('Updating {0} from {1} to {2}...' -f $app.Name, $app.Version, $app.AvailableVersion) -LogColor 'Cyan' + $Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name) + $Message = $NotifLocale.local.outputs.output[2].message -f $($app.Version), $($app.AvailableVersion) + $MessageType = 'info' + $Balise = $($app.Name) + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text - #Send available update notification - Write-ToLog "Updating $($app.Name) from $($app.Version) to $($app.AvailableVersion)..." "Cyan" - $Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name) - $Message = $NotifLocale.local.outputs.output[2].message -f $($app.Version), $($app.AvailableVersion) - $MessageType = "info" - $Balise = $($app.Name) - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text + # Check if mods exist for preinstall/install/upgrade + $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) - #Check if mods exist for preinstall/install/upgrade - $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) + # Winget upgrade + Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - #Winget upgrade - Write-ToLog "########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '$($App.Id)' ##########" "Gray" + # If PreInstall script exist + if ($ModsPreInstall) + { + Write-ToLog -LogMsg ('Modifications for {0} before upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' + & "$ModsPreInstall" + } - #If PreInstall script exist - if ($ModsPreInstall) { - Write-ToLog "Modifications for $($app.Id) before upgrade are being applied..." "Yellow" - & "$ModsPreInstall" - } + # Run Winget Upgrade command + if ($ModsOverride) + { + Write-ToLog -LogMsg ('-> Running (overriding default): Winget upgrade --id {0} --accept-package-agreements --accept-source-agreements --override {1}' -f $app.Id, $ModsOverride) + & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -FilePath $LogFile -Append + } + else + { + Write-ToLog -LogMsg ('-> Running: Winget upgrade --id {0} --accept-package-agreements --accept-source-agreements -h' -f $app.Id) + & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -FilePath $LogFile -Append + } - #Run Winget Upgrade command - if ($ModsOverride) { - Write-ToLog "-> Running (overriding default): Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride" - & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -file $LogFile -Append - } - else { - Write-ToLog "-> Running: Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h" - & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -file $LogFile -Append - } + if ($ModsUpgrade) + { + Write-ToLog -LogMsg ('Modifications for {0} during upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' + & "$ModsUpgrade" + } - if ($ModsUpgrade) { - Write-ToLog "Modifications for $($app.Id) during upgrade are being applied..." "Yellow" - & "$ModsUpgrade" - } + # Check if application updated properly + $FailedToUpgrade = $false + $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - #Check if application updated properly - $FailedToUpgrade = $false - $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) + if ($ConfirmInstall -ne $true) + { + # Upgrade failed! + # Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities) + $PendingReboot = Test-PendingReboot + if ($PendingReboot -eq $true) + { + Write-ToLog -LogMsg ("-> A Pending Reboot lingers and probably prohibited {0} from upgrading...`n-> ...an install for {1} is NOT executed!" -f $app.Name) -LogColor 'Red' + $FailedToUpgrade = $true + break + } - if ($ConfirmInstall -ne $true) { - #Upgrade failed! - #Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities) - $PendingReboot = Test-PendingReboot - if ($PendingReboot -eq $true) { - Write-ToLog "-> A Pending Reboot lingers and probably prohibited $($app.Name) from upgrading...`n-> ...an install for $($app.Name) is NOT executed!" "Red" - $FailedToUpgrade = $true - break - } + # If app failed to upgrade, run Install command + Write-ToLog -LogMsg ('-> An upgrade for {0} failed, now trying an install instead...' -f $app.Name) -LogColor 'Yellow' - #If app failed to upgrade, run Install command - Write-ToLog "-> An upgrade for $($app.Name) failed, now trying an install instead..." "Yellow" + if ($ModsOverride) + { + Write-ToLog -LogMsg ('-> Running (overriding default): Winget install --id {0} --accept-package-agreements --accept-source-agreements --force --override {1}' -f $app.Id, $ModsOverride) + & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force --override $ModsOverride | Tee-Object -FilePath $LogFile -Append + } + else + { + Write-ToLog -LogMsg ('-> Running: Winget install --id {0} --accept-package-agreements --accept-source-agreements --force -h' -f $app.Id) + & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force -h | Tee-Object -FilePath $LogFile -Append + } - if ($ModsOverride) { - Write-ToLog "-> Running (overriding default): Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force --override $ModsOverride" - & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force --override $ModsOverride | Tee-Object -file $LogFile -Append - } - else { - Write-ToLog "-> Running: Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force -h" - & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force -h | Tee-Object -file $LogFile -Append - } + if ($ModsInstall) + { + Write-ToLog -LogMsg ('Modifications for {0} during install are being applied...' -f $app.Id) -LogColor 'Yellow' + & "$ModsInstall" + } - if ($ModsInstall) { - Write-ToLog "Modifications for $($app.Id) during install are being applied..." "Yellow" - & "$ModsInstall" - } + # Check if application installed properly + $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) + if ($ConfirmInstall -eq $false) + { + $FailedToUpgrade = $true + } + } - #Check if application installed properly - $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - if ($ConfirmInstall -eq $false) { - $FailedToUpgrade = $true - } - } + if ($FailedToUpgrade -eq $false) + { + if ($ModsInstalled) + { + Write-ToLog -LogMsg ('Modifications for {0} after upgrade/install are being applied...' -f $app.Id) -LogColor 'Yellow' + & "$ModsInstalled" + } + } - if ($FailedToUpgrade -eq $false) { - if ($ModsInstalled) { - Write-ToLog "Modifications for $($app.Id) after upgrade/install are being applied..." "Yellow" - & "$ModsInstalled" - } - } + Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - Write-ToLog "########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '$($App.Id)' ##########" "Gray" + # Notify installation + if ($FailedToUpgrade -eq $false) + { + # Send success updated app notification + Write-ToLog -LogMsg ('{0} updated to {1} !' -f $app.Name, $app.AvailableVersion) -LogColor 'Green' - #Notify installation - if ($FailedToUpgrade -eq $false) { + # Send Notif + $Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name) + $Message = $NotifLocale.local.outputs.output[3].message -f $($app.AvailableVersion) + $MessageType = 'success' + $Balise = $($app.Name) + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text + $Script:InstallOK += 1 + } + else + { + # Send failed updated app notification + Write-ToLog -LogMsg ('{0} update failed.' -f $app.Name) -LogColor 'Red' - #Send success updated app notification - Write-ToLog "$($app.Name) updated to $($app.AvailableVersion) !" "Green" - - #Send Notif - $Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name) - $Message = $NotifLocale.local.outputs.output[3].message -f $($app.AvailableVersion) - $MessageType = "success" - $Balise = $($app.Name) - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text - - $Script:InstallOK += 1 - - } - else { - - #Send failed updated app notification - Write-ToLog "$($app.Name) update failed." "Red" - - #Send Notif - $Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name) - $Message = $NotifLocale.local.outputs.output[4].message - $MessageType = "error" - $Balise = $($app.Name) - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text - - } - -} \ No newline at end of file + # Send Notif + $Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name) + $Message = $NotifLocale.local.outputs.output[4].message + $MessageType = 'error' + $Balise = $($app.Name) + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text + } +} diff --git a/Winget-AutoUpdate/functions/Update-WAU.ps1 b/Winget-AutoUpdate/functions/Update-WAU.ps1 index 123deb9..0e9d74b 100644 --- a/Winget-AutoUpdate/functions/Update-WAU.ps1 +++ b/Winget-AutoUpdate/functions/Update-WAU.ps1 @@ -1,77 +1,74 @@ -#Function to update WAU +# Function to update WAU -function Update-WAU { +function Update-WAU +{ + $OnClickAction = 'https://github.com/Romanitho/Winget-AutoUpdate/releases' + $Button1Text = $NotifLocale.local.outputs.output[10].message - $OnClickAction = "https://github.com/Romanitho/Winget-AutoUpdate/releases" - $Button1Text = $NotifLocale.local.outputs.output[10].message + #Send available update notification + $Title = $NotifLocale.local.outputs.output[2].title -f 'Winget-AutoUpdate' + $Message = $NotifLocale.local.outputs.output[2].message -f $WAUCurrentVersion, $WAUAvailableVersion + $MessageType = 'info' + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - #Send available update notification - $Title = $NotifLocale.local.outputs.output[2].title -f "Winget-AutoUpdate" - $Message = $NotifLocale.local.outputs.output[2].message -f $WAUCurrentVersion, $WAUAvailableVersion - $MessageType = "info" - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text + # Run WAU update + try + { + # Force to create a zip file + $ZipFile = ('{0}\WAU_update.zip' -f $WorkingDir) + $null = New-Item -Path $ZipFile -ItemType File -Force - #Run WAU update - try { + # Download the zip + Write-ToLog -LogMsg ('Downloading the GitHub Repository version {0}' -f $WAUAvailableVersion) -LogColor 'Cyan' + $null = (Invoke-RestMethod -Uri ('https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v{0}/WAU.zip' -f ($WAUAvailableVersion)) -OutFile $ZipFile) - #Force to create a zip file - $ZipFile = "$WorkingDir\WAU_update.zip" - New-Item $ZipFile -ItemType File -Force | Out-Null + # Extract Zip File + Write-ToLog -LogMsg 'Unzipping the WAU Update package' -LogColor 'Cyan' + $location = ('{0}\WAU_update' -f $WorkingDir) + $null = (Expand-Archive -Path $ZipFile -DestinationPath $location -Force) + $null = (Get-ChildItem -Path $location -Recurse | Unblock-File -ErrorAction SilentlyContinue) - #Download the zip - Write-ToLog "Downloading the GitHub Repository version $WAUAvailableVersion" "Cyan" - Invoke-RestMethod -Uri "https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v$($WAUAvailableVersion)/WAU.zip" -OutFile $ZipFile + # Update scritps + Write-ToLog -LogMsg 'Updating WAU...' -LogColor 'Yellow' + $TempPath = (Resolve-Path -Path ('{0}\Winget-AutoUpdate\' -f $location) -ErrorAction SilentlyContinue)[0].Path + if ($TempPath) + { + $null = (Copy-Item -Path ('{0}\*' -f $TempPath) -Destination ('{0}\' -f $WorkingDir) -Exclude 'icons' -Recurse -Force -Confirm:$false) + } - #Extract Zip File - Write-ToLog "Unzipping the WAU Update package" "Cyan" - $location = "$WorkingDir\WAU_update" - Expand-Archive -Path $ZipFile -DestinationPath $location -Force - Get-ChildItem -Path $location -Recurse | Unblock-File + # Remove update zip file and update temp folder + Write-ToLog -LogMsg 'Done. Cleaning temp files...' -LogColor 'Cyan' + $null = (Remove-Item -Path $ZipFile -Force -Confirm:$false -ErrorAction SilentlyContinue) + $null = (Remove-Item -Path $location -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue) - #Update scritps - Write-ToLog "Updating WAU..." "Yellow" - $TempPath = (Resolve-Path "$location\Winget-AutoUpdate\")[0].Path - if ($TempPath) { - Copy-Item -Path "$TempPath\*" -Destination "$WorkingDir\" -Exclude "icons" -Recurse -Force - } + # Set new version to registry + $WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force + $WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Major -Force + $WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Minor -Force - #Remove update zip file and update temp folder - Write-ToLog "Done. Cleaning temp files..." "Cyan" - Remove-Item -Path $ZipFile -Force -ErrorAction SilentlyContinue - Remove-Item -Path $location -Recurse -Force -ErrorAction SilentlyContinue + # Set Post Update actions to 1 + $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force - #Set new version to registry - $WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force - $WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion.Replace("-", ".")).Major -Force - $WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion.Replace("-", ".")).Minor -Force + # Send success Notif + Write-ToLog -LogMsg 'WAU Update completed.' -LogColor 'Green' + $Title = $NotifLocale.local.outputs.output[3].title -f 'Winget-AutoUpdate' + $Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion + $MessageType = 'success' + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - #Set Post Update actions to 1 - $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force + # Rerun with newer version + Write-ToLog -LogMsg 'Re-run WAU' + Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" - #Send success Notif - Write-ToLog "WAU Update completed." "Green" - $Title = $NotifLocale.local.outputs.output[3].title -f "Winget-AutoUpdate" - $Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion - $MessageType = "success" - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - - #Rerun with newer version - Write-ToLog "Re-run WAU" - Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" - - exit - - } - - catch { - - #Send Error Notif - $Title = $NotifLocale.local.outputs.output[4].title -f "Winget-AutoUpdate" - $Message = $NotifLocale.local.outputs.output[4].message - $MessageType = "error" - Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - Write-ToLog "WAU Update failed" "Red" - - } - -} \ No newline at end of file + exit + } + catch + { + # Send Error Notif + $Title = $NotifLocale.local.outputs.output[4].title -f 'Winget-AutoUpdate' + $Message = $NotifLocale.local.outputs.output[4].message + $MessageType = 'error' + Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text + Write-ToLog -LogMsg 'WAU Update failed' -LogColor 'Red' + } +} diff --git a/Winget-AutoUpdate/functions/Write-ToLog.ps1 b/Winget-AutoUpdate/functions/Write-ToLog.ps1 index db1116e..d1b7c21 100644 --- a/Winget-AutoUpdate/functions/Write-ToLog.ps1 +++ b/Winget-AutoUpdate/functions/Write-ToLog.ps1 @@ -1,14 +1,20 @@ -#Write to Log Function +# Write to Log Function -function Write-ToLog ($LogMsg, $LogColor = "White") { +function Write-ToLog +{ + # Get log + [CmdletBinding()] + param + ( + [string]$LogMsg, + [string]$LogColor = 'White' + ) - #Get log - $Log = "$(Get-Date -UFormat "%T") - $LogMsg" + $Log = ('{0} - {1}' -f (Get-Date -UFormat '%T'), $LogMsg) - #Echo log - $Log | Write-host -ForegroundColor $LogColor - - #Write log to file - $Log | Out-File -FilePath $LogFile -Append + #Echo log + $Log | Write-Host -ForegroundColor $LogColor + #Write log to file + $Log | Out-File -FilePath $LogFile -Append -Force -Confirm:$false } From 6c118323f953fa345b6249529cc45ae3ee813944 Mon Sep 17 00:00:00 2001 From: Joerg Hochwald Date: Fri, 15 Sep 2023 16:38:54 +0200 Subject: [PATCH 2/4] Minor format changes --- Winget-AutoUpdate-Install.ps1 | 351 ++++----- Winget-AutoUpdate/User-Run.ps1 | 38 +- Winget-AutoUpdate/WAU-Uninstall.ps1 | 41 +- Winget-AutoUpdate/Winget-Notify.ps1 | 2 +- Winget-AutoUpdate/Winget-Upgrade.ps1 | 670 ++++++++++-------- .../functions/Add-ScopeMachine.ps1 | 28 +- Winget-AutoUpdate/functions/Add-Shortcut.ps1 | 21 +- .../functions/Confirm-Installation.ps1 | 22 +- Winget-AutoUpdate/functions/Get-AZCopy.ps1 | 43 +- Winget-AutoUpdate/functions/Get-AppInfo.ps1 | 9 +- .../functions/Get-ExcludedApps.ps1 | 18 +- .../functions/Get-IncludedApps.ps1 | 16 +- .../functions/Get-NotifLocale.ps1 | 53 +- Winget-AutoUpdate/functions/Get-Policies.ps1 | 235 +++--- .../functions/Get-WAUAvailableVersion.ps1 | 10 +- Winget-AutoUpdate/functions/Get-WingetCmd.ps1 | 90 +-- .../functions/Get-WingetOutdatedApps.ps1 | 50 +- .../functions/Get-WingetSystemApps.ps1 | 10 +- .../functions/Invoke-LogRotation.ps1 | 69 +- .../functions/Invoke-ModsProtect.ps1 | 37 +- .../functions/Invoke-PostUpdateActions.ps1 | 176 ++--- Winget-AutoUpdate/functions/Start-Init.ps1 | 28 +- .../functions/Start-NotifTask.ps1 | 102 +-- Winget-AutoUpdate/functions/Test-ListPath.ps1 | 69 +- Winget-AutoUpdate/functions/Test-Mods.ps1 | 31 +- Winget-AutoUpdate/functions/Test-ModsPath.ps1 | 183 ++--- Winget-AutoUpdate/functions/Test-Network.ps1 | 40 +- .../functions/Test-PendingReboot.ps1 | 26 +- Winget-AutoUpdate/functions/Update-App.ps1 | 66 +- Winget-AutoUpdate/functions/Update-WAU.ps1 | 30 +- Winget-AutoUpdate/functions/Write-ToLog.ps1 | 14 +- 31 files changed, 1364 insertions(+), 1214 deletions(-) diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index 79d3261..bc1db00 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -91,78 +91,107 @@ #> [CmdletBinding()] -param( - [Alias('S')] [Switch] $Silent = $false, - [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate", - [Alias('List')] [String] $ListPath, - [Alias('Mods')] [String] $ModsPath, - [Alias('AzureBlobURL')] [String] $AzureBlobSASURL, - [Switch] $DoNotUpdate = $false, - [Switch] $DisableWAUAutoUpdate = $false, - [Switch] $RunOnMetered = $false, - [Switch] $Uninstall = $false, - [Switch] $NoClean = $false, - [Switch] $DesktopShortcut = $false, - [Switch] $StartMenuShortcut = $false, - [Switch] $UseWhiteList = $false, - [ValidateSet('Full', 'SuccessOnly', 'None')] [String] $NotificationLevel = 'Full', - [Switch] $UpdatesAtLogon = $false, - [ValidateSet('Daily', 'BiDaily', 'Weekly', 'BiWeekly', 'Monthly', 'Never')] [String] $UpdatesInterval = 'Daily', - [DateTime] $UpdatesAtTime = ('06am'), - [Switch] $BypassListForUsers = $false, - [Switch] $InstallUserContext = $false, - [ValidateRange(0, 99)] [int] $MaxLogFiles = 3, - [long] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB +param ( + [Alias('S')] + [Switch] + $Silent = $false, + [Alias('Path')] + [String] + $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate", + [Alias('List')] + [String] + $ListPath, + [Alias('Mods')] + [String] + $ModsPath, + [Alias('AzureBlobURL')] + [String] + $AzureBlobSASURL, + [Switch] + $DoNotUpdate = $false, + [Switch] + $DisableWAUAutoUpdate = $false, + [Switch] + $RunOnMetered = $false, + [Switch] + $Uninstall = $false, + [Switch] + $NoClean = $false, + [Switch] + $DesktopShortcut = $false, + [Switch] + $StartMenuShortcut = $false, + [Switch] + $UseWhiteList = $false, + [ValidateSet('Full', 'SuccessOnly', 'None')] + [String] + $NotificationLevel = 'Full', + [Switch] + $UpdatesAtLogon = $false, + [ValidateSet('Daily', 'BiDaily', 'Weekly', 'BiWeekly', 'Monthly', 'Never')] + [String] + $UpdatesInterval = 'Daily', + [DateTime] + $UpdatesAtTime = ('06am'), + [Switch] + $BypassListForUsers = $false, + [Switch] + $InstallUserContext = $false, + [ValidateRange(0, 99)] + [int] + $MaxLogFiles = 3, + [long] + $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB ) <# FUNCTIONS #> -function Install-Prerequisites -{ +function Install-Prerequisites +{ Write-Host -Object "`nChecking prerequisites..." -ForegroundColor Yellow - + #Check if Visual C++ 2019 or 2022 installed $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' $path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object -FilterScript { - $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 + $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 } - + #If not installed, ask for installation - if (!($path)) + if (!($path)) { #If -silent option, force installation - if ($Silent) + if ($Silent) { $InstallApp = 1 } - else + else { #Ask for installation $MsgBoxTitle = 'Winget Prerequisites' $MsgBoxContent = 'Microsoft Visual C++ 2015-2022 is required. Would you like to install it?' $MsgBoxTimeOut = 60 $MsgBoxReturn = (New-Object -ComObject 'Wscript.Shell').Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) - if ($MsgBoxReturn -ne 7) + if ($MsgBoxReturn -ne 7) { $InstallApp = 1 } - else + else { $InstallApp = 0 } } #Install if approved - if ($InstallApp -eq 1) + if ($InstallApp -eq 1) { - try + try { - if ((Get-CimInstance Win32_OperatingSystem).OSArchitecture -like '*64*') + if ((Get-CimInstance Win32_OperatingSystem).OSArchitecture -like '*64*') { $OSArch = 'x64' } - else + else { $OSArch = 'x86' } @@ -176,247 +205,247 @@ function Install-Prerequisites Remove-Item $Installer -ErrorAction Ignore Write-Host -Object 'MS Visual C++ 2015-2022 installed successfully' -ForegroundColor Green } - catch + catch { Write-Host -Object 'MS Visual C++ 2015-2022 installation failed.' -ForegroundColor Red Start-Sleep -Seconds 3 } } - else + else { Write-Host -Object '-> MS Visual C++ 2015-2022 will not be installed.' -ForegroundColor Magenta } } - else + else { Write-Host -Object 'Prerequisites checked. OK' -ForegroundColor Green } } -function Install-WinGet -{ +function Install-WinGet +{ Write-Host -Object "`nChecking if Winget is installed" -ForegroundColor Yellow - + #Check Package Install $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { - $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' + $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' } - + #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 - If ([Version]$TestWinGet.Version -ge '2023.808.2243.0') + if ([Version]$TestWinGet.Version -ge '2023.808.2243.0') { Write-Host -Object 'Winget is Installed' -ForegroundColor Green } - Else - { + else + { Write-Host -Object '-> Winget is not installed:' - + #Check if $WingetUpdatePath exist - if (!(Test-Path $WingetUpdatePath)) + if (!(Test-Path $WingetUpdatePath)) { $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath } - + #Downloading and Installing Dependencies in SYSTEM context - if (!(Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7')) + if (!(Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7')) { Write-Host -Object '-> Downloading Microsoft.UI.Xaml.2.7...' $UiXamlUrl = 'https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.0' $UiXamlZip = "$WingetUpdatePath\Microsoft.UI.XAML.2.7.zip" Invoke-RestMethod -Uri $UiXamlUrl -OutFile $UiXamlZip Expand-Archive -Path $UiXamlZip -DestinationPath "$WingetUpdatePath\extracted" -Force - try + try { Write-Host -Object '-> Installing Microsoft.UI.Xaml.2.7...' $null = Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\extracted\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx" -SkipLicense Write-Host -Object 'Microsoft.UI.Xaml.2.7 installed successfully' -ForegroundColor Green } - catch + catch { Write-Host -Object 'Failed to intall Wicrosoft.UI.Xaml.2.7...' -ForegroundColor Red } Remove-Item -Path $UiXamlZip -Force Remove-Item -Path "$WingetUpdatePath\extracted" -Force -Recurse } - - if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop')) + + if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop')) { Write-Host -Object '-> Downloading Microsoft.VCLibs.140.00.UWPDesktop...' $VCLibsUrl = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx' $VCLibsFile = "$WingetUpdatePath\Microsoft.VCLibs.x64.14.00.Desktop.appx" Invoke-RestMethod -Uri $VCLibsUrl -OutFile $VCLibsFile - try + try { Write-Host -Object '-> Installing Microsoft.VCLibs.140.00.UWPDesktop...' $null = Add-AppxProvisionedPackage -Online -PackagePath $VCLibsFile -SkipLicense Write-Host -Object 'Microsoft.VCLibs.140.00.UWPDesktop installed successfully' -ForegroundColor Green } - catch + catch { Write-Host -Object 'Failed to intall Microsoft.VCLibs.140.00.UWPDesktop...' -ForegroundColor Red } Remove-Item -Path $VCLibsFile -Force } - + #Download WinGet MSIXBundle Write-Host -Object '-> Downloading Winget MSIXBundle for App Installer...' $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($WinGetURL, "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle") - + #Install WinGet MSIXBundle in SYSTEM context - try + try { Write-Host -Object '-> Installing Winget MSIXBundle for App Installer...' $null = Add-AppxProvisionedPackage -Online -PackagePath "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -SkipLicense Write-Host -Object 'Winget MSIXBundle for App Installer installed successfully' -ForegroundColor Green } - catch + catch { Write-Host -Object 'Failed to intall Winget MSIXBundle for App Installer...' -ForegroundColor Red } - + #Remove WinGet MSIXBundle Remove-Item -Path "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue } } -function Install-WingetAutoUpdate -{ +function Install-WingetAutoUpdate +{ Write-Host -Object "`nInstalling WAU..." -ForegroundColor Yellow - - try + + try { #Copy files to location (and clean old install) - if (!(Test-Path $WingetUpdatePath)) + if (!(Test-Path $WingetUpdatePath)) { $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath } - else + else { - if (!$NoClean) + if (!$NoClean) { Remove-Item -Path "$WingetUpdatePath\*" -Exclude *.log -Recurse -Force } - else + else { #Keep critical files Get-ChildItem -Path $WingetUpdatePath -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force } } Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - + #White List or Black List apps - if ($UseWhiteList) + if ($UseWhiteList) { - if (!$NoClean) + if (!$NoClean) { - if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) + if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) { Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } - else + else { - if (!$ListPath) + if (!$ListPath) { $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue } } } - elseif (!(Test-Path -Path "$WingetUpdatePath\included_apps.txt")) + elseif (!(Test-Path -Path "$WingetUpdatePath\included_apps.txt")) { - if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) + if ((Test-Path -Path "$PSScriptRoot\included_apps.txt")) { Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } - else + else { - if (!$ListPath) + if (!$ListPath) { $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue } } } } - else + else { - if (!$NoClean) + if (!$NoClean) { Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } - elseif (!(Test-Path -Path "$WingetUpdatePath\excluded_apps.txt")) + elseif (!(Test-Path -Path "$WingetUpdatePath\excluded_apps.txt")) { Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } } - + # Set dummy regkeys for notification name and icon $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v DisplayName /t REG_EXPAND_SZ /d 'Application Update' /f $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v IconUri /t REG_EXPAND_SZ /d %SystemRoot%\system32\@WindowsUpdateToastIcon.png /f - + # Settings for the scheduled task for Updates $taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($WingetUpdatePath)\winget-upgrade.ps1`"" $taskTriggers = @() - if ($UpdatesAtLogon) + if ($UpdatesAtLogon) { $taskTriggers += New-ScheduledTaskTrigger -AtLogOn } - if ($UpdatesInterval -eq 'Daily') + if ($UpdatesInterval -eq 'Daily') { $taskTriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime } - elseif ($UpdatesInterval -eq 'BiDaily') + elseif ($UpdatesInterval -eq 'BiDaily') { $taskTriggers += New-ScheduledTaskTrigger -Daily -At $UpdatesAtTime -DaysInterval 2 } - elseif ($UpdatesInterval -eq 'Weekly') + elseif ($UpdatesInterval -eq 'Weekly') { $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 } - elseif ($UpdatesInterval -eq 'BiWeekly') + elseif ($UpdatesInterval -eq 'BiWeekly') { $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 2 } - elseif ($UpdatesInterval -eq 'Monthly') + elseif ($UpdatesInterval -eq 'Monthly') { $taskTriggers += New-ScheduledTaskTrigger -Weekly -At $UpdatesAtTime -DaysOfWeek 2 -WeeksInterval 4 } $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 - if ($taskTriggers) + if ($taskTriggers) { $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings -Trigger $taskTriggers } - else + else { $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings } - + $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate' -InputObject $task -Force - - if ($InstallUserContext) + + if ($InstallUserContext) { # Settings for the scheduled task in User context $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-upgrade.ps1`"`"" $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 - + # Set up the task for user apps $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force } - + # Settings for the scheduled task for Notifications $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-notify.ps1`"`"" $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 $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -InputObject $task -Force - + #Set task readable/runnable for all users $scheduler = New-Object -ComObject 'Schedule.Service' $scheduler.Connect() @@ -424,7 +453,7 @@ function Install-WingetAutoUpdate $sec = $task.GetSecurityDescriptor(0xF) $sec = $sec + '(A;;GRGX;;;AU)' $task.SetSecurityDescriptor($sec, 0) - + # Configure Reg Key $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' $null = New-Item $regPath -Force @@ -443,67 +472,67 @@ function Install-WingetAutoUpdate { $null = New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force } - else + else { $null = New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force } $null = New-ItemProperty $regPath -Name WAU_PostUpdateActions -Value 0 -PropertyType DWord -Force $null = New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $MaxLogFiles -PropertyType DWord -Force $null = New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $MaxLogSize -PropertyType DWord -Force - if ($DisableWAUAutoUpdate) + if ($DisableWAUAutoUpdate) { $null = New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force } - if ($UseWhiteList) + if ($UseWhiteList) { $null = New-ItemProperty $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force } - if (!$RunOnMetered) + if (!$RunOnMetered) { $null = New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force } - if ($ListPath) + if ($ListPath) { $null = New-ItemProperty $regPath -Name WAU_ListPath -Value $ListPath -Force } - if ($ModsPath) + if ($ModsPath) { $null = New-ItemProperty $regPath -Name WAU_ModsPath -Value $ModsPath -Force } - if ($AzureBlobSASURL) + if ($AzureBlobSASURL) { $null = New-ItemProperty $regPath -Name WAU_AzureBlobSASURL -Value $AzureBlobSASURL -Force } - if ($BypassListForUsers) + if ($BypassListForUsers) { $null = New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force } - + #Log file and symlink initialization . "$WingetUpdatePath\functions\Start-Init.ps1" Start-Init - + #Security check Write-Host -Object "`nChecking Mods Directory:" -ForegroundColor Yellow . "$WingetUpdatePath\functions\Invoke-ModsProtect.ps1" $Protected = Invoke-ModsProtect "$WingetUpdatePath\mods" - if ($Protected -eq $True) + if ($Protected -eq $True) { Write-Host -Object "The mods directory is now secured!`n" -ForegroundColor Green } - elseif ($Protected -eq $false) + elseif ($Protected -eq $false) { Write-Host -Object "The mods directory was already secured!`n" -ForegroundColor Green } - else + else { Write-Host -Object "Error: The mods directory couldn't be verified as secured!`n" -ForegroundColor Red } - + #Create Shortcuts - if ($StartMenuShortcut) + if ($StartMenuShortcut) { - if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" } @@ -511,19 +540,19 @@ function Install-WingetAutoUpdate Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' } - - if ($DesktopShortcut) + + if ($DesktopShortcut) { Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' } - + Write-Host -Object 'WAU Installation succeeded!' -ForegroundColor Green Start-Sleep -Seconds 1 - + #Run Winget ? Start-WingetAutoUpdate } - catch + catch { Write-Host -Object 'WAU Installation failed! Run me with admin rights' -ForegroundColor Red Start-Sleep -Seconds 1 @@ -531,31 +560,31 @@ function Install-WingetAutoUpdate } } -function Uninstall-WingetAutoUpdate -{ +function Uninstall-WingetAutoUpdate +{ Write-Host -Object "`nUninstalling WAU..." -ForegroundColor Yellow - - try + + try { #Get registry install location $InstallLocation = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation - + #Check if installed location exists and delete - if (Test-Path ($InstallLocation)) - { - if (!$NoClean) + if (Test-Path ($InstallLocation)) + { + if (!$NoClean) { Remove-Item $InstallLocation -Force -Recurse - if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") { $null = Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -ErrorAction SilentlyContinue } - if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log") + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log") { $null = Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -ErrorAction SilentlyContinue } } - else + else { #Keep critical files Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force @@ -565,94 +594,90 @@ function Uninstall-WingetAutoUpdate Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f - - if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force } - - if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) + + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { $null = Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force } - + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green Start-Sleep -Seconds 1 } - else + else { Write-Host -Object "$InstallLocation not found! Uninstallation failed!" -ForegroundColor Red } } - catch + catch { Write-Host -Object 'Uninstallation failed! Run as admin ?' -ForegroundColor Red Start-Sleep -Seconds 1 } } -function Start-WingetAutoUpdate +function Start-WingetAutoUpdate { #If -DoNotUpdate is true, skip. - if (!($DoNotUpdate)) + if (!($DoNotUpdate)) { #If -Silent, run Winget-AutoUpdate now - if ($Silent) + if ($Silent) { $RunWinget = 1 } #Ask for WingetAutoUpdate - else + else { $MsgBoxTitle = 'Winget-AutoUpdate' $MsgBoxContent = 'Would you like to run Winget-AutoUpdate now?' $MsgBoxTimeOut = 60 $MsgBoxReturn = (New-Object -ComObject 'Wscript.Shell').Popup($MsgBoxContent, $MsgBoxTimeOut, $MsgBoxTitle, 4 + 32) - if ($MsgBoxReturn -ne 7) + if ($MsgBoxReturn -ne 7) { $RunWinget = 1 } - else + else { $RunWinget = 0 } } - if ($RunWinget -eq 1) + if ($RunWinget -eq 1) { - try + try { Write-Host -Object "`nRunning Winget-AutoUpdate..." -ForegroundColor Yellow Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue - while ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate').State -ne 'Ready') + while ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate').State -ne 'Ready') { Start-Sleep -Seconds 1 } } - catch + catch { Write-Host -Object 'Failed to run Winget-AutoUpdate...' -ForegroundColor Red } } } - else + else { Write-Host -Object 'Skip running Winget-AutoUpdate' } } -function Add-Shortcut -{ +function Add-Shortcut +{ [CmdletBinding()] param ( $Target, - $Shortcut, - $Arguments, - $Icon, - $Description ) $WScriptShell = New-Object -ComObject WScript.Shell @@ -673,12 +698,12 @@ $WAUVersion = Get-Content -Path "$PSScriptRoot\Winget-AutoUpdate\Version.txt" -E <# MAIN #> #If running as a 32-bit process on an x64 system, re-launch as a 64-bit process -if ("$env:PROCESSOR_ARCHITEW6432" -ne 'ARM64') +if ("$env:PROCESSOR_ARCHITEW6432" -ne 'ARM64') { - if (Test-Path -Path "$($env:windir)\SysNative\WindowsPowerShell\v1.0\powershell.exe") + if (Test-Path -Path "$($env:windir)\SysNative\WindowsPowerShell\v1.0\powershell.exe") { Start-Process -FilePath "$($env:windir)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -Wait -NoNewWindow -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command $($MyInvocation.line)" - Exit $lastexitcode + exit $lastexitcode } } @@ -695,14 +720,14 @@ Write-Host -Object "`t Winget-AutoUpdate $WAUVersion`n" -Foregro Write-Host -Object "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta Write-Host -Object "`t________________________________________________________`n`n" -if (!$Uninstall) +if (!$Uninstall) { Write-Host -Object "Installing WAU to $WingetUpdatePath\" Install-Prerequisites Install-WinGet Install-WingetAutoUpdate } -else +else { Write-Host -Object 'Uninstalling WAU...' Uninstall-WingetAutoUpdate diff --git a/Winget-AutoUpdate/User-Run.ps1 b/Winget-AutoUpdate/User-Run.ps1 index bec2dea..07910ed 100644 --- a/Winget-AutoUpdate/User-Run.ps1 +++ b/Winget-AutoUpdate/User-Run.ps1 @@ -18,16 +18,18 @@ #> [CmdletBinding()] -param( - [Switch] $Logs = $False, - [Switch] $Help = $False +param ( + [Switch] + $Logs = $False, + [Switch] + $Help = $False ) -function Test-WAUisRunning +function Test-WAUisRunning { - If (((Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue).State -eq 'Running') -or ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue).State -eq 'Running')) + if (((Get-ScheduledTask -TaskName 'Winget-AutoUpdate' -ErrorAction SilentlyContinue).State -eq 'Running') -or ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue).State -eq 'Running')) { - Return $True + return $True } } @@ -47,13 +49,13 @@ Get-NotifLocale $OnClickAction = ('{0}\logs\updates.log' -f $WorkingDir) $Button1Text = $NotifLocale.local.outputs.output[11].message -if ($Logs) +if ($Logs) { - if (Test-Path -Path ('{0}\logs\updates.log' -f $WorkingDir)) + if (Test-Path -Path ('{0}\logs\updates.log' -f $WorkingDir)) { Invoke-Item -Path ('{0}\logs\updates.log' -f $WorkingDir) } - else + else { #Not available yet $Message = $NotifLocale.local.outputs.output[5].message @@ -61,16 +63,16 @@ if ($Logs) Start-NotifTask -Message $Message -MessageType $MessageType -UserRun } } -elseif ($Help) +elseif ($Help) { Start-Process -FilePath 'https://github.com/Romanitho/Winget-AutoUpdate' } -else +else { - try + try { # Check if WAU is currently running - if (Test-WAUisRunning) + if (Test-WAUisRunning) { $Message = $NotifLocale.local.outputs.output[8].message $MessageType = 'warning' @@ -84,13 +86,13 @@ else $MessageType = 'info' Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun # Sleep until the task is done - While (Test-WAUisRunning) + while (Test-WAUisRunning) { Start-Sleep -Seconds 3 } - + # Test if there was a list_/winget_error - if (Test-Path -Path ('{0}\logs\error.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + if (Test-Path -Path ('{0}\logs\error.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) { $MessageType = 'error' $Critical = Get-Content -Path ('{0}\logs\error.txt' -f $WorkingDir) -Raw @@ -98,14 +100,14 @@ else $Critical = $Critical.Substring(0, [Math]::Min($Critical.Length, 50)) $Message = ("Critical:`n{0}..." -f $Critical) } - else + else { $MessageType = 'success' $Message = $NotifLocale.local.outputs.output[9].message } Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun } - catch + catch { # Check failed - Just send notification $Message = $NotifLocale.local.outputs.output[7].message diff --git a/Winget-AutoUpdate/WAU-Uninstall.ps1 b/Winget-AutoUpdate/WAU-Uninstall.ps1 index c715a9a..089a2a6 100644 --- a/Winget-AutoUpdate/WAU-Uninstall.ps1 +++ b/Winget-AutoUpdate/WAU-Uninstall.ps1 @@ -14,8 +14,9 @@ #> [CmdletBinding()] -param( - [Switch] $NoClean = $false +param ( + [Switch] + $NoClean = $false ) Write-Host -Object "`n" @@ -31,21 +32,21 @@ Write-Host -Object "`t Winget-AutoUpdate`n" -ForegroundColor Write-Host -Object "`t https://github.com/Romanitho/Winget-AutoUpdate`n" -ForegroundColor Magenta Write-Host -Object "`t________________________________________________________`n`n" -try +try { Write-Host -Object 'Uninstalling WAU...' -ForegroundColor Yellow - + # Get registry install location $InstallLocation = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation) - + # Check if installed location exists and delete - if (Test-Path -Path ($InstallLocation)) + if (Test-Path -Path ($InstallLocation)) { - if (!$NoClean) + if (!$NoClean) { $null = (Remove-Item -Path ('{0}\*' -f $InstallLocation) -Force -Confirm:$false -Recurse -Exclude '*.log') } - else + else { # Keep critical files $null = (Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue) @@ -55,40 +56,40 @@ try $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false) $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f - - if (Test-Path -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' -ErrorAction SilentlyContinue) + + if (Test-Path -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' -ErrorAction SilentlyContinue) { $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f } - - if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) } - - if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) + + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) } - + # Remove Intune Logs if they are existing - if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -Force -Confirm:$false -ErrorAction SilentlyContinue) } - if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue) + if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue) { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -Confirm:$false -ErrorAction SilentlyContinue) } - + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green } - else + else { Write-Host -Object ('{0} not found! Uninstallation failed!' -f $InstallLocation) -ForegroundColor Red } } -catch +catch { Write-Host -Object "`nUninstallation failed! Run as admin ?" -ForegroundColor Red } diff --git a/Winget-AutoUpdate/Winget-Notify.ps1 b/Winget-AutoUpdate/Winget-Notify.ps1 index e6036cf..4164a6f 100644 --- a/Winget-AutoUpdate/Winget-Notify.ps1 +++ b/Winget-AutoUpdate/Winget-Notify.ps1 @@ -4,7 +4,7 @@ $WAUinstalledPath = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation) [xml]$NotifConf = (Get-Content -Path "$WAUinstalledPath\config\notif.xml" -Encoding UTF8 -ErrorAction SilentlyContinue) -if (!($NotifConf)) +if (!($NotifConf)) { break } diff --git a/Winget-AutoUpdate/Winget-Upgrade.ps1 b/Winget-AutoUpdate/Winget-Upgrade.ps1 index f36eb8e..1a9eb3d 100644 --- a/Winget-AutoUpdate/Winget-Upgrade.ps1 +++ b/Winget-AutoUpdate/Winget-Upgrade.ps1 @@ -4,7 +4,9 @@ $Script:WorkingDir = $PSScriptRoot # Get Functions -Get-ChildItem -Path "$WorkingDir\functions" | ForEach-Object { . $_.FullName } +Get-ChildItem -Path "$WorkingDir\functions" | ForEach-Object { + . $_.FullName +} <# MAIN #> @@ -18,55 +20,66 @@ Start-Init $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') #Log running context and more... -if ($IsSystem) { - Write-ToLog 'Running in System context' - - #Get and set Domain/Local Policies (GPO) - $ActivateGPOManagement, $ChangedSettings = Get-Policies - if ($ActivateGPOManagement) { - Write-ToLog 'Activated WAU GPO Management detected, comparing...' - if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { - Write-ToLog 'Changed settings detected and applied' 'Yellow' - } - else { - Write-ToLog 'No Changed settings detected' 'Yellow' - } - } - - # Maximum number of log files to keep. Default is 3. Setting MaxLogFiles to 0 will keep all log files. - $MaxLogFiles = $WAUConfig.WAU_MaxLogFiles - if ($null -eq $MaxLogFiles) { - [int] $MaxLogFiles = 3 - } - else { - [int] $MaxLogFiles = $MaxLogFiles - } - - # Maximum size of log file. - $MaxLogSize = $WAUConfig.WAU_MaxLogSize - if (!$MaxLogSize) { - [long] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB - } - else { - [long] $MaxLogSize = $MaxLogSize - } - - #LogRotation if System - $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize - if ($LogRotate -eq $False) { - Write-ToLog 'An Exception occured during Log Rotation...' - } - - #Run post update actions if necessary if run as System - if (!($WAUConfig.WAU_PostUpdateActions -eq 0)) { - Invoke-PostUpdateActions - } - #Run Scope Machine funtion if run as System - $SettingsPath = "$Env:windir\system32\config\systemprofile\AppData\Local\Microsoft\WinGet\Settings\defaultState\settings.json" - Add-ScopeMachine $SettingsPath +if ($IsSystem) +{ + Write-ToLog 'Running in System context' + + #Get and set Domain/Local Policies (GPO) + $ActivateGPOManagement, $ChangedSettings = Get-Policies + if ($ActivateGPOManagement) + { + Write-ToLog 'Activated WAU GPO Management detected, comparing...' + if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) + { + Write-ToLog 'Changed settings detected and applied' 'Yellow' + } + else + { + Write-ToLog 'No Changed settings detected' 'Yellow' + } + } + + # Maximum number of log files to keep. Default is 3. Setting MaxLogFiles to 0 will keep all log files. + $MaxLogFiles = $WAUConfig.WAU_MaxLogFiles + if ($null -eq $MaxLogFiles) + { + [int]$MaxLogFiles = 3 + } + else + { + [int]$MaxLogFiles = $MaxLogFiles + } + + # Maximum size of log file. + $MaxLogSize = $WAUConfig.WAU_MaxLogSize + if (!$MaxLogSize) + { + [long]$MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB + } + else + { + [long]$MaxLogSize = $MaxLogSize + } + + #LogRotation if System + $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize + if ($LogRotate -eq $False) + { + Write-ToLog 'An Exception occured during Log Rotation...' + } + + #Run post update actions if necessary if run as System + if (!($WAUConfig.WAU_PostUpdateActions -eq 0)) + { + Invoke-PostUpdateActions + } + #Run Scope Machine funtion if run as System + $SettingsPath = "$Env:windir\system32\config\systemprofile\AppData\Local\Microsoft\WinGet\Settings\defaultState\settings.json" + Add-ScopeMachine $SettingsPath } -else { - Write-ToLog 'Running in User context' +else +{ + Write-ToLog 'Running in User context' } #Get Notif Locale function @@ -74,270 +87,331 @@ $LocaleDisplayName = Get-NotifLocale Write-ToLog "Notification Level: $($WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" 'Cyan' #Check network connectivity -if (Test-Network) { - #Check if Winget is installed and get Winget cmd - $TestWinget = Get-WingetCmd - - if ($TestWinget) { - #Get Current Version - $WAUCurrentVersion = $WAUConfig.DisplayVersion - Write-ToLog "WAU current version: $WAUCurrentVersion" - if ($IsSystem) { - #Check if WAU update feature is enabled or not if run as System - $WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate - #If yes then check WAU update if run as System - if ($WAUDisableAutoUpdate -eq 1) { - Write-ToLog 'WAU AutoUpdate is Disabled.' 'Gray' +if (Test-Network) +{ + #Check if Winget is installed and get Winget cmd + $TestWinget = Get-WingetCmd + + if ($TestWinget) + { + #Get Current Version + $WAUCurrentVersion = $WAUConfig.DisplayVersion + Write-ToLog "WAU current version: $WAUCurrentVersion" + if ($IsSystem) + { + #Check if WAU update feature is enabled or not if run as System + $WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate + #If yes then check WAU update if run as System + if ($WAUDisableAutoUpdate -eq 1) + { + Write-ToLog 'WAU AutoUpdate is Disabled.' 'Gray' + } + else + { + Write-ToLog 'WAU AutoUpdate is Enabled.' 'Green' + #Get Available Version + $Script:WAUAvailableVersion = Get-WAUAvailableVersion + #Compare + if ([version]$WAUAvailableVersion.Replace('-', '.') -ne [version]$WAUCurrentVersion.Replace('-', '.')) + { + #If new version is available, update it + Write-ToLog "WAU Available version: $WAUAvailableVersion" 'Yellow' + Update-WAU } - else { - Write-ToLog 'WAU AutoUpdate is Enabled.' 'Green' - #Get Available Version - $Script:WAUAvailableVersion = Get-WAUAvailableVersion - #Compare - if ([version]$WAUAvailableVersion.Replace('-', '.') -ne [version]$WAUCurrentVersion.Replace('-', '.')) { - #If new version is available, update it - Write-ToLog "WAU Available version: $WAUAvailableVersion" 'Yellow' - Update-WAU - } - else { - Write-ToLog 'WAU is up to date.' 'Green' - } + else + { + Write-ToLog 'WAU is up to date.' 'Green' } - - #Delete previous list_/winget_error (if they exist) if run as System - if (Test-Path -Path "$WorkingDir\logs\error.txt") { - Remove-Item -Path "$WorkingDir\logs\error.txt" -Force + } + + #Delete previous list_/winget_error (if they exist) if run as System + if (Test-Path -Path "$WorkingDir\logs\error.txt") + { + Remove-Item -Path "$WorkingDir\logs\error.txt" -Force + } + + #Get External ListPath if run as System + if ($WAUConfig.WAU_ListPath) + { + $ListPathClean = $($WAUConfig.WAU_ListPath.TrimEnd(' ', '\', '/')) + Write-ToLog "WAU uses External Lists from: $ListPathClean" + if ($ListPathClean -ne 'GPO') + { + $NewList = Test-ListPath $ListPathClean $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(' ', '\') + if ($ReachNoPath) + { + Write-ToLog "Couldn't reach/find/compare/copy from $ListPathClean..." 'Red' + if ($ListPathClean -notlike 'http*') + { + if (Test-Path -Path "$ListPathClean" -PathType Leaf) + { + Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' + } + } + else + { + if ($ListPathClean -match '_apps.txt') + { + Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' + } + } + $Script:ReachNoPath = $False + } + if ($NewList) + { + Write-ToLog "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))" 'Yellow' + } + else + { + if ($WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\included_apps.txt")) + { + Write-ToLog 'List (white) is up to date.' 'Green' + } + elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\excluded_apps.txt")) + { + Write-ToLog 'List (black) is up to date.' 'Green' + } + else + { + Write-ToLog "Critical: White/Black List doesn't exist, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist" -Force + exit 1 + } + } } - - #Get External ListPath if run as System - if ($WAUConfig.WAU_ListPath) { - $ListPathClean = $($WAUConfig.WAU_ListPath.TrimEnd(' ', '\', '/')) - Write-ToLog "WAU uses External Lists from: $ListPathClean" - if ($ListPathClean -ne 'GPO') { - $NewList = Test-ListPath $ListPathClean $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(' ', '\') - if ($ReachNoPath) { - Write-ToLog "Couldn't reach/find/compare/copy from $ListPathClean..." 'Red' - if ($ListPathClean -notlike 'http*') { - if (Test-Path -Path "$ListPathClean" -PathType Leaf) { - Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' - } - } - else { - if ($ListPathClean -match '_apps.txt') { - Write-ToLog 'PATH must end with a Directory, not a File...' 'Red' - } - } - $Script:ReachNoPath = $False - } - if ($NewList) { - Write-ToLog "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))" 'Yellow' - } - else { - if ($WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\included_apps.txt")) { - Write-ToLog 'List (white) is up to date.' 'Green' - } - elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path -Path "$WorkingDir\excluded_apps.txt")) { - Write-ToLog 'List (black) is up to date.' 'Green' - } - else { - Write-ToLog "Critical: White/Black List doesn't exist, exiting..." 'Red' - New-Item -Path "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist" -Force - Exit 1 - } - } - } + } + + #Get External ModsPath if run as System + if ($WAUConfig.WAU_ModsPath) + { + $ModsPathClean = $($WAUConfig.WAU_ModsPath.TrimEnd(' ', '\', '/')) + Write-ToLog "WAU uses External Mods from: $ModsPathClean" + if ($WAUConfig.WAU_AzureBlobSASURL) + { + $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') $WAUConfig.WAU_AzureBlobSASURL.TrimEnd(' ') } - - #Get External ModsPath if run as System - if ($WAUConfig.WAU_ModsPath) { - $ModsPathClean = $($WAUConfig.WAU_ModsPath.TrimEnd(' ', '\', '/')) - Write-ToLog "WAU uses External Mods from: $ModsPathClean" - if ($WAUConfig.WAU_AzureBlobSASURL) { - $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') $WAUConfig.WAU_AzureBlobSASURL.TrimEnd(' ') - } - else { - $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') - } - if ($ReachNoPath) { - Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." 'Red' - $Script:ReachNoPath = $False - } - if ($NewMods -gt 0) { - Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Yellow' - } - else { - if (Test-Path -Path "$WorkingDir\mods\*.ps1") { - Write-ToLog 'Mods are up to date.' 'Green' - } - else { - Write-ToLog 'No Mods are implemented...' 'Yellow' - } - } - if ($DeletedMods -gt 0) { - Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Red' - } + else + { + $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.TrimEnd(' ', '\') } - - #Test if _WAU-mods.ps1 exist: Mods for WAU (if Network is active/any Winget is installed/running as SYSTEM) - $Mods = "$WorkingDir\mods" - if (Test-Path -Path "$Mods\_WAU-mods.ps1") { - Write-ToLog 'Running Mods for WAU...' 'Yellow' - & "$Mods\_WAU-mods.ps1" - $ModsExitCode = $LASTEXITCODE - #If _WAU-mods.ps1 has ExitCode 1 - Re-run WAU - if ($ModsExitCode -eq 1) { - Write-ToLog 'Re-run WAU' - Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" - Exit - } + if ($ReachNoPath) + { + Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." 'Red' + $Script:ReachNoPath = $False } - - } - - if ($($WAUConfig.WAU_ListPath) -eq 'GPO') { - $Script:GPOList = $True - } - - #Get White or Black list - if ($WAUConfig.WAU_UseWhiteList -eq 1) { - Write-ToLog 'WAU uses White List config' - $toUpdate = Get-IncludedApps - $UseWhiteList = $true - } - else { - Write-ToLog 'WAU uses Black List config' - $toSkip = Get-ExcludedApps - } - - #Fix and count the array if GPO List as ERROR handling! - if ($GPOList) { - if ($UseWhiteList) { - $WhiteList = $toUpdate.GetUpperBound(0) - if ($null -eq $WhiteList) { - Write-ToLog "Critical: Whitelist doesn't exist in GPO, exiting..." 'Red' - New-Item -Path "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force - Exit 1 - } - $toUpdate = $toUpdate.Data + if ($NewMods -gt 0) + { + Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Yellow' } - else { - $BlackList = $toSkip.GetUpperBound(0) - if ($null -eq $BlackList) { - Write-ToLog "Critical: Blacklist doesn't exist in GPO, exiting..." 'Red' - New-Item -Path "$WorkingDir\logs\error.txt" -Value "Blacklist doesn't exist in GPO" -Force - Exit 1 - } - $toSkip = $toSkip.Data + else + { + if (Test-Path -Path "$WorkingDir\mods\*.ps1") + { + Write-ToLog 'Mods are up to date.' 'Green' + } + else + { + Write-ToLog 'No Mods are implemented...' 'Yellow' + } } - } - - #Get outdated Winget packages - Write-ToLog 'Checking application updates on Winget Repository...' 'yellow' - $outdated = Get-WingetOutdatedApps - - #If something unusual happened - if ($outdated -like 'An unusual*') { - Write-ToLog "$outdated" 'cyan' - $outdated = $False - } - - #Run only if $outdated is populated! - if ($outdated) { - #Log list of app to update - foreach ($app in $outdated) { - #List available updates - $Log = "-> Available update : $($app.Name). Current version : $($app.Version). Available version : $($app.AvailableVersion)." - $Log | Write-host - $Log | out-file -filepath $LogFile -Append + if ($DeletedMods -gt 0) + { + Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Red' } - - #Count good update installations - $Script:InstallOK = 0 - - #Trick under user context when -BypassListForUsers is used - if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq 1) { - Write-ToLog 'Bypass system list in user context is Enabled.' - $UseWhiteList = $false - $toSkip = $null + } + + #Test if _WAU-mods.ps1 exist: Mods for WAU (if Network is active/any Winget is installed/running as SYSTEM) + $Mods = "$WorkingDir\mods" + if (Test-Path -Path "$Mods\_WAU-mods.ps1") + { + Write-ToLog 'Running Mods for WAU...' 'Yellow' + & "$Mods\_WAU-mods.ps1" + $ModsExitCode = $LASTEXITCODE + #If _WAU-mods.ps1 has ExitCode 1 - Re-run WAU + if ($ModsExitCode -eq 1) + { + Write-ToLog 'Re-run WAU' + Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" + exit } - - #If White List - if ($UseWhiteList) { - #For each app, notify and update - foreach ($app in $outdated) { - if (($toUpdate -contains $app.Id) -and $($app.Version) -ne 'Unknown') { - Update-App $app - } - #if current app version is unknown - elseif ($($app.Version) -eq 'Unknown') { - Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' - } - #if app is in "excluded list" - else { - Write-ToLog "$($app.Name) : Skipped upgrade because it is not in the included app list" 'Gray' - } - } + } + + } + + if ($($WAUConfig.WAU_ListPath) -eq 'GPO') + { + $Script:GPOList = $True + } + + #Get White or Black list + if ($WAUConfig.WAU_UseWhiteList -eq 1) + { + Write-ToLog 'WAU uses White List config' + $toUpdate = Get-IncludedApps + $UseWhiteList = $true + } + else + { + Write-ToLog 'WAU uses Black List config' + $toSkip = Get-ExcludedApps + } + + #Fix and count the array if GPO List as ERROR handling! + if ($GPOList) + { + if ($UseWhiteList) + { + $WhiteList = $toUpdate.GetUpperBound(0) + if ($null -eq $WhiteList) + { + Write-ToLog "Critical: Whitelist doesn't exist in GPO, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force + exit 1 } - #If Black List or default - else { - #For each app, notify and update - foreach ($app in $outdated) { - if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne 'Unknown') { - Update-App $app - } - #if current app version is unknown - elseif ($($app.Version) -eq 'Unknown') { - Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' - } - #if app is in "excluded list" - else { - Write-ToLog "$($app.Name) : Skipped upgrade because it is in the excluded app list" 'Gray' - } - } + $toUpdate = $toUpdate.Data + } + else + { + $BlackList = $toSkip.GetUpperBound(0) + if ($null -eq $BlackList) + { + Write-ToLog "Critical: Blacklist doesn't exist in GPO, exiting..." 'Red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value "Blacklist doesn't exist in GPO" -Force + exit 1 } - - if ($InstallOK -gt 0) { - Write-ToLog "$InstallOK apps updated ! No more update." 'Green' + $toSkip = $toSkip.Data + } + } + + #Get outdated Winget packages + Write-ToLog 'Checking application updates on Winget Repository...' 'yellow' + $outdated = Get-WingetOutdatedApps + + #If something unusual happened + if ($outdated -like 'An unusual*') + { + Write-ToLog "$outdated" 'cyan' + $outdated = $False + } + + #Run only if $outdated is populated! + if ($outdated) + { + #Log list of app to update + foreach ($app in $outdated) + { + #List available updates + $Log = "-> Available update : $($app.Name). Current version : $($app.Version). Available version : $($app.AvailableVersion)." + $Log | Write-host + $Log | out-file -filepath $LogFile -Append + } + + #Count good update installations + $Script:InstallOK = 0 + + #Trick under user context when -BypassListForUsers is used + if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq 1) + { + Write-ToLog 'Bypass system list in user context is Enabled.' + $UseWhiteList = $false + $toSkip = $null + } + + #If White List + if ($UseWhiteList) + { + #For each app, notify and update + foreach ($app in $outdated) + { + if (($toUpdate -contains $app.Id) -and $($app.Version) -ne 'Unknown') + { + Update-App $app + } + #if current app version is unknown + elseif ($($app.Version) -eq 'Unknown') + { + Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' + } + #if app is in "excluded list" + else + { + Write-ToLog "$($app.Name) : Skipped upgrade because it is not in the included app list" 'Gray' + } } - } - - if ($InstallOK -eq 0 -or !$InstallOK) { - Write-ToLog 'No new update.' 'Green' - } - - #Check if any user is logged on if System and run User task (if installed) - if ($IsSystem) { - #User check routine from: https://stackoverflow.com/questions/23219718/powershell-script-to-see-currently-logged-in-users-domain-and-machine-status - $explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue) - If ($explorerprocesses.Count -eq 0) { - Write-ToLog 'No explorer process found / Nobody interactively logged on...' + } + #If Black List or default + else + { + #For each app, notify and update + foreach ($app in $outdated) + { + if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne 'Unknown') + { + Update-App $app + } + #if current app version is unknown + elseif ($($app.Version) -eq 'Unknown') + { + Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" 'Gray' + } + #if app is in "excluded list" + else + { + Write-ToLog "$($app.Name) : Skipped upgrade because it is in the excluded app list" 'Gray' + } } - Else { - #Run WAU in user context if the user task exist - $UserScheduledTask = Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue - if ($UserScheduledTask) { - - #Get Winget system apps to excape them befor running user context - Write-ToLog 'User logged on, get a list of installed Winget apps in System context...' - Get-WingetSystemApps - - #Run user context scheduled task - Write-ToLog 'Starting WAU in User context' - Start-ScheduledTask -TaskName $UserScheduledTask.TaskName -ErrorAction SilentlyContinue - Exit 0 - } - elseif (!$UserScheduledTask) { - Write-ToLog 'User context execution not installed...' - } + } + + if ($InstallOK -gt 0) + { + Write-ToLog "$InstallOK apps updated ! No more update." 'Green' + } + } + + if ($InstallOK -eq 0 -or !$InstallOK) + { + Write-ToLog 'No new update.' 'Green' + } + + #Check if any user is logged on if System and run User task (if installed) + if ($IsSystem) + { + #User check routine from: https://stackoverflow.com/questions/23219718/powershell-script-to-see-currently-logged-in-users-domain-and-machine-status + $explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue) + if ($explorerprocesses.Count -eq 0) + { + Write-ToLog 'No explorer process found / Nobody interactively logged on...' + } + else + { + #Run WAU in user context if the user task exist + $UserScheduledTask = Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue + if ($UserScheduledTask) + { + + #Get Winget system apps to excape them befor running user context + Write-ToLog 'User logged on, get a list of installed Winget apps in System context...' + Get-WingetSystemApps + + #Run user context scheduled task + Write-ToLog 'Starting WAU in User context' + Start-ScheduledTask -TaskName $UserScheduledTask.TaskName -ErrorAction SilentlyContinue + exit 0 } - } - } - else { - Write-ToLog 'Critical: Winget not installed or detected, exiting...' 'red' - New-Item -Path "$WorkingDir\logs\error.txt" -Value 'Winget not installed or detected' -Force - Write-ToLog 'End of process!' 'Cyan' - Exit 1 - } + elseif (!$UserScheduledTask) + { + Write-ToLog 'User context execution not installed...' + } + } + } + } + else + { + Write-ToLog 'Critical: Winget not installed or detected, exiting...' 'red' + New-Item -Path "$WorkingDir\logs\error.txt" -Value 'Winget not installed or detected' -Force + Write-ToLog 'End of process!' 'Cyan' + exit 1 + } } #End diff --git a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 index 5ff4832..631c7c2 100644 --- a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 +++ b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 @@ -1,38 +1,40 @@ # Function to configure the prefered scope option as Machine -function Add-ScopeMachine +function Add-ScopeMachine { [CmdletBinding()] param ( - [string]$SettingsPath + [string] + $SettingsPath ) - if (Test-Path -Path $SettingsPath -ErrorAction SilentlyContinue) + if (Test-Path -Path $SettingsPath -ErrorAction SilentlyContinue) { $ConfigFile = (Get-Content -Path $SettingsPath -ErrorAction SilentlyContinue | Where-Object -FilterScript { ($_ -notmatch '//') - } | ConvertFrom-Json) + } | ConvertFrom-Json) } - - if (!$ConfigFile) + + if (!$ConfigFile) { - $ConfigFile = @{} + $ConfigFile = @{ + } } - - if ($ConfigFile.installBehavior.preferences.scope) + + if ($ConfigFile.installBehavior.preferences.scope) { $ConfigFile.installBehavior.preferences.scope = 'Machine' } - else + else { $Scope = (New-Object -TypeName PSObject -Property $(@{ scope = 'Machine' - })) + })) $Preference = (New-Object -TypeName PSObject -Property $(@{ preferences = $Scope - })) + })) $null = (Add-Member -InputObject $ConfigFile -MemberType NoteProperty -Name 'installBehavior' -Value $Preference -Force) } - + $null = ($ConfigFile | ConvertTo-Json | Out-File -FilePath $SettingsPath -Encoding utf8 -Force -Confirm:$false) } diff --git a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 index e050281..75d70c7 100644 --- a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 +++ b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 @@ -1,16 +1,21 @@ # Function to create shortcuts -function Add-Shortcut -{ +function Add-Shortcut +{ [CmdletBinding()] param ( - [string]$Target, - [string]$Shortcut, - [string]$Arguments, - [string]$Icon, - [string]$Description + [string] + $Target, + [string] + $Shortcut, + [string] + $Arguments, + [string] + $Icon, + [string] + $Description ) - + $WScriptShell = (New-Object -ComObject WScript.Shell) $Shortcut = $WScriptShell.CreateShortcut($Shortcut) $Shortcut.TargetPath = $Target diff --git a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 index c676e26..7dba44b 100644 --- a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 +++ b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 @@ -1,33 +1,35 @@ -Function Confirm-Installation +function Confirm-Installation { # Set json export file [CmdletBinding()] param ( - [string]$AppName, - [string]$AppVer + [string] + $AppName, + [string] + $AppVer ) - + $JsonFile = ('{0}\Config\InstalledApps.json' -f $WorkingDir) - + # Get installed apps and version in json file $null = (& $Winget export -s winget -o $JsonFile --include-versions) - + # Get json content $Json = (Get-Content -Path $JsonFile -Raw | ConvertFrom-Json) - + # Get apps and version in hashtable $Packages = $Json.Sources.Packages - + # Remove json file $null = (Remove-Item -Path $JsonFile -Force -Confirm:$false -ErrorAction SilentlyContinue) - + # Search for specific app and version $Apps = $Packages | Where-Object -FilterScript { ($_.PackageIdentifier -eq $AppName -and $_.Version -like ('{0}*' -f $AppVer)) } - + if ($Apps) { return $true diff --git a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 index b8da39a..1e52207 100644 --- a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 +++ b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 @@ -1,58 +1,59 @@ # Function to get AZCopy, if it doesn't exist and update it, if it does -Function Get-AZCopy +function Get-AZCopy { [CmdletBinding()] param ( - [string]$WingetUpdatePath + [string] + $WingetUpdatePath ) - + $AZCopyLink = (Invoke-WebRequest -Uri https://aka.ms/downloadazcopy-v10-windows -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue).headers.location $AZCopyVersionRegex = [regex]::new('(\d+\.\d+\.\d+)') $AZCopyLatestVersion = $AZCopyVersionRegex.Match($AZCopyLink).Value - - if ($null -eq $AZCopyLatestVersion -or '' -eq $AZCopyLatestVersion) + + if ($null -eq $AZCopyLatestVersion -or '' -eq $AZCopyLatestVersion) { $AZCopyLatestVersion = '0.0.0' } - - if (Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf -ErrorAction SilentlyContinue) { $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value - Write-ToLog -LogMsg ('AZCopy version {0} found' -f $AZCopyCurrentVersion) + Write-ToLog -LogMsg ('AZCopy version {0} found' -f $AZCopyCurrentVersion) } - else + else { - Write-ToLog -LogMsg 'AZCopy not already installed' + Write-ToLog -LogMsg 'AZCopy not already installed' $AZCopyCurrentVersion = '0.0.0' } - - if (([version] $AZCopyCurrentVersion) -lt ([version] $AZCopyLatestVersion)) + + if (([version]$AZCopyCurrentVersion) -lt ([version]$AZCopyLatestVersion)) { - Write-ToLog -LogMsg ('Installing version {0} of AZCopy' -f $AZCopyLatestVersion) + Write-ToLog -LogMsg ('Installing version {0} of AZCopy' -f $AZCopyLatestVersion) $null = (Invoke-WebRequest -Uri $AZCopyLink -UseBasicParsing -OutFile ('{0}\azcopyv10.zip' -f $WingetUpdatePath)) - Write-ToLog -LogMsg 'Extracting AZCopy zip file' + Write-ToLog -LogMsg 'Extracting AZCopy zip file' $null = (Expand-Archive -Path ('{0}\azcopyv10.zip' -f $WingetUpdatePath) -DestinationPath $WingetUpdatePath -Force -Confirm:$false) $AZCopyPathSearch = (Resolve-Path -Path ('{0}\azcopy_*' -f $WingetUpdatePath)) - - if ($AZCopyPathSearch -is [array]) + + if ($AZCopyPathSearch -is [array]) { $AZCopyEXEPath = $AZCopyPathSearch[$AZCopyPathSearch.Length - 1] } - else + else { $AZCopyEXEPath = $AZCopyPathSearch } - - Write-ToLog -LogMsg "Copying 'azcopy.exe' to main folder" + + Write-ToLog -LogMsg "Copying 'azcopy.exe' to main folder" $null = (Copy-Item -Path ('{0}\azcopy.exe' -f $AZCopyEXEPath) -Destination ('{0}\' -f $WingetUpdatePath) -Force -Confirm:$false) - Write-ToLog -LogMsg 'Removing temporary AZCopy files' + Write-ToLog -LogMsg 'Removing temporary AZCopy files' $null = (Remove-Item -Path $AZCopyEXEPath -Recurse -Force -Confirm:$false) $null = (Remove-Item -Path ('{0}\azcopyv10.zip' -f $WingetUpdatePath) -Force -Confirm:$false) $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v $AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value - Write-ToLog -LogMsg ('AZCopy version {0} installed' -f $AZCopyCurrentVersion) + Write-ToLog -LogMsg ('AZCopy version {0} installed' -f $AZCopyCurrentVersion) } } diff --git a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 index e6b32fd..5038504 100644 --- a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 +++ b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 @@ -1,18 +1,19 @@ # Get the winget App Information -Function Get-AppInfo +function Get-AppInfo { # Get AppID Info [CmdletBinding()] param ( - [string]$AppID + [string] + $AppID ) - + $String = (& $winget show $AppID --accept-source-agreements -s winget | Out-String) # Search for Release Note info $ReleaseNote = [regex]::match($String, '(?<=Release Notes Url: )(.*)(?=\n)').Groups[0].Value - + # Return Release Note return $ReleaseNote } diff --git a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 index 63f42b8..da1d326 100644 --- a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 @@ -1,16 +1,16 @@ #Function to get the Block List apps -function Get-ExcludedApps +function Get-ExcludedApps { - if ($GPOList) + if ($GPOList) { - if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList' -ErrorAction SilentlyContinue) + if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList' -ErrorAction SilentlyContinue) { $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList\' - + $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList').Property - - foreach ($ValueName in $ValueNames) + + foreach ($ValueName in $ValueNames) { $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) [PSCustomObject]@{ @@ -19,13 +19,13 @@ function Get-ExcludedApps } } } - + return $AppIDs } - elseif (Test-Path -Path ('{0}\excluded_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + elseif (Test-Path -Path ('{0}\excluded_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) { return (Get-Content -Path ('{0}\excluded_apps.txt' -f $WorkingDir)).Trim() | Where-Object -FilterScript { - $_.length -gt 0 + $_.length -gt 0 } } } diff --git a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 index 09e9d79..b5d2c7f 100644 --- a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 @@ -1,15 +1,15 @@ # Function to get the allow List apps -function Get-IncludedApps +function Get-IncludedApps { - if ($GPOList) + if ($GPOList) { - if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList' -ErrorAction SilentlyContinue) + if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList' -ErrorAction SilentlyContinue) { $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList\' $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList').Property - - foreach ($ValueName in $ValueNames) + + foreach ($ValueName in $ValueNames) { $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) [PSCustomObject]@{ @@ -18,13 +18,13 @@ function Get-IncludedApps } } } - + return $AppIDs } - elseif (Test-Path -Path ('{0}\included_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) + elseif (Test-Path -Path ('{0}\included_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) { return (Get-Content -Path ('{0}\included_apps.txt' -f $WorkingDir)).Trim() | Where-Object -FilterScript { - $_.length -gt 0 + $_.length -gt 0 } } } diff --git a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 index 63254bd..4704a9e 100644 --- a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 +++ b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 @@ -1,28 +1,31 @@ #Function to get the locale file for notifications -Function Get-NotifLocale { - - # Get OS locale - $OSLocale = (Get-UICulture).Parent - - # Test if OS locale notif file exists - $TestOSLocalPath = ('{0}\locale\{1}.xml' -f $WorkingDir, $OSLocale.Name) - - # Set OS Local if file exists - if (Test-Path -Path $TestOSLocalPath -ErrorAction SilentlyContinue) { - $LocaleDisplayName = $OSLocale.DisplayName - $LocaleFile = $TestOSLocalPath - } - else { - # Set English if file doesn't exist - $LocaleDisplayName = 'English' - $LocaleFile = ('{0}\locale\en.xml' -f $WorkingDir) - } - - # Get locale XML file content - [xml]$Script:NotifLocale = (Get-Content -Path $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue) - - # Rerturn langague display name - Return $LocaleDisplayName - +function Get-NotifLocale +{ + + # Get OS locale + $OSLocale = (Get-UICulture).Parent + + # Test if OS locale notif file exists + $TestOSLocalPath = ('{0}\locale\{1}.xml' -f $WorkingDir, $OSLocale.Name) + + # Set OS Local if file exists + if (Test-Path -Path $TestOSLocalPath -ErrorAction SilentlyContinue) + { + $LocaleDisplayName = $OSLocale.DisplayName + $LocaleFile = $TestOSLocalPath + } + else + { + # Set English if file doesn't exist + $LocaleDisplayName = 'English' + $LocaleFile = ('{0}\locale\en.xml' -f $WorkingDir) + } + + # Get locale XML file content + [xml]$Script:NotifLocale = (Get-Content -Path $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue) + + # Rerturn langague display name + return $LocaleDisplayName + } diff --git a/Winget-AutoUpdate/functions/Get-Policies.ps1 b/Winget-AutoUpdate/functions/Get-Policies.ps1 index ab71cd1..98eb539 100644 --- a/Winget-AutoUpdate/functions/Get-Policies.ps1 +++ b/Winget-AutoUpdate/functions/Get-Policies.ps1 @@ -1,116 +1,116 @@ # Function to get the Domain/Local Policies (GPO) -Function Get-Policies +function Get-Policies { # Get WAU Policies and set the Configurations Registry Accordingly $WAUPolicies = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate' -ErrorAction SilentlyContinue) - - if ($WAUPolicies) + + if ($WAUPolicies) { - if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) + if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) { $ChangedSettings = 0 $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' - - if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) + + if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) { $null = (New-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Value $($WAUPolicies.WAU_BypassListForUsers) -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUConfig.WAU_BypassListForUsers) -or $($WAUConfig.WAU_BypassListForUsers) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUConfig.WAU_BypassListForUsers) -or $($WAUConfig.WAU_BypassListForUsers) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) + + if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUConfig.WAU_DisableAutoUpdate) -or $($WAUConfig.WAU_DisableAutoUpdate) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUConfig.WAU_DisableAutoUpdate) -or $($WAUConfig.WAU_DisableAutoUpdate) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) + + if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_DoNotRunOnMetered) -and !$($WAUConfig.WAU_DoNotRunOnMetered)) + elseif ($null -eq $($WAUPolicies.WAU_DoNotRunOnMetered) -and !$($WAUConfig.WAU_DoNotRunOnMetered)) { $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) + + if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) + elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) + + if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUConfig.WAU_UseWhiteList) -or $($WAUConfig.WAU_UseWhiteList) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUConfig.WAU_UseWhiteList) -or $($WAUConfig.WAU_UseWhiteList) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) + + if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) { $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) + elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) + + if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) { $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_ModsPath) -and $($WAUConfig.WAU_ModsPath)) + elseif ($null -eq $($WAUPolicies.WAU_ModsPath) -and $($WAUConfig.WAU_ModsPath)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - if ($null -ne $($WAUPolicies.WAU_AzureBlobSASURL) -and ($($WAUPolicies.WAU_AzureBlobSASURL) -ne $($WAUConfig.WAU_AzureBlobSASURL))) + if ($null -ne $($WAUPolicies.WAU_AzureBlobSASURL) -and ($($WAUPolicies.WAU_AzureBlobSASURL) -ne $($WAUConfig.WAU_AzureBlobSASURL))) { $null = (New-ItemProperty -Path $regPath -Name WAU_AzureBlobSASURL -Value $($WAUPolicies.WAU_AzureBlobSASURL.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_AzureBlobSASURL) -and $($WAUConfig.WAU_AzureBlobSASURL)) + elseif ($null -eq $($WAUPolicies.WAU_AzureBlobSASURL) -and $($WAUConfig.WAU_AzureBlobSASURL)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_AzureBlobSASURL -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) + + if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) { $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne 'Full') + elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne 'Full') { $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value 'Full' -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) + + if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $($WAUPolicies.WAU_UpdatesAtTime) -Force -Confirm:$false) $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') @@ -119,10 +119,10 @@ Function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) { $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) @@ -134,7 +134,7 @@ Function Get-Policies $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtTime) -and $($WAUConfig.WAU_UpdatesAtTime) -ne '06:00:00') + elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtTime) -and $($WAUConfig.WAU_UpdatesAtTime) -ne '06:00:00') { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value '06:00:00' -Force -Confirm:$false) $Script:WAUConfig = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' @@ -143,10 +143,10 @@ Function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) { $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11) $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6) @@ -155,12 +155,12 @@ Function Get-Policies break } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) + + if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesInterval -Value $($WAUPolicies.WAU_UpdatesInterval) -Force -Confirm:$false) $service = (New-Object -ComObject Schedule.Service) @@ -168,26 +168,26 @@ Function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) { $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) $definition.Triggers.Remove($triggerId) $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) - - if (!$($WAUConfig.WAU_UpdatesAtTime)) + + if (!$($WAUConfig.WAU_UpdatesAtTime)) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - - if ($($WAUPolicies.WAU_UpdatesInterval) -ne 'Never') + + if ($($WAUPolicies.WAU_UpdatesInterval) -ne 'Never') { #Count Triggers (correctly) $service = (New-Object -ComObject Schedule.Service) @@ -196,48 +196,49 @@ Function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $null = $definition.Triggers.Count - switch ($($WAUPolicies.WAU_UpdatesInterval)) { - 'Daily' + switch ($($WAUPolicies.WAU_UpdatesInterval)) + { + 'Daily' { $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) break } - 'BiDaily' + 'BiDaily' { $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) -DaysInterval 2 break } - 'Weekly' + 'Weekly' { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 break } - 'BiWeekly' + 'BiWeekly' { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 2 break } - 'Monthly' + 'Monthly' { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 4 break } } - if ($definition.Triggers.Count -gt 0) + if ($definition.Triggers.Count -gt 0) { $triggers = @() $triggers += (Get-ScheduledTask -TaskName 'Winget-AutoUpdate').Triggers $triggers += $tasktrigger $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) } - else + else { $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $tasktrigger) } } $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesInterval) -and $($WAUConfig.WAU_UpdatesInterval) -ne 'Daily') + elseif ($null -eq $($WAUPolicies.WAU_UpdatesInterval) -and $($WAUConfig.WAU_UpdatesInterval) -ne 'Daily') { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesInterval -Value 'Daily' -Force -Confirm:$false) $service = (New-Object -ComObject Schedule.Service) @@ -245,27 +246,27 @@ Function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) + if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) { $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8) $definition.Triggers.Remove($triggerId) $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) - - if (!$($WAUConfig.WAU_UpdatesAtTime)) + + if (!$($WAUConfig.WAU_UpdatesAtTime)) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - + $tasktrigger = (New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime)) - + # Count Triggers (correctly) $service = (New-Object -ComObject Schedule.Service) $service.Connect($env:COMPUTERNAME) @@ -273,24 +274,24 @@ Function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $null = $definition.Triggers.Count - - if ($definition.Triggers.Count -gt 0) + + if ($definition.Triggers.Count -gt 0) { $triggers = @() $triggers += (Get-ScheduledTask -TaskName 'Winget-AutoUpdate').Triggers $triggers += $tasktrigger $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) } - else + else { $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $tasktrigger) } $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) + + if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) { - if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) + if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force -Confirm:$false) $triggers = @() @@ -302,22 +303,22 @@ Function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $triggerLogon = $false - - foreach ($trigger in $definition.Triggers) + + foreach ($trigger in $definition.Triggers) { - if ($trigger.Type -eq '9') + if ($trigger.Type -eq '9') { $triggerLogon = $true break } } - if (!$triggerLogon) + if (!$triggerLogon) { $triggers += New-ScheduledTaskTrigger -AtLogOn $null = (Set-ScheduledTask -TaskName 'Winget-AutoUpdate' -Trigger $triggers) } } - else + else { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force -Confirm:$false) $service = (New-Object -ComObject Schedule.Service) @@ -326,22 +327,22 @@ Function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $null = $definition.Triggers.Count - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if ($definition.Triggers.Item($triggerId).Type -eq '9') + if ($definition.Triggers.Item($triggerId).Type -eq '9') { $definition.Triggers.Remove($triggerId) $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) } - + $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_UpdatesAtLogon -Force -ErrorAction SilentlyContinue -Confirm:$false) $service = (New-Object -ComObject Schedule.Service) @@ -349,25 +350,25 @@ Function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - - for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) + + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { - if ($definition.Triggers.Item($triggerId).Type -eq '9') + if ($definition.Triggers.Item($triggerId).Type -eq '9') { $definition.Triggers.Remove($triggerId) $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) + + if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UserContext -Value $($WAUPolicies.WAU_UserContext) -PropertyType DWord -Force -Confirm:$false) - - if ($WAUPolicies.WAU_UserContext -eq 1) + + if ($WAUPolicies.WAU_UserContext -eq 1) { # Settings for the scheduled task in User context $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\winget-upgrade.ps1`"`"" @@ -377,94 +378,94 @@ Function Get-Policies $task = (New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings) $null = (Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force) } - else + else { $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) } $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_UserContext) -and ($($WAUConfig.WAU_UserContext) -or $($WAUConfig.WAU_UserContext) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_UserContext) -and ($($WAUConfig.WAU_UserContext) -or $($WAUConfig.WAU_UserContext) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_UserContext -Force -ErrorAction SilentlyContinue -Confirm:$false) $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) + + if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DesktopShortcut -Value $($WAUPolicies.WAU_DesktopShortcut) -PropertyType DWord -Force -Confirm:$false) - - if ($WAUPolicies.WAU_DesktopShortcut -eq 1) + + if ($WAUPolicies.WAU_DesktopShortcut -eq 1) { Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' } - else + else { $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) } $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUConfig.WAU_DesktopShortcut) -or $($WAUConfig.WAU_DesktopShortcut) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUConfig.WAU_DesktopShortcut) -or $($WAUConfig.WAU_DesktopShortcut) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_DesktopShortcut -Force -Confirm:$false -ErrorAction SilentlyContinue) $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) + + if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) { $null = (New-ItemProperty -Path $regPath -Name WAU_StartMenuShortcut -Value $($WAUPolicies.WAU_StartMenuShortcut) -PropertyType DWord -Force -Confirm:$false) - - if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) + + if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) { - if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) + if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = (New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Confirm:$false) } - + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' } - else + else { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) } $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUConfig.WAU_StartMenuShortcut) -or $($WAUConfig.WAU_StartMenuShortcut) -eq 0)) + elseif ($null -eq $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUConfig.WAU_StartMenuShortcut) -or $($WAUConfig.WAU_StartMenuShortcut) -eq 0)) { $null = (Remove-ItemProperty -Path $regPath -Name WAU_StartMenuShortcut -Force -ErrorAction SilentlyContinue -Confirm:$false) $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) + + if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value $($WAUPolicies.WAU_MaxLogFiles.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_MaxLogFiles) -and $($WAUConfig.WAU_MaxLogFiles) -ne 3) + elseif ($null -eq $($WAUPolicies.WAU_MaxLogFiles) -and $($WAUConfig.WAU_MaxLogFiles) -ne 3) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -Force -Confirm:$false) $ChangedSettings++ } - - if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) + + if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value $($WAUPolicies.WAU_MaxLogSize.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) $ChangedSettings++ } - elseif ($null -eq $($WAUPolicies.WAU_MaxLogSize) -and $($WAUConfig.WAU_MaxLogSize) -ne 1048576) + elseif ($null -eq $($WAUPolicies.WAU_MaxLogSize) -and $($WAUConfig.WAU_MaxLogSize) -ne 1048576) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -Force -Confirm:$false) $ChangedSettings++ } - + # Get WAU Configurations after Policies change $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } } - - Return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings + + return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings } diff --git a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 index 5bb5091..99e40d4 100644 --- a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 +++ b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 @@ -1,22 +1,22 @@ # Function to get the latest WAU available version on Github -function Get-WAUAvailableVersion +function Get-WAUAvailableVersion { # Get Github latest version - if ($WAUConfig.WAU_UpdatePrerelease -eq 1) + if ($WAUConfig.WAU_UpdatePrerelease -eq 1) { # Log Write-ToLog -LogMsg 'WAU AutoUpdate Pre-release versions is Enabled' -LogColor 'Cyan' - + # Get latest pre-release info $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases' } - else + else { # Get latest stable info $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases/latest' } - + # Return version return ((Invoke-WebRequest -Uri $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace('v', '') } diff --git a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 index eec9904..72bd927 100644 --- a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 @@ -1,43 +1,53 @@ # Function to get the winget command regarding execution context (User, System...) -Function Get-WingetCmd { - - # Get WinGet Path (if Admin context) - # Includes Workaround for ARM64 (removed X64 and replaces it with a wildcard) - $ResolveWingetPath = (Resolve-Path -Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe" | Sort-Object -Property { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') }) - - if ($ResolveWingetPath) { - # If multiple version, pick last one - $WingetPath = $ResolveWingetPath[-1].Path - } - - #If running under System or Admin context obtain Winget from Program Files - if((([Security.Principal.WindowsIdentity]::GetCurrent().User) -eq 'S-1-5-18') -or ($WingetPath)){ - if (Test-Path -Path ('{0}\winget.exe' -f $WingetPath) -ErrorAction SilentlyContinue) { - $Script:Winget = ('{0}\winget.exe' -f $WingetPath) - } - }else{ - #Get Winget Location in User context - $WingetCmd = (Get-Command -Name winget.exe -ErrorAction SilentlyContinue) - - if ($WingetCmd) { - $Script:Winget = $WingetCmd.Source - } - } - - If(!($Script:Winget)){ - Write-ToLog 'Winget not installed or detected !' 'Red' - - return $false - } - - # Run winget to list apps and accept source agrements (necessary on first run) - $null = (& $Winget list --accept-source-agreements -s winget) - - # Log Winget installed version - $WingetVer = & $Winget --version - Write-ToLog ('Winget Version: {0}' -f $WingetVer) - - return $true - +function Get-WingetCmd +{ + + # Get WinGet Path (if Admin context) + # Includes Workaround for ARM64 (removed X64 and replaces it with a wildcard) + $ResolveWingetPath = (Resolve-Path -Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe" | Sort-Object -Property { + [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') + }) + + if ($ResolveWingetPath) + { + # If multiple version, pick last one + $WingetPath = $ResolveWingetPath[-1].Path + } + + #If running under System or Admin context obtain Winget from Program Files + if ((([Security.Principal.WindowsIdentity]::GetCurrent().User) -eq 'S-1-5-18') -or ($WingetPath)) + { + if (Test-Path -Path ('{0}\winget.exe' -f $WingetPath) -ErrorAction SilentlyContinue) + { + $Script:Winget = ('{0}\winget.exe' -f $WingetPath) + } + } + else + { + #Get Winget Location in User context + $WingetCmd = (Get-Command -Name winget.exe -ErrorAction SilentlyContinue) + + if ($WingetCmd) + { + $Script:Winget = $WingetCmd.Source + } + } + + if (!($Script:Winget)) + { + Write-ToLog 'Winget not installed or detected !' 'Red' + + return $false + } + + # Run winget to list apps and accept source agrements (necessary on first run) + $null = (& $Winget list --accept-source-agreements -s winget) + + # Log Winget installed version + $WingetVer = & $Winget --version + Write-ToLog ('Winget Version: {0}' -f $WingetVer) + + return $true + } diff --git a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 index 62242b0..ec52979 100644 --- a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 @@ -1,6 +1,6 @@ # Function to get the outdated app list, in formatted array -function Get-WingetOutdatedApps +function Get-WingetOutdatedApps { class Software { [string]$Name @@ -8,62 +8,62 @@ function Get-WingetOutdatedApps [string]$Version [string]$AvailableVersion } - + # Get list of available upgrades on winget format $upgradeResult = (& $Winget upgrade --source winget | Out-String) - + # Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) - if (!($upgradeResult -match '-----')) + if (!($upgradeResult -match '-----')) { return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult" } - + # Split winget output to lines $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object -FilterScript { - $_ + $_ } - + # Find the line that starts with "------" $fl = 0 - while (-not $lines[$fl].StartsWith('-----')) + while (-not $lines[$fl].StartsWith('-----')) { $fl++ } - + # Get header line $fl = $fl - 1 - + # Get header titles [without remove seperator] $index = $lines[$fl] -split '(?<=\s)(?!\s)' - + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length - + # Now cycle in real package and split accordingly $upgradeList = @() - - For ($i = $fl + 2; $i -lt $lines.Length; $i++) + + for ($i = $fl + 2; $i -lt $lines.Length; $i++) { $line = $lines[$i] -replace '[\u2026]', ' ' #Fix "..." in long names - - if ($line.StartsWith('-----')) + + if ($line.StartsWith('-----')) { # Get header line $fl = $i - 1 - + # Get header titles [without remove seperator] $index = $lines[$fl] -split '(?<=\s)(?!\s)' - + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length } - + # (Alphanumeric | Literal . | Alphanumeric) - the only unique thing in common for lines with applications - if ($line -match '\w\.\w') + if ($line -match '\w\.\w') { $software = [Software]::new() # Manage non latin characters @@ -76,17 +76,17 @@ function Get-WingetOutdatedApps $upgradeList += $software } } - + # If current user is not system, remove system apps from list - if ($IsSystem -eq $false) + if ($IsSystem -eq $false) { $SystemApps = Get-Content -Path ('{0}\winget_system_apps.txt' -f $WorkingDir) $upgradeList = $upgradeList | Where-Object -FilterScript { - $SystemApps -notcontains $_.Id + $SystemApps -notcontains $_.Id } } - + return $upgradeList | Sort-Object -Property { - Get-Random + Get-Random } } diff --git a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 index 0d1bedf..0692984 100644 --- a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 @@ -1,17 +1,17 @@ -function Get-WingetSystemApps +function Get-WingetSystemApps { # Json File, where to export system installed apps $jsonFile = ('{0}\winget_system_apps.txt' -f $WorkingDir) - + # Get list of installed Winget apps to json file $null = (& $Winget export -o $jsonFile --accept-source-agreements -s winget) - + # Convert json file to txt file with app ids $InstalledApps = (Get-Content -Path $jsonFile | ConvertFrom-Json) - + # Save app list $null = (Set-Content -Value $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Sort app list $null = (Get-Content -Path $jsonFile | Sort-Object | Set-Content -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) } diff --git a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 index 86c40b7..ebc46c1 100644 --- a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 @@ -1,6 +1,6 @@ # Function to rotate the logs -function Invoke-LogRotation +function Invoke-LogRotation { <# .SYNOPSIS @@ -12,38 +12,41 @@ function Invoke-LogRotation URL: https://www.powershellgallery.com/packages/Communary.Logger/1.1 Date: 21.11.2014 Version: 1.0 - #> + #> param ( - [string]$LogFile, - [int]$MaxLogFiles, - [int]$MaxLogSize + [string] + $LogFile, + [int] + $MaxLogFiles, + [int] + $MaxLogSize ) - try + try { # get current size of log file $currentSize = (Get-Item -Path $LogFile).Length - + # get log name $logFileName = (Split-Path -Path $LogFile -Leaf) $logFilePath = (Split-Path -Path $LogFile) $logFileNameWithoutExtension = [IO.Path]::GetFileNameWithoutExtension($logFileName) $logFileNameExtension = [IO.Path]::GetExtension($logFileName) - + # if MaxLogFiles is 1 just keep the original one and let it grow - if (-not($MaxLogFiles -eq 1)) + if (-not ($MaxLogFiles -eq 1)) { - if ($currentSize -ge $MaxLogSize) + if ($currentSize -ge $MaxLogSize) { # construct name of archived log file $newLogFileName = $logFileNameWithoutExtension + (Get-Date -Format 'yyyyMMddHHmmss').ToString() + $logFileNameExtension - + # copy old log file to new using the archived name constructed above $null = (Copy-Item -Path $LogFile -Destination (Join-Path -Path (Split-Path -Path $LogFile) -ChildPath $newLogFileName)) - + # Create a new log file - try + try { $null = (Remove-Item -Path $LogFile -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-Item -ItemType File -Path $LogFile -Force -Confirm:$False -ErrorAction SilentlyContinue) @@ -57,59 +60,59 @@ function Invoke-LogRotation $NewAcl.SetAccessRule($fileSystemAccessRule) $null = (Set-Acl -Path $LogFile -AclObject $NewAcl) } - catch + catch { - Return $False + return $False } - + # if MaxLogFiles is 0 don't delete any old archived log files - if (-not($MaxLogFiles -eq 0)) + if (-not ($MaxLogFiles -eq 0)) { # set filter to search for archived log files $archivedLogFileFilter = $logFileNameWithoutExtension + '??????????????' + $logFileNameExtension - + # get archived log files $oldLogFiles = (Get-Item -Path "$(Join-Path -Path $logFilePath -ChildPath $archivedLogFileFilter)") - - if ([bool]$oldLogFiles) + + if ([bool]$oldLogFiles) { # compare found log files to MaxLogFiles parameter of the log object, and delete oldest until we are # back to the correct number - if (($oldLogFiles.Count + 1) -gt $MaxLogFiles) + if (($oldLogFiles.Count + 1) -gt $MaxLogFiles) { [int]$numTooMany = (($oldLogFiles.Count) + 1) - $MaxLogFiles - $null = ($oldLogFiles | Sort-Object -Property 'LastWriteTime' | Select-Object -First $numTooMany | Remove-Item -Force -Confirm:$False -ErrorAction SilentlyContinue) + $null = ($oldLogFiles | Sort-Object -Property 'LastWriteTime' | Select-Object -First $numTooMany | Remove-Item -Force -Confirm:$False -ErrorAction SilentlyContinue) } } } - + # Log Header $Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-Culture).DateTimeFormat.ShortDatePattern)`n##################################################" $null = ($Log | Out-File -FilePath $LogFile -Append -Force) Write-ToLog -LogMsg 'Running in System context' - - if ($ActivateGPOManagement) + + if ($ActivateGPOManagement) { Write-ToLog -LogMsg 'Activated WAU GPO Management detected, comparing...' - - if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) + + if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { Write-ToLog -LogMsg 'Changed settings detected and applied' -LogColor 'Yellow' } - else + else { Write-ToLog -LogMsg 'No Changed settings detected' -LogColor 'Yellow' } } - + Write-ToLog -LogMsg ('Max Log Size reached: {0} bytes - Rotated Logs' -f $MaxLogSize) - - Return $True + + return $True } } } - catch + catch { - Return $False + return $False } } diff --git a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 index 1d33a33..ec3f270 100644 --- a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 @@ -2,15 +2,16 @@ # Security: Mods directory must be protected (Users could create scripts of their own - then they'll run in System Context)! # Check if Local Users have write rights in Mods directory or not (and take action if necessary): -function Invoke-ModsProtect +function Invoke-ModsProtect { [CmdletBinding()] param ( - [string]$ModsPath + [string] + $ModsPath ) - - try + + try { $directory = (Get-Item -Path $ModsPath -ErrorAction SilentlyContinue) $acl = (Get-Acl -Path $directory.FullName) @@ -21,60 +22,60 @@ function Invoke-ModsProtect $userName = $ntAccount.Value $userRights = [Security.AccessControl.FileSystemRights]'Write' $hasWriteAccess = $False - - foreach ($access in $acl.Access) + + foreach ($access in $acl.Access) { - if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) + if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) { $hasWriteAccess = $True break } } - - if ($hasWriteAccess) + + if ($hasWriteAccess) { # Disable inheritance $acl.SetAccessRuleProtection($True, $True) - + # Remove any existing rules $acl.Access | ForEach-Object -Process { - $acl.RemoveAccessRule($_) + $acl.RemoveAccessRule($_) } - + # SYSTEM Full - S-1-5-18 $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-18')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) # Save the updated ACL $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Administrators Full - S-1-5-32-544 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-544')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Local Users ReadAndExecute - S-1-5-32-545 S-1-5-11 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-545')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Authenticated Users ReadAndExecute - S-1-5-11 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-11')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + return $True } - + return $False } - catch + catch { return 'Error' } diff --git a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 index 558e769..3e1082f 100644 --- a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 @@ -1,47 +1,47 @@ # Function to make actions after WAU update -function Invoke-PostUpdateActions +function Invoke-PostUpdateActions { # log Write-ToLog -LogMsg 'Running Post Update actions:' -LogColor 'yellow' - + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink - if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ErrorAction SilentlyContinue)) + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ErrorAction SilentlyContinue)) { Write-ToLog -LogMsg '-> Creating SymLink for log file in Intune Management Extension log folder' -LogColor 'yellow' $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue } - + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink - if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) { Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + Write-ToLog -LogMsg '-> Checking prerequisites...' -LogColor 'yellow' - + # Check if Visual C++ 2019 or 2022 installed $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' $path = (Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 - }) - + }) + # If not installed, install - if (!($path)) + if (!($path)) { - try + try { - if ((Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -like '*64*') + if ((Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -like '*64*') { $OSArch = 'x64' } - else + else { $OSArch = 'x86' } - + Write-ToLog -LogMsg ('-> Downloading VC_redist.{0}.exe...' -f $OSArch) $SourceURL = ('https://aka.ms/vs/17/release/VC_redist.{0}.exe' -f $OSArch) $Installer = ('{0}\VC_redist.{1}.exe' -f $WAUConfig.InstallLocation, $OSArch) @@ -52,70 +52,70 @@ function Invoke-PostUpdateActions Remove-Item -Path $Installer -ErrorAction Ignore Write-ToLog -LogMsg '-> MS Visual C++ 2015-2022 installed successfully' -LogColor 'green' } - catch + catch { Write-ToLog -LogMsg '-> MS Visual C++ 2015-2022 installation failed.' -LogColor 'red' } } - else + else { Write-ToLog -LogMsg '-> Prerequisites checked. OK' -LogColor 'green' } - + # Check Package Install Write-ToLog -LogMsg '-> Checking if Winget is installed/up to date' -LogColor 'yellow' $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' } - + # Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 - If ([Version]$TestWinGet.Version -ge '2023.808.2243.0') + if ([Version]$TestWinGet.Version -ge '2023.808.2243.0') { Write-ToLog -LogMsg '-> WinGet is Installed/up to date' -LogColor 'green' } - Else + else { # Download WinGet MSIXBundle Write-ToLog -LogMsg '-> Not installed/up to date. Downloading WinGet...' $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($WinGetURL, ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation)) - + # Install WinGet MSIXBundle - try + try { Write-ToLog -LogMsg '-> Installing Winget MSIXBundle for App Installer...' $null = Add-AppxProvisionedPackage -Online -PackagePath ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -SkipLicense Write-ToLog -LogMsg '-> Installed Winget MSIXBundle for App Installer' -LogColor 'green' } - catch + catch { Write-ToLog -LogMsg '-> Failed to intall Winget MSIXBundle for App Installer...' -LogColor 'red' } - + # Remove WinGet MSIXBundle Remove-Item -Path ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -Force -Confirm:$False -ErrorAction Continue } - + # Reset Winget Sources $ResolveWingetPath = Resolve-Path -Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object -Property { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } - - if ($ResolveWingetPath) + + if ($ResolveWingetPath) { # If multiple version, pick last one $WingetPath = $ResolveWingetPath[-1].Path & $WingetPath source reset --force - + # log Write-ToLog -LogMsg '-> Winget sources reseted.' -LogColor 'green' } - + # Create WAU Regkey if not present $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' - - if (!(Test-Path -Path $regPath -ErrorAction SilentlyContinue)) + + if (!(Test-Path -Path $regPath -ErrorAction SilentlyContinue)) { $null = (New-Item -Path $regPath -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name DisplayName -Value 'Winget-AutoUpdate (WAU)' -Force -Confirm:$False -ErrorAction SilentlyContinue) @@ -128,162 +128,162 @@ function Invoke-PostUpdateActions $null = (New-ItemProperty -Path $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - + #log Write-ToLog -LogMsg ('-> {0} created.' -f $regPath) -LogColor 'green' } - + # Fix Notif where WAU_NotificationLevel is not set $regNotif = Get-ItemProperty -Path $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue - - if (!$regNotif) + + if (!$regNotif) { New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value Full -Force - + # log Write-ToLog -LogMsg "-> Notification level setting was missing. Fixed with 'Full' option." } - + # Set WAU_MaxLogFiles/WAU_MaxLogSize if not set $MaxLogFiles = Get-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue - - if (!$MaxLogFiles) + + if (!$MaxLogFiles) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB).' } - + # Set WAU_ListPath if not set $ListPath = Get-ItemProperty -Path $regPath -Name WAU_ListPath -ErrorAction SilentlyContinue - - if (!$ListPath) + + if (!$ListPath) { $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> ListPath setting was missing. Fixed with empty string.' } - + # Set WAU_ModsPath if not set $ModsPath = (Get-ItemProperty -Path $regPath -Name WAU_ModsPath -ErrorAction SilentlyContinue) - - if (!$ModsPath) + + if (!$ModsPath) { $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> ModsPath setting was missing. Fixed with empty string.' } - + # Security check Write-ToLog -LogMsg '-> Checking Mods Directory:' -LogColor 'yellow' $Protected = Invoke-ModsProtect ('{0}\mods' -f $WAUConfig.InstallLocation) - - if ($Protected -eq $True) + + if ($Protected -eq $True) { Write-ToLog -LogMsg '-> The mods directory is now secured!' -LogColor 'green' } - elseif ($Protected -eq $False) + elseif ($Protected -eq $False) { Write-ToLog -LogMsg '-> The mods directory was already secured!' -LogColor 'green' } - else + else { Write-ToLog -LogMsg "-> Error: The mods directory couldn't be verified as secured!" -LogColor 'red' } - + # Convert about.xml if exists (old WAU versions) to reg $WAUAboutPath = ('{0}\config\about.xml' -f $WorkingDir) - - if (Test-Path -Path $WAUAboutPath -ErrorAction SilentlyContinue) + + if (Test-Path -Path $WAUAboutPath -ErrorAction SilentlyContinue) { [xml]$About = Get-Content -Path $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue $null = (New-ItemProperty -Path $regPath -Name DisplayVersion -Value $About.app.version -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Remove file once converted $null = (Remove-Item -Path $WAUAboutPath -Force -Confirm:$False) - + #log Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUAboutPath) -LogColor 'green' } - + # Convert config.xml if exists (previous WAU versions) to reg $WAUConfigPath = ('{0}\config\config.xml' -f $WorkingDir) - - if (Test-Path -Path $WAUConfigPath -ErrorAction SilentlyContinue) + + if (Test-Path -Path $WAUConfigPath -ErrorAction SilentlyContinue) { [xml]$Config = (Get-Content -Path $WAUConfigPath -Encoding UTF8 -ErrorAction SilentlyContinue) - - if ($Config.app.WAUautoupdate -eq 'False') + + if ($Config.app.WAUautoupdate -eq 'False') { $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) } - - if ($Config.app.NotificationLevel) + + if ($Config.app.NotificationLevel) { $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $Config.app.NotificationLevel -Force -Confirm:$False -ErrorAction SilentlyContinue) } - - if ($Config.app.UseWAUWhiteList -eq 'True') + + if ($Config.app.UseWAUWhiteList -eq 'True') { $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) } - - if ($Config.app.WAUprerelease -eq 'True') + + if ($Config.app.WAUprerelease -eq 'True') { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + # Remove file once converted $null = (Remove-Item -Path $WAUConfigPath -Force -Confirm:$False) - + # log Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUConfigPath) -LogColor 'green' } - + # Remove old functions / files $FileNames = @( - ('{0}\functions\Get-WAUConfig.ps1' -f $WorkingDir), - ('{0}\functions\Get-WAUCurrentVersion.ps1' -f $WorkingDir), - ('{0}\functions\Get-WAUUpdateStatus.ps1' -f $WorkingDir), - ('{0}\functions\Write-Log.ps1' -f $WorkingDir), + ('{0}\functions\Get-WAUConfig.ps1' -f $WorkingDir), + ('{0}\functions\Get-WAUCurrentVersion.ps1' -f $WorkingDir), + ('{0}\functions\Get-WAUUpdateStatus.ps1' -f $WorkingDir), + ('{0}\functions\Write-Log.ps1' -f $WorkingDir), ('{0}\Version.txt' -f $WorkingDir) ) - - foreach ($FileName in $FileNames) + + foreach ($FileName in $FileNames) { - if (Test-Path -Path $FileName -ErrorAction SilentlyContinue) + if (Test-Path -Path $FileName -ErrorAction SilentlyContinue) { $null = (Remove-Item -Path $FileName -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg ('-> {0} removed.' -f $FileName) -LogColor 'green' } } - + # Remove old registry key $RegistryKeys = @( - 'VersionMajor', + 'VersionMajor', 'VersionMinor' ) - - foreach ($RegistryKey in $RegistryKeys) + + foreach ($RegistryKey in $RegistryKeys) { - if (Get-ItemProperty -Path $regPath -Name $RegistryKey -ErrorAction SilentlyContinue) + if (Get-ItemProperty -Path $regPath -Name $RegistryKey -ErrorAction SilentlyContinue) { $null = (Remove-ItemProperty -Path $regPath -Name $RegistryKey -Force -Confirm:$False -ErrorAction SilentlyContinue) } } - + # Reset WAU_UpdatePostActions Value $null = ($WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 0 -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Get updated WAU Config $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') - + # log Write-ToLog -LogMsg 'Post Update actions finished' -LogColor 'green' } diff --git a/Winget-AutoUpdate/functions/Start-Init.ps1 b/Winget-AutoUpdate/functions/Start-Init.ps1 index c0e713b..c3fb503 100644 --- a/Winget-AutoUpdate/functions/Start-Init.ps1 +++ b/Winget-AutoUpdate/functions/Start-Init.ps1 @@ -1,15 +1,15 @@ # Initialisation -function Start-Init +function Start-Init { # Config console output encoding [Console]::OutputEncoding = [Text.Encoding]::UTF8 - + # Workaround for ARM64 (Access Denied / Win32 internal Server error) $Script:ProgressPreference = 'SilentlyContinue' $caller = ((Get-ChildItem -Path $MyInvocation.PSCommandPath).Name) - - if ($caller -eq 'Winget-Upgrade.ps1') + + if ($caller -eq 'Winget-Upgrade.ps1') { # Log Header $Log = "`n##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-Culture).DateTimeFormat.ShortDatePattern)`n##################################################" @@ -17,12 +17,12 @@ function Start-Init # Logs initialisation $Script:LogFile = ('{0}\logs\updates.log' -f $WorkingDir) } - elseif ($caller -eq 'Winget-AutoUpdate-Install.ps1') + elseif ($caller -eq 'Winget-AutoUpdate-Install.ps1') { $Script:LogFile = ('{0}\logs\updates.log' -f $WingetUpdatePath) } - - if (!(Test-Path -Path $LogFile -ErrorAction SilentlyContinue)) + + if (!(Test-Path -Path $LogFile -ErrorAction SilentlyContinue)) { # Create file if doesn't exist $null = (New-Item -ItemType File -Path $LogFile -Force -Confirm:$false) @@ -36,7 +36,7 @@ function Start-Init $NewAcl.SetAccessRule($fileSystemAccessRule) Set-Acl -Path $LogFile -AclObject $NewAcl } - elseif ((Test-Path -Path $LogFile -ErrorAction SilentlyContinue) -and ($caller -eq 'Winget-AutoUpdate-Install.ps1')) + elseif ((Test-Path -Path $LogFile -ErrorAction SilentlyContinue) -and ($caller -eq 'Winget-AutoUpdate-Install.ps1')) { #Set ACL for users on logfile $NewAcl = (Get-Acl -Path $LogFile) @@ -48,22 +48,22 @@ function Start-Init $NewAcl.SetAccessRule($fileSystemAccessRule) $null = (Set-Acl -Path $LogFile -AclObject $NewAcl) } - + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink - if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) { Write-Host -Object "`nCreating SymLink for log file (WAU-updates) in Intune Management Extension log folder" -ForegroundColor Yellow $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue } - + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink - if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) + if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) { Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -ErrorAction SilentlyContinue) } - - if ($caller -eq 'Winget-Upgrade.ps1') + + if ($caller -eq 'Winget-Upgrade.ps1') { # Log file $Log | Out-File -FilePath $LogFile -Append -Force diff --git a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 index 8abb674..ff3dafb 100644 --- a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 +++ b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 @@ -1,39 +1,49 @@ # Function to send the notifications to user -function Start-NotifTask +function Start-NotifTask { [CmdletBinding()] - param( - [String]$Title = 'Winget-AutoUpdate', - [String]$Message, - [String]$MessageType, - [String]$Balise = 'WAU', - [String]$OnClickAction, - [String]$Body, - [String]$Button1Text, - [String]$Button1Action, - [Switch]$ButtonDismiss = $false, - [Switch]$UserRun = $false + param ( + [String] + $Title = 'Winget-AutoUpdate', + [String] + $Message, + [String] + $MessageType, + [String] + $Balise = 'WAU', + [String] + $OnClickAction, + [String] + $Body, + [String] + $Button1Text, + [String] + $Button1Action, + [Switch] + $ButtonDismiss = $false, + [Switch] + $UserRun = $false ) - - if (($WAUConfig.WAU_NotificationLevel -eq 'Full') -or ($WAUConfig.WAU_NotificationLevel -eq 'SuccessOnly' -and $MessageType -eq 'Success') -or ($UserRun)) + + if (($WAUConfig.WAU_NotificationLevel -eq 'Full') -or ($WAUConfig.WAU_NotificationLevel -eq 'SuccessOnly' -and $MessageType -eq 'Success') -or ($UserRun)) { # XML Toast template creation [xml]$ToastTemplate = New-Object -TypeName system.Xml.XmlDocument $ToastTemplate.LoadXml("") - + # Creation of visual node $XMLvisual = $ToastTemplate.CreateElement('visual') - + # Creation of a binding node $XMLbinding = $ToastTemplate.CreateElement('binding') $null = $XMLvisual.AppendChild($XMLbinding) $XMLbindingAtt1 = ($ToastTemplate.CreateAttribute('template')) $XMLbindingAtt1.Value = 'ToastGeneric' $null = $XMLbinding.Attributes.Append($XMLbindingAtt1) - + $XMLimagepath = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) - if (Test-Path -Path $XMLimagepath -ErrorAction SilentlyContinue) + if (Test-Path -Path $XMLimagepath -ErrorAction SilentlyContinue) { # Creation of a image node $XMLimage = $ToastTemplate.CreateElement('image') @@ -45,8 +55,8 @@ function Start-NotifTask $XMLimageAtt2.Value = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) $null = $XMLimage.Attributes.Append($XMLimageAtt2) } - - if ($Title) + + if ($Title) { # Creation of a text node $XMLtitle = $ToastTemplate.CreateElement('text') @@ -54,8 +64,8 @@ function Start-NotifTask $null = $XMLtitle.AppendChild($XMLtitleText) $null = $XMLbinding.AppendChild($XMLtitle) } - - if ($Message) + + if ($Message) { # Creation of a text node $XMLtext = $ToastTemplate.CreateElement('text') @@ -63,17 +73,17 @@ function Start-NotifTask $null = $XMLtext.AppendChild($XMLtextText) $null = $XMLbinding.AppendChild($XMLtext) } - - if ($Body) + + if ($Body) { # Creation of a group node $XMLgroup = $ToastTemplate.CreateElement('group') $null = $XMLbinding.AppendChild($XMLgroup) - + # Creation of a subgroup node $XMLsubgroup = $ToastTemplate.CreateElement('subgroup') $null = $XMLgroup.AppendChild($XMLsubgroup) - + # Creation of a text node $XMLcontent = $ToastTemplate.CreateElement('text') $XMLcontentText = $ToastTemplate.CreateTextNode($Body) @@ -86,11 +96,11 @@ function Start-NotifTask $XMLcontentAtt2.Value = 'true' $null = $XMLcontent.Attributes.Append($XMLcontentAtt2) } - + # Creation of actions node $XMLactions = $ToastTemplate.CreateElement('actions') - - if ($Button1Text) + + if ($Button1Text) { # Creation of action node $XMLaction = $ToastTemplate.CreateElement('action') @@ -98,7 +108,7 @@ function Start-NotifTask $XMLactionAtt1 = $ToastTemplate.CreateAttribute('content') $XMLactionAtt1.Value = $Button1Text $null = $XMLaction.Attributes.Append($XMLactionAtt1) - if ($Button1Action) + if ($Button1Action) { $XMLactionAtt2 = $ToastTemplate.CreateAttribute('arguments') $XMLactionAtt2.Value = $Button1Action @@ -108,8 +118,8 @@ function Start-NotifTask $null = $XMLaction.Attributes.Append($XMLactionAtt3) } } - - if ($ButtonDismiss) + + if ($ButtonDismiss) { # Creation of action node $XMLaction = $ToastTemplate.CreateElement('action') @@ -124,39 +134,39 @@ function Start-NotifTask $XMLactionAtt3.Value = 'system' $null = $XMLaction.Attributes.Append($XMLactionAtt3) } - + # Creation of tag node $XMLtag = $ToastTemplate.CreateElement('tag') $XMLtagText = $ToastTemplate.CreateTextNode($Balise) $null = $XMLtag.AppendChild($XMLtagText) - + # Add the visual node to the xml $null = $ToastTemplate.LastChild.AppendChild($XMLvisual) $null = $ToastTemplate.LastChild.AppendChild($XMLactions) $null = $ToastTemplate.LastChild.AppendChild($XMLtag) - - if ($OnClickAction) + + if ($OnClickAction) { $null = $ToastTemplate.toast.SetAttribute('activationType', 'Protocol') $null = $ToastTemplate.toast.SetAttribute('launch', $OnClickAction) } - + # if not "Interactive" user, run as system - if ($IsSystem) + if ($IsSystem) { # Save XML to File $ToastTemplateLocation = ('{0}\config\' -f $WAUConfig.InstallLocation) - if (!(Test-Path -Path $ToastTemplateLocation -ErrorAction SilentlyContinue)) + if (!(Test-Path -Path $ToastTemplateLocation -ErrorAction SilentlyContinue)) { $null = (New-Item -ItemType Directory -Force -Confirm:$false -Path $ToastTemplateLocation) } - + $ToastTemplate.Save(('{0}\notif.xml' -f $ToastTemplateLocation)) - + # Run Notify scheduled task to notify conneted users $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue) } - else + else { #else, run as connected user # Load Assemblies @@ -164,20 +174,20 @@ function Start-NotifTask $null = (Add-Type -AssemblyName Windows.Data) $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] - + # Prepare XML $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New() $ToastXml.LoadXml($ToastTemplate.OuterXml) - + # Specify Launcher App ID $LauncherID = 'Windows.SystemToast.Winget.Notification' - + # Prepare and Create Toast $ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) $ToastMessage.Tag = $ToastTemplate.toast.tag [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) } - + # Wait for notification to display Start-Sleep -Seconds 3 } diff --git a/Winget-AutoUpdate/functions/Test-ListPath.ps1 b/Winget-AutoUpdate/functions/Test-ListPath.ps1 index 210a1cc..86fe8e7 100644 --- a/Winget-AutoUpdate/functions/Test-ListPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ListPath.ps1 @@ -1,53 +1,56 @@ # Function to check Block/Allow List External Path -function Test-ListPath +function Test-ListPath { # URL, UNC or Local Path [CmdletBinding()] param ( - [string]$ListPath, - [string]$UseWhiteList, - [string]$WingetUpdatePath + [string] + $ListPath, + [string] + $UseWhiteList, + [string] + $WingetUpdatePath ) - if ($UseWhiteList) + if ($UseWhiteList) { $ListType = 'included_apps.txt' } - else + else { $ListType = 'excluded_apps.txt' } - + # Get local and external list paths $LocalList = -join ($WingetUpdatePath, '\', $ListType) $ExternalList = -join ($ListPath, '\', $ListType) - + # Check if a list exists - if (Test-Path -Path $LocalList -ErrorAction SilentlyContinue) + if (Test-Path -Path $LocalList -ErrorAction SilentlyContinue) { $dateLocal = (Get-Item -Path $LocalList).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + # If path is URL - if ($ListPath -like 'http*') + if ($ListPath -like 'http*') { $ExternalList = -join ($ListPath, '/', $ListType) $wc = (New-Object -TypeName System.Net.WebClient) - - try + + try { $null = $wc.OpenRead($ExternalList).Close() $dateExternal = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - - if ($dateExternal -gt $dateLocal) + + if ($dateExternal -gt $dateLocal) { - try + try { $wc.DownloadFile($ExternalList, $LocalList) } - catch + catch { $Script:ReachNoPath = $True return $False @@ -55,52 +58,52 @@ function Test-ListPath return $True } } - catch + catch { - try + try { $content = $wc.DownloadString(('{0}' -f $ExternalList)) - - if ($null -ne $content -and $content -match '\w\.\w') + + if ($null -ne $content -and $content -match '\w\.\w') { $wc.DownloadFile($ExternalList, $LocalList) return $True } - else + else { $Script:ReachNoPath = $True return $False } } - catch + catch { $Script:ReachNoPath = $True return $False } } } - else + else { # If path is UNC or local - if (Test-Path -Path $ExternalList) + if (Test-Path -Path $ExternalList) { - try + try { $dateExternal = (Get-Item -Path ('{0}' -f $ExternalList)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - catch + catch { $Script:ReachNoPath = $True return $False } - - if ($dateExternal -gt $dateLocal) + + if ($dateExternal -gt $dateLocal) { - try + try { Copy-Item -Path $ExternalList -Destination $LocalList -Force } - catch + catch { $Script:ReachNoPath = $True return $False @@ -108,11 +111,11 @@ function Test-ListPath return $True } } - else + else { $Script:ReachNoPath = $True } - + return $False } } diff --git a/Winget-AutoUpdate/functions/Test-Mods.ps1 b/Winget-AutoUpdate/functions/Test-Mods.ps1 index 03e53c1..598c548 100644 --- a/Winget-AutoUpdate/functions/Test-Mods.ps1 +++ b/Winget-AutoUpdate/functions/Test-Mods.ps1 @@ -1,49 +1,50 @@ # Function to check if modification exists within 'mods' directory -function Test-Mods +function Test-Mods { # Takes care of a null situation [CmdletBinding()] param ( - [string]$app + [string] + $app ) - + $ModsPreInstall = $null $ModsOverride = $null $ModsUpgrade = $null $ModsInstall = $null $ModsInstalled = $null $Mods = ('{0}\mods' -f $WorkingDir) - - if (Test-Path -Path ('{0}\{1}-*' -f $Mods, $app) -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\{1}-*' -f $Mods, $app) -ErrorAction SilentlyContinue) { - if (Test-Path -Path ('{0}\{1}-preinstall.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + if (Test-Path -Path ('{0}\{1}-preinstall.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsPreInstall = ('{0}\{1}-preinstall.ps1' -f $Mods, $app) } - - if (Test-Path -Path ('{0}\{1}-override.txt' -f $Mods, $app) -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\{1}-override.txt' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsOverride = Get-Content -Path ('{0}\{1}-override.txt' -f $Mods, $app) -Raw } - - if (Test-Path -Path ('{0}\{1}-install.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\{1}-install.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsInstall = ('{0}\{1}-install.ps1' -f $Mods, $app) $ModsUpgrade = ('{0}\{1}-install.ps1' -f $Mods, $app) } - - if (Test-Path -Path ('{0}\{1}-upgrade.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\{1}-upgrade.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsUpgrade = ('{0}\{1}-upgrade.ps1' -f $Mods, $app) } - - if (Test-Path -Path ('{0}\{1}-installed.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) + + if (Test-Path -Path ('{0}\{1}-installed.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsInstalled = ('{0}\{1}-installed.ps1' -f $Mods, $app) } } - + return $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled } diff --git a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 index 3be0e88..5cdf7dd 100644 --- a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 @@ -1,6 +1,6 @@ #Function to check mods External Path -function Test-ModsPath +function Test-ModsPath { # URL, UNC or Local Path # Get local and external Mods paths @@ -8,38 +8,41 @@ function Test-ModsPath [CmdletBinding()] param ( - [string]$ModsPath, - [string]$WingetUpdatePath, - [string]$AzureBlobSASURL + [string] + $ModsPath, + [string] + $WingetUpdatePath, + [string] + $AzureBlobSASURL ) $LocalMods = -join ($WingetUpdatePath, '\', 'mods') $ExternalMods = $ModsPath - + # Get File Names Locally $InternalModsNames = (Get-ChildItem -Path $LocalMods -Name -Recurse -Include *.ps1, *.txt -ErrorAction SilentlyContinue) $InternalBinsNames = (Get-ChildItem -Path $LocalMods"\bins" -Name -Recurse -Include *.exe -ErrorAction SilentlyContinue) - + # If path is URL - if ($ExternalMods -like 'http*') + if ($ExternalMods -like 'http*') { # enable TLS 1.2 and TLS 1.1 protocols [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Tls11 # Get Index of $ExternalMods (or index page with href listing of all the Mods) - try + try { $WebResponse = (Invoke-WebRequest -Uri $ExternalMods -UseBasicParsing) } - catch + catch { $Script:ReachNoPath = $True - + return $False } - + # Check for bins, download if newer. Delete if not external $ExternalBins = ('{0}/bins' -f $ModsPath) - if ($WebResponse -match 'bins/') + if ($WebResponse -match 'bins/') { $BinResponse = Invoke-WebRequest -Uri $ExternalBins -UseBasicParsing # Collect the external list of href links @@ -49,9 +52,9 @@ function Test-ModsPath # Modify strings to HREF:s $index = 0 - foreach ($Bin in $CleanBinLinks) + foreach ($Bin in $CleanBinLinks) { - if ($Bin) + if ($Bin) { $CleanBinLinks[$index] = ' ' + $Bin + '' } @@ -61,36 +64,36 @@ function Test-ModsPath # Delete Local Bins that don't exist Externally $index = 0 $CleanLinks = $BinLinks -replace '/.*/', '' - - foreach ($Bin in $InternalBinsNames) + + foreach ($Bin in $InternalBinsNames) { - If ($CleanLinks -notcontains $Bin) + if ($CleanLinks -notcontains $Bin) { $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + $index++ } - + $CleanBinLinks = $BinLinks -replace '/.*/', '' $Bin = '' # Loop through all links $wc = New-Object -TypeName System.Net.WebClient $CleanBinLinks | ForEach-Object -Process { # Check for .exe in listing/HREF:s in an index page pointing to .exe - if ($_ -like '*.exe') + if ($_ -like '*.exe') { $dateExternalBin = '' $dateLocalBin = '' $null = $wc.OpenRead(('{0}/{1}' -f $ExternalBins, $_)).Close() $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - - if (Test-Path -Path $LocalMods"\bins\"$_) + + if (Test-Path -Path $LocalMods"\bins\"$_) { $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - - if ($dateExternalBin -gt $dateLocalBin) + + if ($dateExternalBin -gt $dateLocalBin) { $SaveBin = Join-Path -Path ('{0}\bins' -f $LocalMods) -ChildPath $_ Invoke-WebRequest -Uri ('{0}/{1}' -f $ExternalBins, $_) -OutFile $SaveBin.Replace('%20', ' ') -UseBasicParsing @@ -98,76 +101,76 @@ function Test-ModsPath } } } - + # Collect the external list of href links $ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF # If there's a directory path in the HREF:s, delete it (IIS) $CleanLinks = $ModLinks -replace '/.*/', '' # Modify strings to HREF:s $index = 0 - - foreach ($Mod in $CleanLinks) + + foreach ($Mod in $CleanLinks) { - if ($Mod) + if ($Mod) { $CleanLinks[$index] = ' ' + $Mod + '' } $index++ } - + # Delete Local Mods that don't exist Externally $DeletedMods = 0 $index = 0 $CleanLinks = $ModLinks -replace '/.*/', '' - - foreach ($Mod in $InternalModsNames) + + foreach ($Mod in $InternalModsNames) { - If ($CleanLinks -notcontains $Mod) + if ($CleanLinks -notcontains $Mod) { $null = (Remove-Item -Path $LocalMods\$Mod -Force -Confirm:$False -ErrorAction SilentlyContinue) $DeletedMods++ } $index++ } - + $CleanLinks = $ModLinks -replace '/.*/', '' - + # Loop through all links - + $CleanLinks | ForEach-Object -Process { # Check for .ps1/.txt in listing/HREF:s in an index page pointing to .ps1/.txt - if (($_ -like '*.ps1') -or ($_ -like '*.txt')) + if (($_ -like '*.ps1') -or ($_ -like '*.txt')) { - try + try { $dateExternalMod = '' $dateLocalMod = '' $null = $wc.OpenRead(('{0}/{1}' -f $ExternalMods, $_)).Close() $dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - - if (Test-Path -Path $LocalMods"\"$_) + + if (Test-Path -Path $LocalMods"\"$_) { $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - - if ($dateExternalMod -gt $dateLocalMod) + + if ($dateExternalMod -gt $dateLocalMod) { - try + try { $SaveMod = Join-Path -Path ('{0}\' -f $LocalMods) -ChildPath $_ $Mod = '{0}/{1}' -f $ModsPath.TrimEnd('/'), $_ $null = (Invoke-WebRequest -Uri $Mod -OutFile $SaveMod -UseBasicParsing) $ModsUpdated++ } - catch + catch { $Script:ReachNoPath = $True } } } - catch + catch { - if (($_ -like '*.ps1') -or ($_ -like '*.txt')) + if (($_ -like '*.ps1') -or ($_ -like '*.txt')) { $Script:ReachNoPath = $True } @@ -177,131 +180,131 @@ function Test-ModsPath return $ModsUpdated, $DeletedMods } # If Path is Azure Blob - elseif ($ExternalMods -like 'AzureBlob') + elseif ($ExternalMods -like 'AzureBlob') { Write-ToLog -LogMsg 'Azure Blob Storage set as mod source' Write-ToLog -LogMsg 'Checking AZCopy' Get-AZCopy $WingetUpdatePath - + # Safety check to make sure we really do have azcopy.exe and a Blob URL - if ((Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) + if ((Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) { Write-ToLog -LogMsg 'Syncing Blob storage with local storage' - + $AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync $AzureBlobSASURL $LocalMods --from-to BlobLocal --delete-destination=true $AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine) - - foreach ( $_ in $AZCopyOutputLines) + + foreach ($_ in $AZCopyOutputLines) { $AZCopySyncAdditionsRegex = [regex]::new('(?<=Number of Copy Transfers Completed:\s+)\d+') $AZCopySyncDeletionsRegex = [regex]::new('(?<=Number of Deletions at Destination:\s+)\d+') $AZCopySyncErrorRegex = [regex]::new('^Cannot perform sync due to error:') - - $AZCopyAdditions = [int] $AZCopySyncAdditionsRegex.Match($_).Value - $AZCopyDeletions = [int] $AZCopySyncDeletionsRegex.Match($_).Value - - if ($AZCopyAdditions -ne 0) + + $AZCopyAdditions = [int]$AZCopySyncAdditionsRegex.Match($_).Value + $AZCopyDeletions = [int]$AZCopySyncDeletionsRegex.Match($_).Value + + if ($AZCopyAdditions -ne 0) { $ModsUpdated = $AZCopyAdditions } - - if ($AZCopyDeletions -ne 0) + + if ($AZCopyDeletions -ne 0) { $DeletedMods = $AZCopyDeletions } - - if ($AZCopySyncErrorRegex.Match($_).Value) + + if ($AZCopySyncErrorRegex.Match($_).Value) { - Write-ToLog -LogMsg ('AZCopy Sync Error! {0}' -f $_) + Write-ToLog -LogMsg ('AZCopy Sync Error! {0}' -f $_) } } } - else + else { Write-ToLog -LogMsg "Error 'azcopy.exe' or SAS Token not found!" } - + return $ModsUpdated, $DeletedMods } - else + else { # If path is UNC or local $ExternalBins = ('{0}\bins' -f $ModsPath) - - if (Test-Path -Path $ExternalBins"\*.exe") + + if (Test-Path -Path $ExternalBins"\*.exe") { $ExternalBinsNames = (Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe) - + # Delete Local Bins that don't exist Externally - foreach ($Bin in $InternalBinsNames) + foreach ($Bin in $InternalBinsNames) { - If ($Bin -notin $ExternalBinsNames ) + if ($Bin -notin $ExternalBinsNames) { $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) } } - + # Copy newer external bins - foreach ($Bin in $ExternalBinsNames) + foreach ($Bin in $ExternalBinsNames) { $dateExternalBin = '' $dateLocalBin = '' - - if (Test-Path -Path $LocalMods"\bins\"$Bin) + + if (Test-Path -Path $LocalMods"\bins\"$Bin) { $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + $dateExternalBin = (Get-Item -Path ('{0}\{1}' -f $ExternalBins, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') - - if ($dateExternalBin -gt $dateLocalBin) + + if ($dateExternalBin -gt $dateLocalBin) { $null = Copy-Item -Path $ExternalBins\$Bin -Destination $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue } } } - - if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) + + if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) { # Get File Names Externally $ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt - + # Delete Local Mods that don't exist Externally $DeletedMods = 0 - - foreach ($Mod in $InternalModsNames) + + foreach ($Mod in $InternalModsNames) { - If ($Mod -notin $ExternalModsNames ) + if ($Mod -notin $ExternalModsNames) { $null = Remove-Item -Path $LocalMods\$Mod -Force -ErrorAction SilentlyContinue $DeletedMods++ } } - + # Copy newer external mods - foreach ($Mod in $ExternalModsNames) + foreach ($Mod in $ExternalModsNames) { $dateExternalMod = '' $dateLocalMod = '' - if (Test-Path -Path $LocalMods"\"$Mod) + if (Test-Path -Path $LocalMods"\"$Mod) { $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + $dateExternalMod = (Get-Item -Path ('{0}\{1}' -f $ExternalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') - - if ($dateExternalMod -gt $dateLocalMod) + + if ($dateExternalMod -gt $dateLocalMod) { $null = Copy-Item -Path $ExternalMods\$Mod -Destination $LocalMods\$Mod -Force -ErrorAction SilentlyContinue $ModsUpdated++ } } } - else + else { $Script:ReachNoPath = $True } - + return $ModsUpdated, $DeletedMods } } diff --git a/Winget-AutoUpdate/functions/Test-Network.ps1 b/Winget-AutoUpdate/functions/Test-Network.ps1 index 7a50781..d0c7eb3 100644 --- a/Winget-AutoUpdate/functions/Test-Network.ps1 +++ b/Winget-AutoUpdate/functions/Test-Network.ps1 @@ -1,58 +1,58 @@ # Function to check the connectivity -function Test-Network +function Test-Network { #Init - + $timeout = 0 - + # Test connectivity during 30 min then timeout Write-ToLog -LogMsg 'Checking internet connection...' -LogColor 'Yellow' - While ($timeout -lt 1800) + while ($timeout -lt 1800) { $URLtoTest = 'https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE' $URLcontent = ((Invoke-WebRequest -Uri $URLtoTest -UseBasicParsing).content) - - if ($URLcontent -like '*MIT License*') + + if ($URLcontent -like '*MIT License*') { Write-ToLog -LogMsg 'Connected !' -LogColor 'Green' - + # Check for metered connection $null = (Add-Type -AssemblyName Windows.Networking) $null = [Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime] $cost = [Windows.Networking.Connectivity.NetworkInformation]::GetInternetConnectionProfile().GetConnectionCost() - - if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne 'Unrestricted')) + + if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne 'Unrestricted')) { Write-ToLog -LogMsg 'Metered connection detected.' -LogColor 'Yellow' - - if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) + + if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) { Write-ToLog -LogMsg 'WAU is configured to bypass update checking on metered connection' return $false } - else + else { Write-ToLog -LogMsg 'WAU is configured to force update checking on metered connection' return $true } } - else + else { return $true } } - else + else { Start-Sleep -Seconds 10 $timeout += 10 - + # Send Warning Notif if no connection for 5 min - if ($timeout -eq 300) + if ($timeout -eq 300) { # Log Write-ToLog -LogMsg "Notify 'No connection' sent." -LogColor 'Yellow' - + # Notif $Title = $NotifLocale.local.outputs.output[0].title $Message = $NotifLocale.local.outputs.output[0].message @@ -62,16 +62,16 @@ function Test-Network } } } - + # Send Timeout Notif if no connection for 30 min Write-ToLog -LogMsg 'Timeout. No internet connection !' -LogColor 'Red' - + # Notif $Title = $NotifLocale.local.outputs.output[1].title $Message = $NotifLocale.local.outputs.output[1].message $MessageType = 'error' $Balise = 'Connection' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise - + return $false } diff --git a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 index fb4235b..e9ea46e 100644 --- a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 +++ b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 @@ -1,34 +1,34 @@ # Function to check if there is a Pending Reboot -function Test-PendingReboot +function Test-PendingReboot { $Computer = $env:COMPUTERNAME $PendingReboot = $false - + $HKLM = [UInt32] '0x80000002' $WMI_Reg = [WMIClass] ('\\{0}\root\default:StdRegProv' -f $Computer) - - if ($WMI_Reg) + + if ($WMI_Reg) { - if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\')).sNames -contains 'RebootPending') + if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\')).sNames -contains 'RebootPending') { - $PendingReboot = $true + $PendingReboot = $true } - if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\')).sNames -contains 'RebootRequired') + if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\')).sNames -contains 'RebootRequired') { - $PendingReboot = $true + $PendingReboot = $true } - + # Checking for SCCM namespace $SCCM_Namespace = Get-WmiObject -Namespace ROOT\CCM\ClientSDK -List -ComputerName $Computer -ErrorAction Ignore - if ($SCCM_Namespace) + if ($SCCM_Namespace) { - if (([WmiClass]('\\{0}\ROOT\CCM\ClientSDK:CCM_ClientUtilities' -f $Computer)).DetermineIfRebootPending().RebootPending -eq $true) + if (([WmiClass]('\\{0}\ROOT\CCM\ClientSDK:CCM_ClientUtilities' -f $Computer)).DetermineIfRebootPending().RebootPending -eq $true) { - $PendingReboot = $true + $PendingReboot = $true } } } - + return $PendingReboot } diff --git a/Winget-AutoUpdate/functions/Update-App.ps1 b/Winget-AutoUpdate/functions/Update-App.ps1 index d9c3b49..a5549be 100644 --- a/Winget-AutoUpdate/functions/Update-App.ps1 +++ b/Winget-AutoUpdate/functions/Update-App.ps1 @@ -1,6 +1,6 @@ # Function to update an App -Function Update-App +function Update-App { # Get App Info [CmdletBinding()] @@ -9,11 +9,11 @@ Function Update-App $app ) $ReleaseNoteURL = Get-AppInfo $app.Id - if ($ReleaseNoteURL) + if ($ReleaseNoteURL) { $Button1Text = $NotifLocale.local.outputs.output[10].message } - + # Send available update notification Write-ToLog -LogMsg ('Updating {0} from {1} to {2}...' -f $app.Name, $app.Version, $app.AvailableVersion) -LogColor 'Cyan' $Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name) @@ -21,99 +21,99 @@ Function Update-App $MessageType = 'info' $Balise = $($app.Name) Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text - + # Check if mods exist for preinstall/install/upgrade $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) - + # Winget upgrade Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - + # If PreInstall script exist - if ($ModsPreInstall) + if ($ModsPreInstall) { Write-ToLog -LogMsg ('Modifications for {0} before upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsPreInstall" } - + # Run Winget Upgrade command - if ($ModsOverride) + if ($ModsOverride) { Write-ToLog -LogMsg ('-> Running (overriding default): Winget upgrade --id {0} --accept-package-agreements --accept-source-agreements --override {1}' -f $app.Id, $ModsOverride) & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -FilePath $LogFile -Append } - else + else { Write-ToLog -LogMsg ('-> Running: Winget upgrade --id {0} --accept-package-agreements --accept-source-agreements -h' -f $app.Id) & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -FilePath $LogFile -Append } - - if ($ModsUpgrade) + + if ($ModsUpgrade) { Write-ToLog -LogMsg ('Modifications for {0} during upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsUpgrade" } - + # Check if application updated properly $FailedToUpgrade = $false $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - - if ($ConfirmInstall -ne $true) + + if ($ConfirmInstall -ne $true) { # Upgrade failed! # Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities) $PendingReboot = Test-PendingReboot - if ($PendingReboot -eq $true) + if ($PendingReboot -eq $true) { Write-ToLog -LogMsg ("-> A Pending Reboot lingers and probably prohibited {0} from upgrading...`n-> ...an install for {1} is NOT executed!" -f $app.Name) -LogColor 'Red' $FailedToUpgrade = $true break } - + # If app failed to upgrade, run Install command Write-ToLog -LogMsg ('-> An upgrade for {0} failed, now trying an install instead...' -f $app.Name) -LogColor 'Yellow' - - if ($ModsOverride) + + if ($ModsOverride) { Write-ToLog -LogMsg ('-> Running (overriding default): Winget install --id {0} --accept-package-agreements --accept-source-agreements --force --override {1}' -f $app.Id, $ModsOverride) & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force --override $ModsOverride | Tee-Object -FilePath $LogFile -Append } - else + else { Write-ToLog -LogMsg ('-> Running: Winget install --id {0} --accept-package-agreements --accept-source-agreements --force -h' -f $app.Id) & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force -h | Tee-Object -FilePath $LogFile -Append } - - if ($ModsInstall) + + if ($ModsInstall) { Write-ToLog -LogMsg ('Modifications for {0} during install are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsInstall" } - + # Check if application installed properly $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - if ($ConfirmInstall -eq $false) + if ($ConfirmInstall -eq $false) { $FailedToUpgrade = $true } } - - if ($FailedToUpgrade -eq $false) + + if ($FailedToUpgrade -eq $false) { - if ($ModsInstalled) + if ($ModsInstalled) { Write-ToLog -LogMsg ('Modifications for {0} after upgrade/install are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsInstalled" } } - + Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - + # Notify installation - if ($FailedToUpgrade -eq $false) + if ($FailedToUpgrade -eq $false) { # Send success updated app notification Write-ToLog -LogMsg ('{0} updated to {1} !' -f $app.Name, $app.AvailableVersion) -LogColor 'Green' - + # Send Notif $Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name) $Message = $NotifLocale.local.outputs.output[3].message -f $($app.AvailableVersion) @@ -122,11 +122,11 @@ Function Update-App Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text $Script:InstallOK += 1 } - else + else { # Send failed updated app notification Write-ToLog -LogMsg ('{0} update failed.' -f $app.Name) -LogColor 'Red' - + # Send Notif $Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name) $Message = $NotifLocale.local.outputs.output[4].message diff --git a/Winget-AutoUpdate/functions/Update-WAU.ps1 b/Winget-AutoUpdate/functions/Update-WAU.ps1 index 0e9d74b..62f950e 100644 --- a/Winget-AutoUpdate/functions/Update-WAU.ps1 +++ b/Winget-AutoUpdate/functions/Update-WAU.ps1 @@ -1,68 +1,68 @@ # Function to update WAU -function Update-WAU +function Update-WAU { $OnClickAction = 'https://github.com/Romanitho/Winget-AutoUpdate/releases' $Button1Text = $NotifLocale.local.outputs.output[10].message - + #Send available update notification $Title = $NotifLocale.local.outputs.output[2].title -f 'Winget-AutoUpdate' $Message = $NotifLocale.local.outputs.output[2].message -f $WAUCurrentVersion, $WAUAvailableVersion $MessageType = 'info' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - + # Run WAU update - try + try { # Force to create a zip file $ZipFile = ('{0}\WAU_update.zip' -f $WorkingDir) $null = New-Item -Path $ZipFile -ItemType File -Force - + # Download the zip Write-ToLog -LogMsg ('Downloading the GitHub Repository version {0}' -f $WAUAvailableVersion) -LogColor 'Cyan' $null = (Invoke-RestMethod -Uri ('https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v{0}/WAU.zip' -f ($WAUAvailableVersion)) -OutFile $ZipFile) - + # Extract Zip File Write-ToLog -LogMsg 'Unzipping the WAU Update package' -LogColor 'Cyan' $location = ('{0}\WAU_update' -f $WorkingDir) $null = (Expand-Archive -Path $ZipFile -DestinationPath $location -Force) $null = (Get-ChildItem -Path $location -Recurse | Unblock-File -ErrorAction SilentlyContinue) - + # Update scritps Write-ToLog -LogMsg 'Updating WAU...' -LogColor 'Yellow' $TempPath = (Resolve-Path -Path ('{0}\Winget-AutoUpdate\' -f $location) -ErrorAction SilentlyContinue)[0].Path - if ($TempPath) + if ($TempPath) { $null = (Copy-Item -Path ('{0}\*' -f $TempPath) -Destination ('{0}\' -f $WorkingDir) -Exclude 'icons' -Recurse -Force -Confirm:$false) } - + # Remove update zip file and update temp folder Write-ToLog -LogMsg 'Done. Cleaning temp files...' -LogColor 'Cyan' $null = (Remove-Item -Path $ZipFile -Force -Confirm:$false -ErrorAction SilentlyContinue) $null = (Remove-Item -Path $location -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue) - + # Set new version to registry $WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force $WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Major -Force $WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Minor -Force - + # Set Post Update actions to 1 $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force - + # Send success Notif Write-ToLog -LogMsg 'WAU Update completed.' -LogColor 'Green' $Title = $NotifLocale.local.outputs.output[3].title -f 'Winget-AutoUpdate' $Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion $MessageType = 'success' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - + # Rerun with newer version Write-ToLog -LogMsg 'Re-run WAU' Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" - + exit } - catch + catch { # Send Error Notif $Title = $NotifLocale.local.outputs.output[4].title -f 'Winget-AutoUpdate' diff --git a/Winget-AutoUpdate/functions/Write-ToLog.ps1 b/Winget-AutoUpdate/functions/Write-ToLog.ps1 index d1b7c21..6482edd 100644 --- a/Winget-AutoUpdate/functions/Write-ToLog.ps1 +++ b/Winget-AutoUpdate/functions/Write-ToLog.ps1 @@ -1,20 +1,22 @@ # Write to Log Function -function Write-ToLog +function Write-ToLog { # Get log [CmdletBinding()] param ( - [string]$LogMsg, - [string]$LogColor = 'White' + [string] + $LogMsg, + [string] + $LogColor = 'White' ) - + $Log = ('{0} - {1}' -f (Get-Date -UFormat '%T'), $LogMsg) - + #Echo log $Log | Write-Host -ForegroundColor $LogColor - + #Write log to file $Log | Out-File -FilePath $LogFile -Append -Force -Confirm:$false } From 9d6fa351381dd9557364f64c67f0cddde99807b3 Mon Sep 17 00:00:00 2001 From: Joerg Hochwald Date: Fri, 15 Sep 2023 16:40:37 +0200 Subject: [PATCH 3/4] Final touches Cleanup, mostly whitespaces --- Winget-AutoUpdate-Install.ps1 | 66 ++++++------ Winget-AutoUpdate/User-Run.ps1 | 2 +- Winget-AutoUpdate/WAU-Uninstall.ps1 | 14 +-- Winget-AutoUpdate/Winget-Upgrade.ps1 | 50 ++++----- .../functions/Add-ScopeMachine.ps1 | 8 +- Winget-AutoUpdate/functions/Add-Shortcut.ps1 | 2 +- .../functions/Confirm-Installation.ps1 | 16 +-- Winget-AutoUpdate/functions/Get-AZCopy.ps1 | 12 +-- Winget-AutoUpdate/functions/Get-AppInfo.ps1 | 6 +- .../functions/Get-ExcludedApps.ps1 | 6 +- .../functions/Get-IncludedApps.ps1 | 4 +- .../functions/Get-NotifLocale.ps1 | 12 +-- Winget-AutoUpdate/functions/Get-Policies.ps1 | 84 +++++++-------- .../functions/Get-WAUAvailableVersion.ps1 | 4 +- Winget-AutoUpdate/functions/Get-WingetCmd.ps1 | 20 ++-- .../functions/Get-WingetOutdatedApps.ps1 | 30 +++--- .../functions/Get-WingetSystemApps.ps1 | 8 +- .../functions/Invoke-LogRotation.ps1 | 28 ++--- .../functions/Invoke-ModsProtect.ps1 | 20 ++-- .../functions/Invoke-PostUpdateActions.ps1 | 100 +++++++++--------- Winget-AutoUpdate/functions/Start-Init.ps1 | 12 +-- .../functions/Start-NotifTask.ps1 | 44 ++++---- Winget-AutoUpdate/functions/Test-ListPath.ps1 | 20 ++-- Winget-AutoUpdate/functions/Test-Mods.ps1 | 14 +-- Winget-AutoUpdate/functions/Test-ModsPath.ps1 | 86 +++++++-------- Winget-AutoUpdate/functions/Test-Network.ps1 | 22 ++-- .../functions/Test-PendingReboot.ps1 | 8 +- Winget-AutoUpdate/functions/Update-App.ps1 | 34 +++--- Winget-AutoUpdate/functions/Update-WAU.ps1 | 22 ++-- Winget-AutoUpdate/functions/Write-ToLog.ps1 | 6 +- 30 files changed, 380 insertions(+), 380 deletions(-) diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index bc1db00..dfea1a2 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -150,14 +150,14 @@ param ( function Install-Prerequisites { Write-Host -Object "`nChecking prerequisites..." -ForegroundColor Yellow - + #Check if Visual C++ 2019 or 2022 installed $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' $path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object -FilterScript { $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 } - + #If not installed, ask for installation if (!($path)) { @@ -225,12 +225,12 @@ function Install-Prerequisites function Install-WinGet { Write-Host -Object "`nChecking if Winget is installed" -ForegroundColor Yellow - + #Check Package Install $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' } - + #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 if ([Version]$TestWinGet.Version -ge '2023.808.2243.0') { @@ -239,13 +239,13 @@ function Install-WinGet else { Write-Host -Object '-> Winget is not installed:' - + #Check if $WingetUpdatePath exist if (!(Test-Path $WingetUpdatePath)) { $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath } - + #Downloading and Installing Dependencies in SYSTEM context if (!(Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7')) { @@ -267,7 +267,7 @@ function Install-WinGet Remove-Item -Path $UiXamlZip -Force Remove-Item -Path "$WingetUpdatePath\extracted" -Force -Recurse } - + if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop')) { Write-Host -Object '-> Downloading Microsoft.VCLibs.140.00.UWPDesktop...' @@ -286,13 +286,13 @@ function Install-WinGet } Remove-Item -Path $VCLibsFile -Force } - + #Download WinGet MSIXBundle Write-Host -Object '-> Downloading Winget MSIXBundle for App Installer...' $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($WinGetURL, "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle") - + #Install WinGet MSIXBundle in SYSTEM context try { @@ -304,7 +304,7 @@ function Install-WinGet { Write-Host -Object 'Failed to intall Winget MSIXBundle for App Installer...' -ForegroundColor Red } - + #Remove WinGet MSIXBundle Remove-Item -Path "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue } @@ -313,7 +313,7 @@ function Install-WinGet function Install-WingetAutoUpdate { Write-Host -Object "`nInstalling WAU..." -ForegroundColor Yellow - + try { #Copy files to location (and clean old install) @@ -334,7 +334,7 @@ function Install-WingetAutoUpdate } } Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - + #White List or Black List apps if ($UseWhiteList) { @@ -378,11 +378,11 @@ function Install-WingetAutoUpdate Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue } } - + # Set dummy regkeys for notification name and icon $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v DisplayName /t REG_EXPAND_SZ /d 'Application Update' /f $null = & "$env:windir\system32\reg.exe" add 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /v IconUri /t REG_EXPAND_SZ /d %SystemRoot%\system32\@WindowsUpdateToastIcon.png /f - + # Settings for the scheduled task for Updates $taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($WingetUpdatePath)\winget-upgrade.ps1`"" $taskTriggers = @() @@ -412,7 +412,7 @@ function Install-WingetAutoUpdate } $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 if ($taskTriggers) { @@ -422,30 +422,30 @@ function Install-WingetAutoUpdate { $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings } - + $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate' -InputObject $task -Force - + if ($InstallUserContext) { # Settings for the scheduled task in User context $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-upgrade.ps1`"`"" $taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11 $taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00 - + # Set up the task for user apps $task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force } - + # Settings for the scheduled task for Notifications $taskAction = New-ScheduledTaskAction -Execute 'wscript.exe' -Argument "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\winget-notify.ps1`"`"" $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 $null = Register-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -InputObject $task -Force - + #Set task readable/runnable for all users $scheduler = New-Object -ComObject 'Schedule.Service' $scheduler.Connect() @@ -453,7 +453,7 @@ function Install-WingetAutoUpdate $sec = $task.GetSecurityDescriptor(0xF) $sec = $sec + '(A;;GRGX;;;AU)' $task.SetSecurityDescriptor($sec, 0) - + # Configure Reg Key $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' $null = New-Item $regPath -Force @@ -507,11 +507,11 @@ function Install-WingetAutoUpdate { $null = New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force } - + #Log file and symlink initialization . "$WingetUpdatePath\functions\Start-Init.ps1" Start-Init - + #Security check Write-Host -Object "`nChecking Mods Directory:" -ForegroundColor Yellow . "$WingetUpdatePath\functions\Invoke-ModsProtect.ps1" @@ -528,7 +528,7 @@ function Install-WingetAutoUpdate { Write-Host -Object "Error: The mods directory couldn't be verified as secured!`n" -ForegroundColor Red } - + #Create Shortcuts if ($StartMenuShortcut) { @@ -540,15 +540,15 @@ function Install-WingetAutoUpdate Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' } - + if ($DesktopShortcut) { Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WingetUpdatePath)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WingetUpdatePath)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' } - + Write-Host -Object 'WAU Installation succeeded!' -ForegroundColor Green Start-Sleep -Seconds 1 - + #Run Winget ? Start-WingetAutoUpdate } @@ -563,12 +563,12 @@ function Install-WingetAutoUpdate function Uninstall-WingetAutoUpdate { Write-Host -Object "`nUninstalling WAU..." -ForegroundColor Yellow - + try { #Get registry install location $InstallLocation = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation - + #Check if installed location exists and delete if (Test-Path ($InstallLocation)) { @@ -594,17 +594,17 @@ function Uninstall-WingetAutoUpdate Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f - + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force } - + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { $null = Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force } - + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green Start-Sleep -Seconds 1 } diff --git a/Winget-AutoUpdate/User-Run.ps1 b/Winget-AutoUpdate/User-Run.ps1 index 07910ed..d2c8d6b 100644 --- a/Winget-AutoUpdate/User-Run.ps1 +++ b/Winget-AutoUpdate/User-Run.ps1 @@ -90,7 +90,7 @@ else { Start-Sleep -Seconds 3 } - + # Test if there was a list_/winget_error if (Test-Path -Path ('{0}\logs\error.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) { diff --git a/Winget-AutoUpdate/WAU-Uninstall.ps1 b/Winget-AutoUpdate/WAU-Uninstall.ps1 index 089a2a6..32e4eab 100644 --- a/Winget-AutoUpdate/WAU-Uninstall.ps1 +++ b/Winget-AutoUpdate/WAU-Uninstall.ps1 @@ -35,10 +35,10 @@ Write-Host -Object "`t________________________________________________________`n try { Write-Host -Object 'Uninstalling WAU...' -ForegroundColor Yellow - + # Get registry install location $InstallLocation = (Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation) - + # Check if installed location exists and delete if (Test-Path -Path ($InstallLocation)) { @@ -56,22 +56,22 @@ try $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false) $null = & "$env:windir\system32\reg.exe" delete 'HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification' /f $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f - + if (Test-Path -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' -ErrorAction SilentlyContinue) { $null = & "$env:windir\system32\reg.exe" delete 'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' /f } - + if ((Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) } - + if ((Test-Path -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk")) { $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) } - + # Remove Intune Logs if they are existing if (Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log") { @@ -81,7 +81,7 @@ try { $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -Force -Confirm:$false -ErrorAction SilentlyContinue) } - + Write-Host -Object 'Uninstallation succeeded!' -ForegroundColor Green } else diff --git a/Winget-AutoUpdate/Winget-Upgrade.ps1 b/Winget-AutoUpdate/Winget-Upgrade.ps1 index 1a9eb3d..72af605 100644 --- a/Winget-AutoUpdate/Winget-Upgrade.ps1 +++ b/Winget-AutoUpdate/Winget-Upgrade.ps1 @@ -23,7 +23,7 @@ $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Cu if ($IsSystem) { Write-ToLog 'Running in System context' - + #Get and set Domain/Local Policies (GPO) $ActivateGPOManagement, $ChangedSettings = Get-Policies if ($ActivateGPOManagement) @@ -38,7 +38,7 @@ if ($IsSystem) Write-ToLog 'No Changed settings detected' 'Yellow' } } - + # Maximum number of log files to keep. Default is 3. Setting MaxLogFiles to 0 will keep all log files. $MaxLogFiles = $WAUConfig.WAU_MaxLogFiles if ($null -eq $MaxLogFiles) @@ -49,7 +49,7 @@ if ($IsSystem) { [int]$MaxLogFiles = $MaxLogFiles } - + # Maximum size of log file. $MaxLogSize = $WAUConfig.WAU_MaxLogSize if (!$MaxLogSize) @@ -60,14 +60,14 @@ if ($IsSystem) { [long]$MaxLogSize = $MaxLogSize } - + #LogRotation if System $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize if ($LogRotate -eq $False) { Write-ToLog 'An Exception occured during Log Rotation...' } - + #Run post update actions if necessary if run as System if (!($WAUConfig.WAU_PostUpdateActions -eq 0)) { @@ -91,7 +91,7 @@ if (Test-Network) { #Check if Winget is installed and get Winget cmd $TestWinget = Get-WingetCmd - + if ($TestWinget) { #Get Current Version @@ -123,13 +123,13 @@ if (Test-Network) Write-ToLog 'WAU is up to date.' 'Green' } } - + #Delete previous list_/winget_error (if they exist) if run as System if (Test-Path -Path "$WorkingDir\logs\error.txt") { Remove-Item -Path "$WorkingDir\logs\error.txt" -Force } - + #Get External ListPath if run as System if ($WAUConfig.WAU_ListPath) { @@ -180,7 +180,7 @@ if (Test-Network) } } } - + #Get External ModsPath if run as System if ($WAUConfig.WAU_ModsPath) { @@ -219,7 +219,7 @@ if (Test-Network) Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Red' } } - + #Test if _WAU-mods.ps1 exist: Mods for WAU (if Network is active/any Winget is installed/running as SYSTEM) $Mods = "$WorkingDir\mods" if (Test-Path -Path "$Mods\_WAU-mods.ps1") @@ -235,14 +235,14 @@ if (Test-Network) exit } } - + } - + if ($($WAUConfig.WAU_ListPath) -eq 'GPO') { $Script:GPOList = $True } - + #Get White or Black list if ($WAUConfig.WAU_UseWhiteList -eq 1) { @@ -255,7 +255,7 @@ if (Test-Network) Write-ToLog 'WAU uses Black List config' $toSkip = Get-ExcludedApps } - + #Fix and count the array if GPO List as ERROR handling! if ($GPOList) { @@ -282,18 +282,18 @@ if (Test-Network) $toSkip = $toSkip.Data } } - + #Get outdated Winget packages Write-ToLog 'Checking application updates on Winget Repository...' 'yellow' $outdated = Get-WingetOutdatedApps - + #If something unusual happened if ($outdated -like 'An unusual*') { Write-ToLog "$outdated" 'cyan' $outdated = $False } - + #Run only if $outdated is populated! if ($outdated) { @@ -305,10 +305,10 @@ if (Test-Network) $Log | Write-host $Log | out-file -filepath $LogFile -Append } - + #Count good update installations $Script:InstallOK = 0 - + #Trick under user context when -BypassListForUsers is used if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq 1) { @@ -316,7 +316,7 @@ if (Test-Network) $UseWhiteList = $false $toSkip = $null } - + #If White List if ($UseWhiteList) { @@ -361,18 +361,18 @@ if (Test-Network) } } } - + if ($InstallOK -gt 0) { Write-ToLog "$InstallOK apps updated ! No more update." 'Green' } } - + if ($InstallOK -eq 0 -or !$InstallOK) { Write-ToLog 'No new update.' 'Green' } - + #Check if any user is logged on if System and run User task (if installed) if ($IsSystem) { @@ -388,11 +388,11 @@ if (Test-Network) $UserScheduledTask = Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue if ($UserScheduledTask) { - + #Get Winget system apps to excape them befor running user context Write-ToLog 'User logged on, get a list of installed Winget apps in System context...' Get-WingetSystemApps - + #Run user context scheduled task Write-ToLog 'Starting WAU in User context' Start-ScheduledTask -TaskName $UserScheduledTask.TaskName -ErrorAction SilentlyContinue diff --git a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 index 631c7c2..e0dcb72 100644 --- a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 +++ b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 @@ -7,20 +7,20 @@ function Add-ScopeMachine [string] $SettingsPath ) - + if (Test-Path -Path $SettingsPath -ErrorAction SilentlyContinue) { $ConfigFile = (Get-Content -Path $SettingsPath -ErrorAction SilentlyContinue | Where-Object -FilterScript { ($_ -notmatch '//') } | ConvertFrom-Json) } - + if (!$ConfigFile) { $ConfigFile = @{ } } - + if ($ConfigFile.installBehavior.preferences.scope) { $ConfigFile.installBehavior.preferences.scope = 'Machine' @@ -35,6 +35,6 @@ function Add-ScopeMachine })) $null = (Add-Member -InputObject $ConfigFile -MemberType NoteProperty -Name 'installBehavior' -Value $Preference -Force) } - + $null = ($ConfigFile | ConvertTo-Json | Out-File -FilePath $SettingsPath -Encoding utf8 -Force -Confirm:$false) } diff --git a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 index 75d70c7..0ab9e23 100644 --- a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 +++ b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 @@ -15,7 +15,7 @@ function Add-Shortcut [string] $Description ) - + $WScriptShell = (New-Object -ComObject WScript.Shell) $Shortcut = $WScriptShell.CreateShortcut($Shortcut) $Shortcut.TargetPath = $Target diff --git a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 index 7dba44b..db7100c 100644 --- a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 +++ b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 @@ -1,7 +1,7 @@ function Confirm-Installation { # Set json export file - + [CmdletBinding()] param ( @@ -10,26 +10,26 @@ function Confirm-Installation [string] $AppVer ) - + $JsonFile = ('{0}\Config\InstalledApps.json' -f $WorkingDir) - + # Get installed apps and version in json file $null = (& $Winget export -s winget -o $JsonFile --include-versions) - + # Get json content $Json = (Get-Content -Path $JsonFile -Raw | ConvertFrom-Json) - + # Get apps and version in hashtable $Packages = $Json.Sources.Packages - + # Remove json file $null = (Remove-Item -Path $JsonFile -Force -Confirm:$false -ErrorAction SilentlyContinue) - + # Search for specific app and version $Apps = $Packages | Where-Object -FilterScript { ($_.PackageIdentifier -eq $AppName -and $_.Version -like ('{0}*' -f $AppVer)) } - + if ($Apps) { return $true diff --git a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 index 1e52207..eddcec8 100644 --- a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 +++ b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 @@ -8,16 +8,16 @@ function Get-AZCopy [string] $WingetUpdatePath ) - + $AZCopyLink = (Invoke-WebRequest -Uri https://aka.ms/downloadazcopy-v10-windows -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue).headers.location $AZCopyVersionRegex = [regex]::new('(\d+\.\d+\.\d+)') $AZCopyLatestVersion = $AZCopyVersionRegex.Match($AZCopyLink).Value - + if ($null -eq $AZCopyLatestVersion -or '' -eq $AZCopyLatestVersion) { $AZCopyLatestVersion = '0.0.0' } - + if (Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf -ErrorAction SilentlyContinue) { $AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v @@ -29,7 +29,7 @@ function Get-AZCopy Write-ToLog -LogMsg 'AZCopy not already installed' $AZCopyCurrentVersion = '0.0.0' } - + if (([version]$AZCopyCurrentVersion) -lt ([version]$AZCopyLatestVersion)) { Write-ToLog -LogMsg ('Installing version {0} of AZCopy' -f $AZCopyLatestVersion) @@ -37,7 +37,7 @@ function Get-AZCopy Write-ToLog -LogMsg 'Extracting AZCopy zip file' $null = (Expand-Archive -Path ('{0}\azcopyv10.zip' -f $WingetUpdatePath) -DestinationPath $WingetUpdatePath -Force -Confirm:$false) $AZCopyPathSearch = (Resolve-Path -Path ('{0}\azcopy_*' -f $WingetUpdatePath)) - + if ($AZCopyPathSearch -is [array]) { $AZCopyEXEPath = $AZCopyPathSearch[$AZCopyPathSearch.Length - 1] @@ -46,7 +46,7 @@ function Get-AZCopy { $AZCopyEXEPath = $AZCopyPathSearch } - + Write-ToLog -LogMsg "Copying 'azcopy.exe' to main folder" $null = (Copy-Item -Path ('{0}\azcopy.exe' -f $AZCopyEXEPath) -Destination ('{0}\' -f $WingetUpdatePath) -Force -Confirm:$false) Write-ToLog -LogMsg 'Removing temporary AZCopy files' diff --git a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 index 5038504..57b50e4 100644 --- a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 +++ b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 @@ -2,18 +2,18 @@ function Get-AppInfo { - # Get AppID Info + # Get AppID Info [CmdletBinding()] param ( [string] $AppID ) - + $String = (& $winget show $AppID --accept-source-agreements -s winget | Out-String) # Search for Release Note info $ReleaseNote = [regex]::match($String, '(?<=Release Notes Url: )(.*)(?=\n)').Groups[0].Value - + # Return Release Note return $ReleaseNote } diff --git a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 index da1d326..3ac689a 100644 --- a/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-ExcludedApps.ps1 @@ -7,9 +7,9 @@ function Get-ExcludedApps if (Test-Path -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList' -ErrorAction SilentlyContinue) { $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList\' - + $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList').Property - + foreach ($ValueName in $ValueNames) { $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) @@ -19,7 +19,7 @@ function Get-ExcludedApps } } } - + return $AppIDs } elseif (Test-Path -Path ('{0}\excluded_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) diff --git a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 index b5d2c7f..476944c 100644 --- a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 @@ -8,7 +8,7 @@ function Get-IncludedApps { $Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList\' $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList').Property - + foreach ($ValueName in $ValueNames) { $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) @@ -18,7 +18,7 @@ function Get-IncludedApps } } } - + return $AppIDs } elseif (Test-Path -Path ('{0}\included_apps.txt' -f $WorkingDir) -ErrorAction SilentlyContinue) diff --git a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 index 4704a9e..46147d6 100644 --- a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 +++ b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 @@ -2,13 +2,13 @@ function Get-NotifLocale { - + # Get OS locale $OSLocale = (Get-UICulture).Parent - + # Test if OS locale notif file exists $TestOSLocalPath = ('{0}\locale\{1}.xml' -f $WorkingDir, $OSLocale.Name) - + # Set OS Local if file exists if (Test-Path -Path $TestOSLocalPath -ErrorAction SilentlyContinue) { @@ -21,11 +21,11 @@ function Get-NotifLocale $LocaleDisplayName = 'English' $LocaleFile = ('{0}\locale\en.xml' -f $WorkingDir) } - + # Get locale XML file content [xml]$Script:NotifLocale = (Get-Content -Path $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue) - + # Rerturn langague display name return $LocaleDisplayName - + } diff --git a/Winget-AutoUpdate/functions/Get-Policies.ps1 b/Winget-AutoUpdate/functions/Get-Policies.ps1 index 98eb539..fd293fb 100644 --- a/Winget-AutoUpdate/functions/Get-Policies.ps1 +++ b/Winget-AutoUpdate/functions/Get-Policies.ps1 @@ -4,14 +4,14 @@ function Get-Policies { # Get WAU Policies and set the Configurations Registry Accordingly $WAUPolicies = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate' -ErrorAction SilentlyContinue) - + if ($WAUPolicies) { if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) { $ChangedSettings = 0 $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' - + if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) { $null = (New-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Value $($WAUPolicies.WAU_BypassListForUsers) -PropertyType DWord -Force -Confirm:$false) @@ -22,7 +22,7 @@ function Get-Policies $null = (Remove-ItemProperty -Path $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force -Confirm:$false) @@ -33,7 +33,7 @@ function Get-Policies $null = (Remove-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force -Confirm:$false) @@ -44,7 +44,7 @@ function Get-Policies $null = (New-ItemProperty -Path $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force -Confirm:$false) @@ -55,7 +55,7 @@ function Get-Policies $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force -Confirm:$false) @@ -66,7 +66,7 @@ function Get-Policies $null = (Remove-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) { $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) @@ -77,7 +77,7 @@ function Get-Policies $null = (Remove-ItemProperty -Path $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) { $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) @@ -98,7 +98,7 @@ function Get-Policies $null = (Remove-ItemProperty -Path $regPath -Name WAU_AzureBlobSASURL -Force -ErrorAction SilentlyContinue -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) { $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force -Confirm:$false) @@ -109,7 +109,7 @@ function Get-Policies $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value 'Full' -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $($WAUPolicies.WAU_UpdatesAtTime) -Force -Confirm:$false) @@ -119,7 +119,7 @@ function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) @@ -143,7 +143,7 @@ function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) @@ -155,11 +155,11 @@ function Get-Policies break } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesInterval -Value $($WAUPolicies.WAU_UpdatesInterval) -Force -Confirm:$false) @@ -168,7 +168,7 @@ function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) @@ -178,15 +178,15 @@ function Get-Policies $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) - + if (!$($WAUConfig.WAU_UpdatesAtTime)) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - + if ($($WAUPolicies.WAU_UpdatesInterval) -ne 'Never') { #Count Triggers (correctly) @@ -246,7 +246,7 @@ function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if (($definition.Triggers.Item($triggerId).Type -eq '2') -or ($definition.Triggers.Item($triggerId).Type -eq '3')) @@ -256,17 +256,17 @@ function Get-Policies $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) - + if (!$($WAUConfig.WAU_UpdatesAtTime)) { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force -Confirm:$false) $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } - + $tasktrigger = (New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime)) - + # Count Triggers (correctly) $service = (New-Object -ComObject Schedule.Service) $service.Connect($env:COMPUTERNAME) @@ -274,7 +274,7 @@ function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $null = $definition.Triggers.Count - + if ($definition.Triggers.Count -gt 0) { $triggers = @() @@ -288,7 +288,7 @@ function Get-Policies } $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) { if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) @@ -303,7 +303,7 @@ function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $triggerLogon = $false - + foreach ($trigger in $definition.Triggers) { if ($trigger.Type -eq '9') @@ -327,7 +327,7 @@ function Get-Policies $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition $null = $definition.Triggers.Count - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if ($definition.Triggers.Item($triggerId).Type -eq '9') @@ -336,10 +336,10 @@ function Get-Policies $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) } - + $ChangedSettings++ } elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) @@ -350,7 +350,7 @@ function Get-Policies $folder = $service.GetFolder('\') $task = $folder.GetTask('Winget-AutoUpdate') $definition = $task.Definition - + for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) { if ($definition.Triggers.Item($triggerId).Type -eq '9') @@ -359,15 +359,15 @@ function Get-Policies $triggerId -= 1 } } - + $null = $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) { $null = (New-ItemProperty -Path $regPath -Name WAU_UserContext -Value $($WAUPolicies.WAU_UserContext) -PropertyType DWord -Force -Confirm:$false) - + if ($WAUPolicies.WAU_UserContext -eq 1) { # Settings for the scheduled task in User context @@ -390,11 +390,11 @@ function Get-Policies $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) { $null = (New-ItemProperty -Path $regPath -Name WAU_DesktopShortcut -Value $($WAUPolicies.WAU_DesktopShortcut) -PropertyType DWord -Force -Confirm:$false) - + if ($WAUPolicies.WAU_DesktopShortcut -eq 1) { Add-Shortcut 'wscript.exe' "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' @@ -411,18 +411,18 @@ function Get-Policies $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) { $null = (New-ItemProperty -Path $regPath -Name WAU_StartMenuShortcut -Value $($WAUPolicies.WAU_StartMenuShortcut) -PropertyType DWord -Force -Confirm:$false) - + if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) { if (!(Test-Path -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { $null = (New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Confirm:$false) } - + Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" 'Manual start of Winget-AutoUpdate (WAU)...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" 'Open existing WAU logs...' Add-Shortcut 'wscript.exe' "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" 'Help for WAU...' @@ -439,7 +439,7 @@ function Get-Policies $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value $($WAUPolicies.WAU_MaxLogFiles.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) @@ -450,7 +450,7 @@ function Get-Policies $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -Force -Confirm:$false) $ChangedSettings++ } - + if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value $($WAUPolicies.WAU_MaxLogSize.TrimEnd(' ', '\', '/')) -Force -Confirm:$false) @@ -461,11 +461,11 @@ function Get-Policies $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -Force -Confirm:$false) $ChangedSettings++ } - + # Get WAU Configurations after Policies change $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') } } - + return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings } diff --git a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 index 99e40d4..08e0f93 100644 --- a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 +++ b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 @@ -7,7 +7,7 @@ function Get-WAUAvailableVersion { # Log Write-ToLog -LogMsg 'WAU AutoUpdate Pre-release versions is Enabled' -LogColor 'Cyan' - + # Get latest pre-release info $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases' } @@ -16,7 +16,7 @@ function Get-WAUAvailableVersion # Get latest stable info $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases/latest' } - + # Return version return ((Invoke-WebRequest -Uri $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace('v', '') } diff --git a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 index 72bd927..03fe939 100644 --- a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 @@ -2,19 +2,19 @@ function Get-WingetCmd { - + # Get WinGet Path (if Admin context) # Includes Workaround for ARM64 (removed X64 and replaces it with a wildcard) $ResolveWingetPath = (Resolve-Path -Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe" | Sort-Object -Property { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') }) - + if ($ResolveWingetPath) { # If multiple version, pick last one $WingetPath = $ResolveWingetPath[-1].Path } - + #If running under System or Admin context obtain Winget from Program Files if ((([Security.Principal.WindowsIdentity]::GetCurrent().User) -eq 'S-1-5-18') -or ($WingetPath)) { @@ -27,27 +27,27 @@ function Get-WingetCmd { #Get Winget Location in User context $WingetCmd = (Get-Command -Name winget.exe -ErrorAction SilentlyContinue) - + if ($WingetCmd) { $Script:Winget = $WingetCmd.Source } } - + if (!($Script:Winget)) { Write-ToLog 'Winget not installed or detected !' 'Red' - + return $false } - + # Run winget to list apps and accept source agrements (necessary on first run) $null = (& $Winget list --accept-source-agreements -s winget) - + # Log Winget installed version $WingetVer = & $Winget --version Write-ToLog ('Winget Version: {0}' -f $WingetVer) - + return $true - + } diff --git a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 index ec52979..c2d1b9e 100644 --- a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 @@ -8,60 +8,60 @@ function Get-WingetOutdatedApps [string]$Version [string]$AvailableVersion } - + # Get list of available upgrades on winget format $upgradeResult = (& $Winget upgrade --source winget | Out-String) - + # Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) if (!($upgradeResult -match '-----')) { return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult" } - + # Split winget output to lines $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object -FilterScript { $_ } - + # Find the line that starts with "------" $fl = 0 while (-not $lines[$fl].StartsWith('-----')) { $fl++ } - + # Get header line $fl = $fl - 1 - + # Get header titles [without remove seperator] $index = $lines[$fl] -split '(?<=\s)(?!\s)' - + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length - + # Now cycle in real package and split accordingly $upgradeList = @() - + for ($i = $fl + 2; $i -lt $lines.Length; $i++) { $line = $lines[$i] -replace '[\u2026]', ' ' #Fix "..." in long names - + if ($line.StartsWith('-----')) { # Get header line $fl = $i - 1 - + # Get header titles [without remove seperator] $index = $lines[$fl] -split '(?<=\s)(?!\s)' - + # Line $fl has the header, we can find char where we find ID and Version [and manage non latin characters] $idStart = $($index[0] -replace '[\u4e00-\u9fa5]', '**').Length $versionStart = $idStart + $($index[1] -replace '[\u4e00-\u9fa5]', '**').Length $availableStart = $versionStart + $($index[2] -replace '[\u4e00-\u9fa5]', '**').Length } - + # (Alphanumeric | Literal . | Alphanumeric) - the only unique thing in common for lines with applications if ($line -match '\w\.\w') { @@ -76,7 +76,7 @@ function Get-WingetOutdatedApps $upgradeList += $software } } - + # If current user is not system, remove system apps from list if ($IsSystem -eq $false) { @@ -85,7 +85,7 @@ function Get-WingetOutdatedApps $SystemApps -notcontains $_.Id } } - + return $upgradeList | Sort-Object -Property { Get-Random } diff --git a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 index 0692984..e7df94b 100644 --- a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 @@ -2,16 +2,16 @@ function Get-WingetSystemApps { # Json File, where to export system installed apps $jsonFile = ('{0}\winget_system_apps.txt' -f $WorkingDir) - + # Get list of installed Winget apps to json file $null = (& $Winget export -o $jsonFile --accept-source-agreements -s winget) - + # Convert json file to txt file with app ids $InstalledApps = (Get-Content -Path $jsonFile | ConvertFrom-Json) - + # Save app list $null = (Set-Content -Value $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Sort app list $null = (Get-Content -Path $jsonFile | Sort-Object | Set-Content -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) } diff --git a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 index ebc46c1..35d17c8 100644 --- a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 @@ -12,7 +12,7 @@ function Invoke-LogRotation URL: https://www.powershellgallery.com/packages/Communary.Logger/1.1 Date: 21.11.2014 Version: 1.0 - #> + #> param ( [string] @@ -22,18 +22,18 @@ function Invoke-LogRotation [int] $MaxLogSize ) - + try { # get current size of log file $currentSize = (Get-Item -Path $LogFile).Length - + # get log name $logFileName = (Split-Path -Path $LogFile -Leaf) $logFilePath = (Split-Path -Path $LogFile) $logFileNameWithoutExtension = [IO.Path]::GetFileNameWithoutExtension($logFileName) $logFileNameExtension = [IO.Path]::GetExtension($logFileName) - + # if MaxLogFiles is 1 just keep the original one and let it grow if (-not ($MaxLogFiles -eq 1)) { @@ -41,10 +41,10 @@ function Invoke-LogRotation { # construct name of archived log file $newLogFileName = $logFileNameWithoutExtension + (Get-Date -Format 'yyyyMMddHHmmss').ToString() + $logFileNameExtension - + # copy old log file to new using the archived name constructed above $null = (Copy-Item -Path $LogFile -Destination (Join-Path -Path (Split-Path -Path $LogFile) -ChildPath $newLogFileName)) - + # Create a new log file try { @@ -64,16 +64,16 @@ function Invoke-LogRotation { return $False } - + # if MaxLogFiles is 0 don't delete any old archived log files if (-not ($MaxLogFiles -eq 0)) { # set filter to search for archived log files $archivedLogFileFilter = $logFileNameWithoutExtension + '??????????????' + $logFileNameExtension - + # get archived log files $oldLogFiles = (Get-Item -Path "$(Join-Path -Path $logFilePath -ChildPath $archivedLogFileFilter)") - + if ([bool]$oldLogFiles) { # compare found log files to MaxLogFiles parameter of the log object, and delete oldest until we are @@ -85,16 +85,16 @@ function Invoke-LogRotation } } } - + # Log Header $Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-Culture).DateTimeFormat.ShortDatePattern)`n##################################################" $null = ($Log | Out-File -FilePath $LogFile -Append -Force) Write-ToLog -LogMsg 'Running in System context' - + if ($ActivateGPOManagement) { Write-ToLog -LogMsg 'Activated WAU GPO Management detected, comparing...' - + if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { Write-ToLog -LogMsg 'Changed settings detected and applied' -LogColor 'Yellow' @@ -104,9 +104,9 @@ function Invoke-LogRotation Write-ToLog -LogMsg 'No Changed settings detected' -LogColor 'Yellow' } } - + Write-ToLog -LogMsg ('Max Log Size reached: {0} bytes - Rotated Logs' -f $MaxLogSize) - + return $True } } diff --git a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 index ec3f270..2e8fad2 100644 --- a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 @@ -10,7 +10,7 @@ function Invoke-ModsProtect [string] $ModsPath ) - + try { $directory = (Get-Item -Path $ModsPath -ErrorAction SilentlyContinue) @@ -22,7 +22,7 @@ function Invoke-ModsProtect $userName = $ntAccount.Value $userRights = [Security.AccessControl.FileSystemRights]'Write' $hasWriteAccess = $False - + foreach ($access in $acl.Access) { if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) @@ -31,48 +31,48 @@ function Invoke-ModsProtect break } } - + if ($hasWriteAccess) { # Disable inheritance $acl.SetAccessRuleProtection($True, $True) - + # Remove any existing rules $acl.Access | ForEach-Object -Process { $acl.RemoveAccessRule($_) } - + # SYSTEM Full - S-1-5-18 $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-18')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) # Save the updated ACL $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Administrators Full - S-1-5-32-544 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-544')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Local Users ReadAndExecute - S-1-5-32-545 S-1-5-11 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-32-545')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + # Authenticated Users ReadAndExecute - S-1-5-11 $acl = (Get-Acl -Path $directory.FullName) $userSID = (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-11')) $rule = (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($userSID, 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow')) $acl.SetAccessRule($rule) $null = (Set-Acl -Path $directory.FullName -AclObject $acl) - + return $True } - + return $False } catch diff --git a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 index 3e1082f..f839679 100644 --- a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 @@ -4,30 +4,30 @@ function Invoke-PostUpdateActions { # log Write-ToLog -LogMsg 'Running Post Update actions:' -LogColor 'yellow' - + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ErrorAction SilentlyContinue)) { Write-ToLog -LogMsg '-> Creating SymLink for log file in Intune Management Extension log folder' -LogColor 'yellow' $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue } - + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) { Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + Write-ToLog -LogMsg '-> Checking prerequisites...' -LogColor 'yellow' - + # Check if Visual C++ 2019 or 2022 installed $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' $path = (Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 }) - + # If not installed, install if (!($path)) { @@ -41,7 +41,7 @@ function Invoke-PostUpdateActions { $OSArch = 'x86' } - + Write-ToLog -LogMsg ('-> Downloading VC_redist.{0}.exe...' -f $OSArch) $SourceURL = ('https://aka.ms/vs/17/release/VC_redist.{0}.exe' -f $OSArch) $Installer = ('{0}\VC_redist.{1}.exe' -f $WAUConfig.InstallLocation, $OSArch) @@ -61,13 +61,13 @@ function Invoke-PostUpdateActions { Write-ToLog -LogMsg '-> Prerequisites checked. OK' -LogColor 'green' } - + # Check Package Install Write-ToLog -LogMsg '-> Checking if Winget is installed/up to date' -LogColor 'yellow' $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' } - + # Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 if ([Version]$TestWinGet.Version -ge '2023.808.2243.0') { @@ -80,7 +80,7 @@ function Invoke-PostUpdateActions $WinGetURL = 'https://github.com/microsoft/winget-cli/releases/download/v1.5.2201/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($WinGetURL, ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation)) - + # Install WinGet MSIXBundle try { @@ -92,29 +92,29 @@ function Invoke-PostUpdateActions { Write-ToLog -LogMsg '-> Failed to intall Winget MSIXBundle for App Installer...' -LogColor 'red' } - + # Remove WinGet MSIXBundle Remove-Item -Path ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -Force -Confirm:$False -ErrorAction Continue } - + # Reset Winget Sources $ResolveWingetPath = Resolve-Path -Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object -Property { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } - + if ($ResolveWingetPath) { # If multiple version, pick last one $WingetPath = $ResolveWingetPath[-1].Path & $WingetPath source reset --force - + # log Write-ToLog -LogMsg '-> Winget sources reseted.' -LogColor 'green' } - + # Create WAU Regkey if not present $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' - + if (!(Test-Path -Path $regPath -ErrorAction SilentlyContinue)) { $null = (New-Item -Path $regPath -Force -Confirm:$False -ErrorAction SilentlyContinue) @@ -128,60 +128,60 @@ function Invoke-PostUpdateActions $null = (New-ItemProperty -Path $regPath -Name UninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name QuietUninstallString -Value "powershell.exe -noprofile -executionpolicy bypass -file `"$WorkingDir\WAU-Uninstall.ps1`"" -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - + #log Write-ToLog -LogMsg ('-> {0} created.' -f $regPath) -LogColor 'green' } - + # Fix Notif where WAU_NotificationLevel is not set $regNotif = Get-ItemProperty -Path $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue - + if (!$regNotif) { New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value Full -Force - + # log Write-ToLog -LogMsg "-> Notification level setting was missing. Fixed with 'Full' option." } - + # Set WAU_MaxLogFiles/WAU_MaxLogSize if not set $MaxLogFiles = Get-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue - + if (!$MaxLogFiles) { $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -Value 3 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) $null = (New-ItemProperty -Path $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB).' } - + # Set WAU_ListPath if not set $ListPath = Get-ItemProperty -Path $regPath -Name WAU_ListPath -ErrorAction SilentlyContinue - + if (!$ListPath) { $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> ListPath setting was missing. Fixed with empty string.' } - + # Set WAU_ModsPath if not set $ModsPath = (Get-ItemProperty -Path $regPath -Name WAU_ModsPath -ErrorAction SilentlyContinue) - + if (!$ModsPath) { $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg '-> ModsPath setting was missing. Fixed with empty string.' } - + # Security check Write-ToLog -LogMsg '-> Checking Mods Directory:' -LogColor 'yellow' $Protected = Invoke-ModsProtect ('{0}\mods' -f $WAUConfig.InstallLocation) - + if ($Protected -eq $True) { Write-ToLog -LogMsg '-> The mods directory is now secured!' -LogColor 'green' @@ -194,56 +194,56 @@ function Invoke-PostUpdateActions { Write-ToLog -LogMsg "-> Error: The mods directory couldn't be verified as secured!" -LogColor 'red' } - + # Convert about.xml if exists (old WAU versions) to reg $WAUAboutPath = ('{0}\config\about.xml' -f $WorkingDir) - + if (Test-Path -Path $WAUAboutPath -ErrorAction SilentlyContinue) { [xml]$About = Get-Content -Path $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue $null = (New-ItemProperty -Path $regPath -Name DisplayVersion -Value $About.app.version -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Remove file once converted $null = (Remove-Item -Path $WAUAboutPath -Force -Confirm:$False) - + #log Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUAboutPath) -LogColor 'green' } - + # Convert config.xml if exists (previous WAU versions) to reg $WAUConfigPath = ('{0}\config\config.xml' -f $WorkingDir) - + if (Test-Path -Path $WAUConfigPath -ErrorAction SilentlyContinue) { [xml]$Config = (Get-Content -Path $WAUConfigPath -Encoding UTF8 -ErrorAction SilentlyContinue) - + if ($Config.app.WAUautoupdate -eq 'False') { $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + if ($Config.app.NotificationLevel) { $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $Config.app.NotificationLevel -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + if ($Config.app.UseWAUWhiteList -eq 'True') { $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + if ($Config.app.WAUprerelease -eq 'True') { $null = (New-ItemProperty -Path $regPath -Name WAU_UpdatePrerelease -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + # Remove file once converted $null = (Remove-Item -Path $WAUConfigPath -Force -Confirm:$False) - + # log Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUConfigPath) -LogColor 'green' } - + # Remove old functions / files $FileNames = @( ('{0}\functions\Get-WAUConfig.ps1' -f $WorkingDir), @@ -252,24 +252,24 @@ function Invoke-PostUpdateActions ('{0}\functions\Write-Log.ps1' -f $WorkingDir), ('{0}\Version.txt' -f $WorkingDir) ) - + foreach ($FileName in $FileNames) { if (Test-Path -Path $FileName -ErrorAction SilentlyContinue) { $null = (Remove-Item -Path $FileName -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # log Write-ToLog -LogMsg ('-> {0} removed.' -f $FileName) -LogColor 'green' } } - + # Remove old registry key $RegistryKeys = @( 'VersionMajor', 'VersionMinor' ) - + foreach ($RegistryKey in $RegistryKeys) { if (Get-ItemProperty -Path $regPath -Name $RegistryKey -ErrorAction SilentlyContinue) @@ -277,13 +277,13 @@ function Invoke-PostUpdateActions $null = (Remove-ItemProperty -Path $regPath -Name $RegistryKey -Force -Confirm:$False -ErrorAction SilentlyContinue) } } - + # Reset WAU_UpdatePostActions Value $null = ($WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 0 -Force -Confirm:$False -ErrorAction SilentlyContinue) - + # Get updated WAU Config $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') - + # log Write-ToLog -LogMsg 'Post Update actions finished' -LogColor 'green' } diff --git a/Winget-AutoUpdate/functions/Start-Init.ps1 b/Winget-AutoUpdate/functions/Start-Init.ps1 index c3fb503..9b74de2 100644 --- a/Winget-AutoUpdate/functions/Start-Init.ps1 +++ b/Winget-AutoUpdate/functions/Start-Init.ps1 @@ -4,11 +4,11 @@ function Start-Init { # Config console output encoding [Console]::OutputEncoding = [Text.Encoding]::UTF8 - + # Workaround for ARM64 (Access Denied / Win32 internal Server error) $Script:ProgressPreference = 'SilentlyContinue' $caller = ((Get-ChildItem -Path $MyInvocation.PSCommandPath).Name) - + if ($caller -eq 'Winget-Upgrade.ps1') { # Log Header @@ -21,7 +21,7 @@ function Start-Init { $Script:LogFile = ('{0}\logs\updates.log' -f $WingetUpdatePath) } - + if (!(Test-Path -Path $LogFile -ErrorAction SilentlyContinue)) { # Create file if doesn't exist @@ -48,21 +48,21 @@ function Start-Init $NewAcl.SetAccessRule($fileSystemAccessRule) $null = (Set-Acl -Path $LogFile -AclObject $NewAcl) } - + # Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) { Write-Host -Object "`nCreating SymLink for log file (WAU-updates) in Intune Management Extension log folder" -ForegroundColor Yellow $null = New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue } - + # Check if Intune Management Extension Logs folder and WAU-install.log exists, make symlink if ((Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs" -ErrorAction SilentlyContinue) -and (Test-Path -Path ('{0}\logs\install.log' -f $WorkingDir) -ErrorAction SilentlyContinue) -and !(Test-Path -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ErrorAction SilentlyContinue)) { Write-Host -Object "`nCreating SymLink for log file (WAU-install) in Intune Management Extension log folder" -ForegroundColor Yellow $null = (New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-install.log" -ItemType SymbolicLink -Value ('{0}\logs\install.log' -f $WorkingDir) -Force -ErrorAction SilentlyContinue) } - + if ($caller -eq 'Winget-Upgrade.ps1') { # Log file diff --git a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 index ff3dafb..a5f2c95 100644 --- a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 +++ b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 @@ -25,23 +25,23 @@ function Start-NotifTask [Switch] $UserRun = $false ) - + if (($WAUConfig.WAU_NotificationLevel -eq 'Full') -or ($WAUConfig.WAU_NotificationLevel -eq 'SuccessOnly' -and $MessageType -eq 'Success') -or ($UserRun)) { # XML Toast template creation [xml]$ToastTemplate = New-Object -TypeName system.Xml.XmlDocument $ToastTemplate.LoadXml("") - + # Creation of visual node $XMLvisual = $ToastTemplate.CreateElement('visual') - + # Creation of a binding node $XMLbinding = $ToastTemplate.CreateElement('binding') $null = $XMLvisual.AppendChild($XMLbinding) $XMLbindingAtt1 = ($ToastTemplate.CreateAttribute('template')) $XMLbindingAtt1.Value = 'ToastGeneric' $null = $XMLbinding.Attributes.Append($XMLbindingAtt1) - + $XMLimagepath = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) if (Test-Path -Path $XMLimagepath -ErrorAction SilentlyContinue) { @@ -55,7 +55,7 @@ function Start-NotifTask $XMLimageAtt2.Value = ('{0}\icons\{1}.png' -f $WorkingDir, $MessageType) $null = $XMLimage.Attributes.Append($XMLimageAtt2) } - + if ($Title) { # Creation of a text node @@ -64,7 +64,7 @@ function Start-NotifTask $null = $XMLtitle.AppendChild($XMLtitleText) $null = $XMLbinding.AppendChild($XMLtitle) } - + if ($Message) { # Creation of a text node @@ -73,17 +73,17 @@ function Start-NotifTask $null = $XMLtext.AppendChild($XMLtextText) $null = $XMLbinding.AppendChild($XMLtext) } - + if ($Body) { # Creation of a group node $XMLgroup = $ToastTemplate.CreateElement('group') $null = $XMLbinding.AppendChild($XMLgroup) - + # Creation of a subgroup node $XMLsubgroup = $ToastTemplate.CreateElement('subgroup') $null = $XMLgroup.AppendChild($XMLsubgroup) - + # Creation of a text node $XMLcontent = $ToastTemplate.CreateElement('text') $XMLcontentText = $ToastTemplate.CreateTextNode($Body) @@ -96,10 +96,10 @@ function Start-NotifTask $XMLcontentAtt2.Value = 'true' $null = $XMLcontent.Attributes.Append($XMLcontentAtt2) } - + # Creation of actions node $XMLactions = $ToastTemplate.CreateElement('actions') - + if ($Button1Text) { # Creation of action node @@ -118,7 +118,7 @@ function Start-NotifTask $null = $XMLaction.Attributes.Append($XMLactionAtt3) } } - + if ($ButtonDismiss) { # Creation of action node @@ -134,23 +134,23 @@ function Start-NotifTask $XMLactionAtt3.Value = 'system' $null = $XMLaction.Attributes.Append($XMLactionAtt3) } - + # Creation of tag node $XMLtag = $ToastTemplate.CreateElement('tag') $XMLtagText = $ToastTemplate.CreateTextNode($Balise) $null = $XMLtag.AppendChild($XMLtagText) - + # Add the visual node to the xml $null = $ToastTemplate.LastChild.AppendChild($XMLvisual) $null = $ToastTemplate.LastChild.AppendChild($XMLactions) $null = $ToastTemplate.LastChild.AppendChild($XMLtag) - + if ($OnClickAction) { $null = $ToastTemplate.toast.SetAttribute('activationType', 'Protocol') $null = $ToastTemplate.toast.SetAttribute('launch', $OnClickAction) } - + # if not "Interactive" user, run as system if ($IsSystem) { @@ -160,9 +160,9 @@ function Start-NotifTask { $null = (New-Item -ItemType Directory -Force -Confirm:$false -Path $ToastTemplateLocation) } - + $ToastTemplate.Save(('{0}\notif.xml' -f $ToastTemplateLocation)) - + # Run Notify scheduled task to notify conneted users $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-Notify' -ErrorAction SilentlyContinue | Start-ScheduledTask -ErrorAction SilentlyContinue) } @@ -174,20 +174,20 @@ function Start-NotifTask $null = (Add-Type -AssemblyName Windows.Data) $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] - + # Prepare XML $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New() $ToastXml.LoadXml($ToastTemplate.OuterXml) - + # Specify Launcher App ID $LauncherID = 'Windows.SystemToast.Winget.Notification' - + # Prepare and Create Toast $ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) $ToastMessage.Tag = $ToastTemplate.toast.tag [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) } - + # Wait for notification to display Start-Sleep -Seconds 3 } diff --git a/Winget-AutoUpdate/functions/Test-ListPath.ps1 b/Winget-AutoUpdate/functions/Test-ListPath.ps1 index 86fe8e7..a527ec1 100644 --- a/Winget-AutoUpdate/functions/Test-ListPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ListPath.ps1 @@ -2,7 +2,7 @@ function Test-ListPath { - # URL, UNC or Local Path + # URL, UNC or Local Path [CmdletBinding()] param ( @@ -13,7 +13,7 @@ function Test-ListPath [string] $WingetUpdatePath ) - + if ($UseWhiteList) { $ListType = 'included_apps.txt' @@ -22,28 +22,28 @@ function Test-ListPath { $ListType = 'excluded_apps.txt' } - + # Get local and external list paths $LocalList = -join ($WingetUpdatePath, '\', $ListType) $ExternalList = -join ($ListPath, '\', $ListType) - + # Check if a list exists if (Test-Path -Path $LocalList -ErrorAction SilentlyContinue) { $dateLocal = (Get-Item -Path $LocalList).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + # If path is URL if ($ListPath -like 'http*') { $ExternalList = -join ($ListPath, '/', $ListType) $wc = (New-Object -TypeName System.Net.WebClient) - + try { $null = $wc.OpenRead($ExternalList).Close() $dateExternal = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - + if ($dateExternal -gt $dateLocal) { try @@ -63,7 +63,7 @@ function Test-ListPath try { $content = $wc.DownloadString(('{0}' -f $ExternalList)) - + if ($null -ne $content -and $content -match '\w\.\w') { $wc.DownloadFile($ExternalList, $LocalList) @@ -96,7 +96,7 @@ function Test-ListPath $Script:ReachNoPath = $True return $False } - + if ($dateExternal -gt $dateLocal) { try @@ -115,7 +115,7 @@ function Test-ListPath { $Script:ReachNoPath = $True } - + return $False } } diff --git a/Winget-AutoUpdate/functions/Test-Mods.ps1 b/Winget-AutoUpdate/functions/Test-Mods.ps1 index 598c548..81bf593 100644 --- a/Winget-AutoUpdate/functions/Test-Mods.ps1 +++ b/Winget-AutoUpdate/functions/Test-Mods.ps1 @@ -9,42 +9,42 @@ function Test-Mods [string] $app ) - + $ModsPreInstall = $null $ModsOverride = $null $ModsUpgrade = $null $ModsInstall = $null $ModsInstalled = $null $Mods = ('{0}\mods' -f $WorkingDir) - + if (Test-Path -Path ('{0}\{1}-*' -f $Mods, $app) -ErrorAction SilentlyContinue) { if (Test-Path -Path ('{0}\{1}-preinstall.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsPreInstall = ('{0}\{1}-preinstall.ps1' -f $Mods, $app) } - + if (Test-Path -Path ('{0}\{1}-override.txt' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsOverride = Get-Content -Path ('{0}\{1}-override.txt' -f $Mods, $app) -Raw } - + if (Test-Path -Path ('{0}\{1}-install.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsInstall = ('{0}\{1}-install.ps1' -f $Mods, $app) $ModsUpgrade = ('{0}\{1}-install.ps1' -f $Mods, $app) } - + if (Test-Path -Path ('{0}\{1}-upgrade.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsUpgrade = ('{0}\{1}-upgrade.ps1' -f $Mods, $app) } - + if (Test-Path -Path ('{0}\{1}-installed.ps1' -f $Mods, $app) -ErrorAction SilentlyContinue) { $ModsInstalled = ('{0}\{1}-installed.ps1' -f $Mods, $app) } } - + return $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled } diff --git a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 index 5cdf7dd..6385d84 100644 --- a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 @@ -4,7 +4,7 @@ function Test-ModsPath { # URL, UNC or Local Path # Get local and external Mods paths - + [CmdletBinding()] param ( @@ -17,11 +17,11 @@ function Test-ModsPath ) $LocalMods = -join ($WingetUpdatePath, '\', 'mods') $ExternalMods = $ModsPath - + # Get File Names Locally $InternalModsNames = (Get-ChildItem -Path $LocalMods -Name -Recurse -Include *.ps1, *.txt -ErrorAction SilentlyContinue) $InternalBinsNames = (Get-ChildItem -Path $LocalMods"\bins" -Name -Recurse -Include *.exe -ErrorAction SilentlyContinue) - + # If path is URL if ($ExternalMods -like 'http*') { @@ -35,13 +35,13 @@ function Test-ModsPath catch { $Script:ReachNoPath = $True - + return $False } - + # Check for bins, download if newer. Delete if not external $ExternalBins = ('{0}/bins' -f $ModsPath) - + if ($WebResponse -match 'bins/') { $BinResponse = Invoke-WebRequest -Uri $ExternalBins -UseBasicParsing @@ -51,7 +51,7 @@ function Test-ModsPath $CleanBinLinks = $BinLinks -replace '/.*/', '' # Modify strings to HREF:s $index = 0 - + foreach ($Bin in $CleanBinLinks) { if ($Bin) @@ -60,21 +60,21 @@ function Test-ModsPath } $index++ } - + # Delete Local Bins that don't exist Externally $index = 0 $CleanLinks = $BinLinks -replace '/.*/', '' - + foreach ($Bin in $InternalBinsNames) { if ($CleanLinks -notcontains $Bin) { $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) } - + $index++ } - + $CleanBinLinks = $BinLinks -replace '/.*/', '' $Bin = '' # Loop through all links @@ -87,12 +87,12 @@ function Test-ModsPath $dateLocalBin = '' $null = $wc.OpenRead(('{0}/{1}' -f $ExternalBins, $_)).Close() $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - + if (Test-Path -Path $LocalMods"\bins\"$_) { $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + if ($dateExternalBin -gt $dateLocalBin) { $SaveBin = Join-Path -Path ('{0}\bins' -f $LocalMods) -ChildPath $_ @@ -101,14 +101,14 @@ function Test-ModsPath } } } - + # Collect the external list of href links $ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF # If there's a directory path in the HREF:s, delete it (IIS) $CleanLinks = $ModLinks -replace '/.*/', '' # Modify strings to HREF:s $index = 0 - + foreach ($Mod in $CleanLinks) { if ($Mod) @@ -117,12 +117,12 @@ function Test-ModsPath } $index++ } - + # Delete Local Mods that don't exist Externally $DeletedMods = 0 $index = 0 $CleanLinks = $ModLinks -replace '/.*/', '' - + foreach ($Mod in $InternalModsNames) { if ($CleanLinks -notcontains $Mod) @@ -132,11 +132,11 @@ function Test-ModsPath } $index++ } - + $CleanLinks = $ModLinks -replace '/.*/', '' - + # Loop through all links - + $CleanLinks | ForEach-Object -Process { # Check for .ps1/.txt in listing/HREF:s in an index page pointing to .ps1/.txt if (($_ -like '*.ps1') -or ($_ -like '*.txt')) @@ -147,12 +147,12 @@ function Test-ModsPath $dateLocalMod = '' $null = $wc.OpenRead(('{0}/{1}' -f $ExternalMods, $_)).Close() $dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') - + if (Test-Path -Path $LocalMods"\"$_) { $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $_)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + if ($dateExternalMod -gt $dateLocalMod) { try @@ -185,34 +185,34 @@ function Test-ModsPath Write-ToLog -LogMsg 'Azure Blob Storage set as mod source' Write-ToLog -LogMsg 'Checking AZCopy' Get-AZCopy $WingetUpdatePath - + # Safety check to make sure we really do have azcopy.exe and a Blob URL if ((Test-Path -Path ('{0}\azcopy.exe' -f $WingetUpdatePath) -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) { Write-ToLog -LogMsg 'Syncing Blob storage with local storage' - + $AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync $AzureBlobSASURL $LocalMods --from-to BlobLocal --delete-destination=true $AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine) - + foreach ($_ in $AZCopyOutputLines) { $AZCopySyncAdditionsRegex = [regex]::new('(?<=Number of Copy Transfers Completed:\s+)\d+') $AZCopySyncDeletionsRegex = [regex]::new('(?<=Number of Deletions at Destination:\s+)\d+') $AZCopySyncErrorRegex = [regex]::new('^Cannot perform sync due to error:') - + $AZCopyAdditions = [int]$AZCopySyncAdditionsRegex.Match($_).Value $AZCopyDeletions = [int]$AZCopySyncDeletionsRegex.Match($_).Value - + if ($AZCopyAdditions -ne 0) { $ModsUpdated = $AZCopyAdditions } - + if ($AZCopyDeletions -ne 0) { $DeletedMods = $AZCopyDeletions } - + if ($AZCopySyncErrorRegex.Match($_).Value) { Write-ToLog -LogMsg ('AZCopy Sync Error! {0}' -f $_) @@ -223,18 +223,18 @@ function Test-ModsPath { Write-ToLog -LogMsg "Error 'azcopy.exe' or SAS Token not found!" } - + return $ModsUpdated, $DeletedMods } else { # If path is UNC or local $ExternalBins = ('{0}\bins' -f $ModsPath) - + if (Test-Path -Path $ExternalBins"\*.exe") { $ExternalBinsNames = (Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe) - + # Delete Local Bins that don't exist Externally foreach ($Bin in $InternalBinsNames) { @@ -243,35 +243,35 @@ function Test-ModsPath $null = (Remove-Item -Path $LocalMods\bins\$Bin -Force -Confirm:$False -ErrorAction SilentlyContinue) } } - + # Copy newer external bins foreach ($Bin in $ExternalBinsNames) { $dateExternalBin = '' $dateLocalBin = '' - + if (Test-Path -Path $LocalMods"\bins\"$Bin) { $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + $dateExternalBin = (Get-Item -Path ('{0}\{1}' -f $ExternalBins, $Bin)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') - + if ($dateExternalBin -gt $dateLocalBin) { $null = Copy-Item -Path $ExternalBins\$Bin -Destination $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue } } } - + if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) { # Get File Names Externally $ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt - + # Delete Local Mods that don't exist Externally $DeletedMods = 0 - + foreach ($Mod in $InternalModsNames) { if ($Mod -notin $ExternalModsNames) @@ -280,7 +280,7 @@ function Test-ModsPath $DeletedMods++ } } - + # Copy newer external mods foreach ($Mod in $ExternalModsNames) { @@ -290,9 +290,9 @@ function Test-ModsPath { $dateLocalMod = (Get-Item -Path ('{0}\{1}' -f $LocalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') } - + $dateExternalMod = (Get-Item -Path ('{0}\{1}' -f $ExternalMods, $Mod)).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') - + if ($dateExternalMod -gt $dateLocalMod) { $null = Copy-Item -Path $ExternalMods\$Mod -Destination $LocalMods\$Mod -Force -ErrorAction SilentlyContinue @@ -304,7 +304,7 @@ function Test-ModsPath { $Script:ReachNoPath = $True } - + return $ModsUpdated, $DeletedMods } } diff --git a/Winget-AutoUpdate/functions/Test-Network.ps1 b/Winget-AutoUpdate/functions/Test-Network.ps1 index d0c7eb3..22b3877 100644 --- a/Winget-AutoUpdate/functions/Test-Network.ps1 +++ b/Winget-AutoUpdate/functions/Test-Network.ps1 @@ -3,29 +3,29 @@ function Test-Network { #Init - + $timeout = 0 - + # Test connectivity during 30 min then timeout Write-ToLog -LogMsg 'Checking internet connection...' -LogColor 'Yellow' while ($timeout -lt 1800) { $URLtoTest = 'https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE' $URLcontent = ((Invoke-WebRequest -Uri $URLtoTest -UseBasicParsing).content) - + if ($URLcontent -like '*MIT License*') { Write-ToLog -LogMsg 'Connected !' -LogColor 'Green' - + # Check for metered connection $null = (Add-Type -AssemblyName Windows.Networking) $null = [Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime] $cost = [Windows.Networking.Connectivity.NetworkInformation]::GetInternetConnectionProfile().GetConnectionCost() - + if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne 'Unrestricted')) { Write-ToLog -LogMsg 'Metered connection detected.' -LogColor 'Yellow' - + if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) { Write-ToLog -LogMsg 'WAU is configured to bypass update checking on metered connection' @@ -46,13 +46,13 @@ function Test-Network { Start-Sleep -Seconds 10 $timeout += 10 - + # Send Warning Notif if no connection for 5 min if ($timeout -eq 300) { # Log Write-ToLog -LogMsg "Notify 'No connection' sent." -LogColor 'Yellow' - + # Notif $Title = $NotifLocale.local.outputs.output[0].title $Message = $NotifLocale.local.outputs.output[0].message @@ -62,16 +62,16 @@ function Test-Network } } } - + # Send Timeout Notif if no connection for 30 min Write-ToLog -LogMsg 'Timeout. No internet connection !' -LogColor 'Red' - + # Notif $Title = $NotifLocale.local.outputs.output[1].title $Message = $NotifLocale.local.outputs.output[1].message $MessageType = 'error' $Balise = 'Connection' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise - + return $false } diff --git a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 index e9ea46e..0e371f7 100644 --- a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 +++ b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 @@ -4,10 +4,10 @@ function Test-PendingReboot { $Computer = $env:COMPUTERNAME $PendingReboot = $false - + $HKLM = [UInt32] '0x80000002' $WMI_Reg = [WMIClass] ('\\{0}\root\default:StdRegProv' -f $Computer) - + if ($WMI_Reg) { if (($WMI_Reg.EnumKey($HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\')).sNames -contains 'RebootPending') @@ -18,7 +18,7 @@ function Test-PendingReboot { $PendingReboot = $true } - + # Checking for SCCM namespace $SCCM_Namespace = Get-WmiObject -Namespace ROOT\CCM\ClientSDK -List -ComputerName $Computer -ErrorAction Ignore if ($SCCM_Namespace) @@ -29,6 +29,6 @@ function Test-PendingReboot } } } - + return $PendingReboot } diff --git a/Winget-AutoUpdate/functions/Update-App.ps1 b/Winget-AutoUpdate/functions/Update-App.ps1 index a5549be..d7e0a4c 100644 --- a/Winget-AutoUpdate/functions/Update-App.ps1 +++ b/Winget-AutoUpdate/functions/Update-App.ps1 @@ -13,7 +13,7 @@ function Update-App { $Button1Text = $NotifLocale.local.outputs.output[10].message } - + # Send available update notification Write-ToLog -LogMsg ('Updating {0} from {1} to {2}...' -f $app.Name, $app.Version, $app.AvailableVersion) -LogColor 'Cyan' $Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name) @@ -21,20 +21,20 @@ function Update-App $MessageType = 'info' $Balise = $($app.Name) Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Balise $Balise -Button1Action $ReleaseNoteURL -Button1Text $Button1Text - + # Check if mods exist for preinstall/install/upgrade $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) - + # Winget upgrade Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - + # If PreInstall script exist if ($ModsPreInstall) { Write-ToLog -LogMsg ('Modifications for {0} before upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsPreInstall" } - + # Run Winget Upgrade command if ($ModsOverride) { @@ -46,17 +46,17 @@ function Update-App Write-ToLog -LogMsg ('-> Running: Winget upgrade --id {0} --accept-package-agreements --accept-source-agreements -h' -f $app.Id) & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -FilePath $LogFile -Append } - + if ($ModsUpgrade) { Write-ToLog -LogMsg ('Modifications for {0} during upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsUpgrade" } - + # Check if application updated properly $FailedToUpgrade = $false $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - + if ($ConfirmInstall -ne $true) { # Upgrade failed! @@ -68,10 +68,10 @@ function Update-App $FailedToUpgrade = $true break } - + # If app failed to upgrade, run Install command Write-ToLog -LogMsg ('-> An upgrade for {0} failed, now trying an install instead...' -f $app.Name) -LogColor 'Yellow' - + if ($ModsOverride) { Write-ToLog -LogMsg ('-> Running (overriding default): Winget install --id {0} --accept-package-agreements --accept-source-agreements --force --override {1}' -f $app.Id, $ModsOverride) @@ -82,13 +82,13 @@ function Update-App Write-ToLog -LogMsg ('-> Running: Winget install --id {0} --accept-package-agreements --accept-source-agreements --force -h' -f $app.Id) & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --force -h | Tee-Object -FilePath $LogFile -Append } - + if ($ModsInstall) { Write-ToLog -LogMsg ('Modifications for {0} during install are being applied...' -f $app.Id) -LogColor 'Yellow' & "$ModsInstall" } - + # Check if application installed properly $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) if ($ConfirmInstall -eq $false) @@ -96,7 +96,7 @@ function Update-App $FailedToUpgrade = $true } } - + if ($FailedToUpgrade -eq $false) { if ($ModsInstalled) @@ -105,15 +105,15 @@ function Update-App & "$ModsInstalled" } } - + Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' - + # Notify installation if ($FailedToUpgrade -eq $false) { # Send success updated app notification Write-ToLog -LogMsg ('{0} updated to {1} !' -f $app.Name, $app.AvailableVersion) -LogColor 'Green' - + # Send Notif $Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name) $Message = $NotifLocale.local.outputs.output[3].message -f $($app.AvailableVersion) @@ -126,7 +126,7 @@ function Update-App { # Send failed updated app notification Write-ToLog -LogMsg ('{0} update failed.' -f $app.Name) -LogColor 'Red' - + # Send Notif $Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name) $Message = $NotifLocale.local.outputs.output[4].message diff --git a/Winget-AutoUpdate/functions/Update-WAU.ps1 b/Winget-AutoUpdate/functions/Update-WAU.ps1 index 62f950e..57c6f49 100644 --- a/Winget-AutoUpdate/functions/Update-WAU.ps1 +++ b/Winget-AutoUpdate/functions/Update-WAU.ps1 @@ -4,30 +4,30 @@ function Update-WAU { $OnClickAction = 'https://github.com/Romanitho/Winget-AutoUpdate/releases' $Button1Text = $NotifLocale.local.outputs.output[10].message - + #Send available update notification $Title = $NotifLocale.local.outputs.output[2].title -f 'Winget-AutoUpdate' $Message = $NotifLocale.local.outputs.output[2].message -f $WAUCurrentVersion, $WAUAvailableVersion $MessageType = 'info' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - + # Run WAU update try { # Force to create a zip file $ZipFile = ('{0}\WAU_update.zip' -f $WorkingDir) $null = New-Item -Path $ZipFile -ItemType File -Force - + # Download the zip Write-ToLog -LogMsg ('Downloading the GitHub Repository version {0}' -f $WAUAvailableVersion) -LogColor 'Cyan' $null = (Invoke-RestMethod -Uri ('https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v{0}/WAU.zip' -f ($WAUAvailableVersion)) -OutFile $ZipFile) - + # Extract Zip File Write-ToLog -LogMsg 'Unzipping the WAU Update package' -LogColor 'Cyan' $location = ('{0}\WAU_update' -f $WorkingDir) $null = (Expand-Archive -Path $ZipFile -DestinationPath $location -Force) $null = (Get-ChildItem -Path $location -Recurse | Unblock-File -ErrorAction SilentlyContinue) - + # Update scritps Write-ToLog -LogMsg 'Updating WAU...' -LogColor 'Yellow' $TempPath = (Resolve-Path -Path ('{0}\Winget-AutoUpdate\' -f $location) -ErrorAction SilentlyContinue)[0].Path @@ -35,31 +35,31 @@ function Update-WAU { $null = (Copy-Item -Path ('{0}\*' -f $TempPath) -Destination ('{0}\' -f $WorkingDir) -Exclude 'icons' -Recurse -Force -Confirm:$false) } - + # Remove update zip file and update temp folder Write-ToLog -LogMsg 'Done. Cleaning temp files...' -LogColor 'Cyan' $null = (Remove-Item -Path $ZipFile -Force -Confirm:$false -ErrorAction SilentlyContinue) $null = (Remove-Item -Path $location -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue) - + # Set new version to registry $WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force $WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Major -Force $WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion.Replace('-', '.')).Minor -Force - + # Set Post Update actions to 1 $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force - + # Send success Notif Write-ToLog -LogMsg 'WAU Update completed.' -LogColor 'Green' $Title = $NotifLocale.local.outputs.output[3].title -f 'Winget-AutoUpdate' $Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion $MessageType = 'success' Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text - + # Rerun with newer version Write-ToLog -LogMsg 'Re-run WAU' Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" - + exit } catch diff --git a/Winget-AutoUpdate/functions/Write-ToLog.ps1 b/Winget-AutoUpdate/functions/Write-ToLog.ps1 index 6482edd..772c437 100644 --- a/Winget-AutoUpdate/functions/Write-ToLog.ps1 +++ b/Winget-AutoUpdate/functions/Write-ToLog.ps1 @@ -11,12 +11,12 @@ function Write-ToLog [string] $LogColor = 'White' ) - + $Log = ('{0} - {1}' -f (Get-Date -UFormat '%T'), $LogMsg) - + #Echo log $Log | Write-Host -ForegroundColor $LogColor - + #Write log to file $Log | Out-File -FilePath $LogFile -Append -Force -Confirm:$false } From 3978edd9d21f9be9b683649c4e20192eaf5ea2eb Mon Sep 17 00:00:00 2001 From: Joerg Hochwald Date: Fri, 15 Sep 2023 16:55:22 +0200 Subject: [PATCH 4/4] Removed the bad Assemblies my fault :( --- Winget-AutoUpdate/functions/Start-NotifTask.ps1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 index a5f2c95..4bb561f 100644 --- a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 +++ b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 @@ -170,8 +170,6 @@ function Start-NotifTask { #else, run as connected user # Load Assemblies - $null = (Add-Type -AssemblyName Windows.UI) - $null = (Add-Type -AssemblyName Windows.Data) $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]