diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index dfea1a2..6ab9df9 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -1,738 +1,611 @@ <# - .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 ( - [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( + [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 ) <# FUNCTIONS #> -function Install-Prerequisites -{ - Write-Host -Object "`nChecking prerequisites..." -ForegroundColor Yellow +function Install-Prerequisites { - #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 - } + Write-Host "`nChecking prerequisites..." -ForegroundColor Yellow - #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) - { + #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) { $InstallApp = 1 - } - else - { - $InstallApp = 0 - } - } - #Install if approved - if ($InstallApp -eq 1) - { - try - { - if ((Get-CimInstance Win32_OperatingSystem).OSArchitecture -like '*64*') - { - $OSArch = 'x64' + } + 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 - { - $OSArch = 'x86' + else { + $InstallApp = 0 } - 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 - } + } + #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 + } } -function Install-WinGet -{ - Write-Host -Object "`nChecking if Winget is installed" -ForegroundColor Yellow +function Install-WinGet { - #Check Package Install - $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object -FilterScript { - $_.DisplayName -eq 'Microsoft.DesktopAppInstaller' - } + Write-Host "`nChecking if Winget is installed" -ForegroundColor Yellow - #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:' + #Check Package Install + $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" } - #Check if $WingetUpdatePath exist - if (!(Test-Path $WingetUpdatePath)) - { - $null = New-Item -ItemType Directory -Force -Path $WingetUpdatePath - } + #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 + If ([Version]$TestWinGet.Version -ge "2023.808.2243.0") { - #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 - } + Write-Host "Winget is Installed" -ForegroundColor Green - 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 - } + } + Else { - #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") + Write-Host "-> Winget is not installed:" - #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 - } + #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 + + } - #Remove WinGet MSIXBundle - Remove-Item -Path "$WingetUpdatePath\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue - } } -function Install-WingetAutoUpdate -{ - Write-Host -Object "`nInstalling WAU..." -ForegroundColor Yellow +function Install-WingetAutoUpdate { - 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 + Write-Host "`nInstalling WAU..." -ForegroundColor Yellow - #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 + 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 } - else - { - if (!$ListPath) - { - $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue - } + else { + #Keep critical files + Get-ChildItem -Path $WingetUpdatePath -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force } - } - 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 + } + Copy-Item -Path "$PSScriptRoot\Winget-AutoUpdate\*" -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 + } + } } - else - { - if (!$ListPath) - { - $null = New-Item -Path $WingetUpdatePath -Name 'included_apps.txt' -ItemType 'file' -ErrorAction SilentlyContinue - } + 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 -Path "$WingetUpdatePath\excluded_apps.txt")) - { - Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue - } - } + } + 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 -Object 'WAU Installation failed! Run me with admin rights' -ForegroundColor Red - Start-Sleep -Seconds 1 - return $false - } + #Run Winget ? + Start-WingetAutoUpdate + } + catch { + Write-host "WAU Installation failed! Run me with admin rights" -ForegroundColor Red + Start-sleep 1 + return $False + } } -function Uninstall-WingetAutoUpdate -{ - Write-Host -Object "`nUninstalling WAU..." -ForegroundColor Yellow +function Uninstall-WingetAutoUpdate { - try - { - #Get registry install location - $InstallLocation = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\' -Name InstallLocation + Write-Host "`nUninstalling WAU..." -ForegroundColor Yellow - #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 + 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 + } } - 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 { + #Keep critical files + Get-ChildItem -Path $InstallLocation -Exclude *.txt, mods, logs | Remove-Item -Recurse -Force } - } - 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 + 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 -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: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:Public}\Desktop\WAU - Check for updated Apps.lnk")) - { - $null = Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -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 + } - 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 - } + 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 + } } -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) - { +function Start-WingetAutoUpdate { + #If -DoNotUpdate is true, skip. + if (!($DoNotUpdate)) { + #If -Silent, run Winget-AutoUpdate now + if ($Silent) { $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 + } + #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 } - } - catch - { - Write-Host -Object 'Failed to run Winget-AutoUpdate...' -ForegroundColor Red - } - } - } - else - { - Write-Host -Object 'Skip running Winget-AutoUpdate' - } + 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" + } } -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() +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() } <# APP INFO #> -$WAUVersion = Get-Content -Path "$PSScriptRoot\Winget-AutoUpdate\Version.txt" -ErrorAction SilentlyContinue +$WAUVersion = Get-Content "$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 -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 - } +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 + } } -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" +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" -if (!$Uninstall) -{ - Write-Host -Object "Installing WAU to $WingetUpdatePath\" - Install-Prerequisites - Install-WinGet - Install-WingetAutoUpdate +if (!$Uninstall) { + Write-host "Installing WAU to $WingetUpdatePath\" + Install-Prerequisites + Install-WinGet + Install-WingetAutoUpdate } -else -{ - Write-Host -Object 'Uninstalling WAU...' - Uninstall-WingetAutoUpdate +else { + Write-Host "Uninstalling WAU..." + Uninstall-WingetAutoUpdate } -Remove-Item -Path "$WingetUpdatePath\Version.txt" -Force -Write-Host -Object "`nEnd of process." -ForegroundColor Cyan -Start-Sleep -Seconds 3 +Remove-Item "$WingetUpdatePath\Version.txt" -Force +Write-host "`nEnd of process." -ForegroundColor Cyan +Start-Sleep 3 diff --git a/Winget-AutoUpdate/User-Run.ps1 b/Winget-AutoUpdate/User-Run.ps1 index d2c8d6b..176fb26 100644 --- a/Winget-AutoUpdate/User-Run.ps1 +++ b/Winget-AutoUpdate/User-Run.ps1 @@ -1,36 +1,32 @@ <# - .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 ( - [Switch] - $Logs = $False, - [Switch] - $Help = $False +param( + [Parameter(Mandatory = $False)] [Switch] $Logs = $false, + [Parameter(Mandatory = $False)] [Switch] $Help = $false ) -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 - } +function Test-WAUisRunning { + If (((Get-ScheduledTask -TaskName 'Winget-AutoUpdate').State -eq 'Running') -or ((Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext').State -eq 'Running')) { + Return $True + } } <# MAIN #> @@ -46,72 +42,61 @@ $Script:WorkingDir = $PSScriptRoot Get-NotifLocale #Set common variables -$OnClickAction = ('{0}\logs\updates.log' -f $WorkingDir) +$OnClickAction = "$WorkingDir\logs\updates.log" $Button1Text = $NotifLocale.local.outputs.output[11].message -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 - } +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 + } } -elseif ($Help) -{ - Start-Process -FilePath 'https://github.com/Romanitho/Winget-AutoUpdate' +elseif ($Help) { + Start-Process "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 -Seconds 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 3 + } - # 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 - } + #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 + } } diff --git a/Winget-AutoUpdate/WAU-Uninstall.ps1 b/Winget-AutoUpdate/WAU-Uninstall.ps1 index 32e4eab..ff10d8d 100644 --- a/Winget-AutoUpdate/WAU-Uninstall.ps1 +++ b/Winget-AutoUpdate/WAU-Uninstall.ps1 @@ -1,97 +1,85 @@ <# - .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 ( - [Switch] - $NoClean = $false +param( + [Parameter(Mandatory = $False)] [Switch] $NoClean = $false ) -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" +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" -try -{ - Write-Host -Object 'Uninstalling WAU...' -ForegroundColor Yellow +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 - # 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)) { - # 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 (!$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 + } - 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 -Object 'Uninstallation succeeded!' -ForegroundColor Green - } - else - { - Write-Host -Object ('{0} not found! Uninstallation failed!' -f $InstallLocation) -ForegroundColor Red - } + Write-host "Uninstallation succeeded!" -ForegroundColor Green + } + else { + Write-host "$InstallLocation not found! Uninstallation failed!" -ForegroundColor Red + } } -catch -{ - Write-Host -Object "`nUninstallation failed! Run as admin ?" -ForegroundColor Red +catch { + Write-host "`nUninstallation failed! Run as admin ?" -ForegroundColor Red } -Start-Sleep -Seconds 2 +Start-sleep 2 diff --git a/Winget-AutoUpdate/Winget-Notify.ps1 b/Winget-AutoUpdate/Winget-Notify.ps1 index 4164a6f..de22ef7 100644 --- a/Winget-AutoUpdate/Winget-Notify.ps1 +++ b/Winget-AutoUpdate/Winget-Notify.ps1 @@ -1,29 +1,24 @@ -# 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 -Path "$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 "$WAUinstalledPath\config\notif.xml" -Encoding UTF8 -ErrorAction SilentlyContinue +if (!($NotifConf)) { + break } -# Load Assemblies -$null = (Add-Type -AssemblyName Windows.Data) -$null = (Add-Type -AssemblyName Windows.UI) +#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 -$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 +#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 72af605..25cfbc7 100644 --- a/Winget-AutoUpdate/Winget-Upgrade.ps1 +++ b/Winget-AutoUpdate/Winget-Upgrade.ps1 @@ -1,419 +1,345 @@ <# 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 = [Security.Principal.WindowsIdentity]::GetCurrent().IsSystem +#Check if running account is system or interactive logon +$Script:IsSystem = [System.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' +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' - } - } + #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 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 + } + else { + [int32] $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 - } + # Maximum size of log file. + $MaxLogSize = $WAUConfig.WAU_MaxLogSize + if (!$MaxLogSize) { + [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB + } + else { + [int64] $MaxLogSize = $MaxLogSize + } - #LogRotation if System - $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize - if ($LogRotate -eq $False) - { - Write-ToLog 'An Exception occured during Log Rotation...' - } + #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 + #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 $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) -{ - #Check if Winget is installed and get Winget cmd - $TestWinget = Get-WingetCmd +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 + 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 is up to date.' 'Green' + 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" + } } - } - #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 - } - } + #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 } - } - #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 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 "$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" + } + 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 + Exit 1 + } + } + } } - else - { - $NewMods, $DeletedMods = Test-ModsPath $ModsPathClean $WAUConfig.InstallLocation.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 "$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" + } } - if ($ReachNoPath) - { - Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." 'Red' - $Script:ReachNoPath = $False + + #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" + & "$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`"" + Exit + } } - if ($NewMods -gt 0) - { - Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Yellow' + + } + + 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 "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force + Exit 1 + } + $toUpdate = $toUpdate.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' - } + 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 + Exit 1 + } + $toSkip = $toSkip.Data } - if ($DeletedMods -gt 0) - { - Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(' ', '\'))\mods" 'Red' + } + + #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 } - } - #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 + #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 ($($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 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" + } + } } - $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 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" + } + } } - $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 -gt 0) { + Write-ToLog "$InstallOK apps updated ! No more update." "Green" } - } - #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' - } + } + + 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) { - if ($InstallOK -gt 0) - { - Write-ToLog "$InstallOK apps updated ! No more update." 'Green' - } - } + #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 - 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 + #Run user context scheduled task + Write-ToLog "Starting WAU in User context" + Start-ScheduledTask $UserScheduledTask.TaskName -ErrorAction SilentlyContinue + Exit 0 + } + elseif (!$UserScheduledTask) { + Write-ToLog "User context execution not installed..." + } } - 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 - } + } + } + 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" + Exit 1 + } } #End -Write-ToLog 'End of process!' 'Cyan' -Start-Sleep -Seconds 3 +Write-ToLog "End of process!" "Cyan" +Start-Sleep 3 diff --git a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 index e0dcb72..44bb7e4 100644 --- a/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 +++ b/Winget-AutoUpdate/functions/Add-ScopeMachine.ps1 @@ -1,40 +1,20 @@ -# Function to configure the prefered scope option as Machine -function Add-ScopeMachine -{ - [CmdletBinding()] - param - ( - [string] - $SettingsPath - ) +#Function to configure the prefered scope option as Machine +function Add-ScopeMachine ($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 0ab9e23..98b6e77 100644 --- a/Winget-AutoUpdate/functions/Add-Shortcut.ps1 +++ b/Winget-AutoUpdate/functions/Add-Shortcut.ps1 @@ -1,26 +1,10 @@ -# 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() +#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() } diff --git a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 index db7100c..e96b66d 100644 --- a/Winget-AutoUpdate/functions/Confirm-Installation.ps1 +++ b/Winget-AutoUpdate/functions/Confirm-Installation.ps1 @@ -1,41 +1,27 @@ -function Confirm-Installation -{ - # Set json export file +Function Confirm-Installation ($AppName, $AppVer){ - [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 - } -} + if ($Apps){ + return $true + } + else{ + return $false + } +} \ No newline at end of file diff --git a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 index eddcec8..e6f7d54 100644 --- a/Winget-AutoUpdate/functions/Get-AZCopy.ps1 +++ b/Winget-AutoUpdate/functions/Get-AZCopy.ps1 @@ -1,59 +1,50 @@ -# 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 -{ - [CmdletBinding()] - param - ( - [string] - $WingetUpdatePath - ) +Function Get-AZCopy ($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 ('{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 (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 (([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)) + 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 ($AZCopyPathSearch -is [array]) - { - $AZCopyEXEPath = $AZCopyPathSearch[$AZCopyPathSearch.Length - 1] - } - else - { - $AZCopyEXEPath = $AZCopyPathSearch - } + Expand-archive -Path "$WingetUpdatePath\azcopyv10.zip" -Destinationpath "$WingetUpdatePath" -Force - 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) - } -} + $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 diff --git a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 index 57b50e4..747a818 100644 --- a/Winget-AutoUpdate/functions/Get-AppInfo.ps1 +++ b/Winget-AutoUpdate/functions/Get-AppInfo.ps1 @@ -1,19 +1,12 @@ -# Get the winget App Information +#Get the winget App Information -function Get-AppInfo -{ - # Get AppID Info - [CmdletBinding()] - param - ( - [string] - $AppID - ) +Function Get-AppInfo ($AppID) { + #Get AppID Info + $String = & $winget show $AppID --accept-source-agreements -s winget | Out-String - $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 + #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 3ac689a..0212e5c 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 -{ - 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\' +function Get-ExcludedApps { - $ValueNames = (Get-Item -Path 'HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList').Property + if ($GPOList) { - foreach ($ValueName in $ValueNames) - { - $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) - [PSCustomObject]@{ - Value = $ValueName - Data = $AppIDs.Trim() + 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() + } } - } - } - 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 - } - } + } + return $AppIDs + + } + elseif (Test-Path "$WorkingDir\excluded_apps.txt") { + + return (Get-Content -Path "$WorkingDir\excluded_apps.txt").Trim() | Where-Object { $_.length -gt 0 } + + } + } diff --git a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 index 476944c..ae2a8ad 100644 --- a/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-IncludedApps.ps1 @@ -1,30 +1,31 @@ -# Function to get the allow List apps +#Function to get the allow List apps -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 +function Get-IncludedApps { - foreach ($ValueName in $ValueNames) - { - $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) - [PSCustomObject]@{ - Value = $ValueName - Data = $AppIDs.Trim() + 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() + } } - } - } - 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 - } - } + } + return $AppIDs + + } + elseif (Test-Path "$WorkingDir\included_apps.txt") { + + return (Get-Content -Path "$WorkingDir\included_apps.txt").Trim() | Where-Object { $_.length -gt 0 } + + } + } diff --git a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 index 46147d6..f0bd3a2 100644 --- a/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 +++ b/Winget-AutoUpdate/functions/Get-NotifLocale.ps1 @@ -1,31 +1,28 @@ #Function to get the locale file for notifications -function Get-NotifLocale -{ +Function Get-NotifLocale { - # Get OS locale - $OSLocale = (Get-UICulture).Parent + #Get OS locale + $OSLocale = (Get-UICulture).Parent - # Test if OS locale notif file exists - $TestOSLocalPath = ('{0}\locale\{1}.xml' -f $WorkingDir, $OSLocale.Name) + #Test if OS locale notif file exists + $TestOSLocalPath = "$WorkingDir\locale\$($OSLocale.Name).xml" - # 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) - } + #Set OS Local if file exists + if (Test-Path $TestOSLocalPath) { + $LocaleDisplayName = $OSLocale.DisplayName + $LocaleFile = $TestOSLocalPath + } + #Set English if file doesn't exist + else { + $LocaleDisplayName = "English" + $LocaleFile = "$WorkingDir\locale\en.xml" + } - # Get locale XML file content - [xml]$Script:NotifLocale = (Get-Content -Path $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue) + #Get locale XML file content + [xml]$Script:NotifLocale = Get-Content $LocaleFile -Encoding UTF8 -ErrorAction SilentlyContinue - # Rerturn langague display name - return $LocaleDisplayName + #Rerturn langague display name + Return $LocaleDisplayName } diff --git a/Winget-AutoUpdate/functions/Get-Policies.ps1 b/Winget-AutoUpdate/functions/Get-Policies.ps1 index fd293fb..0200341 100644 --- a/Winget-AutoUpdate/functions/Get-Policies.ps1 +++ b/Winget-AutoUpdate/functions/Get-Policies.ps1 @@ -1,471 +1,364 @@ -# 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))) - { - $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 - } +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++ } - $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 - } + 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++ - } - - 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_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) - - 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_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++ } - 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) - } + 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++ } - $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 - } + elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) { + New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -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_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++ } - $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) + 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++ } - 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) + elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) { + Remove-ItemProperty $regPath -Name WAU_ListPath -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_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++ } - $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 - $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) + 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++ } - else - { - $null = (Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue) + elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne "Full") { + New-ItemProperty $regPath -Name WAU_NotificationLevel -Value "Full" -Force | Out-Null + $ChangedSettings++ } - $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 ($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)...' + 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++ } - else - { - $null = (Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force -Confirm:$false) + 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++ } - $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 ($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 ($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_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) - } + 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" + } - 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...' + 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++ } - else - { - $null = (Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force -Confirm:$false) + 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 + + 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" + } + + $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 + $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++ } - $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_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_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_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++ - } + 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 - # Get WAU Configurations after Policies change - $Script:WAUConfig = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate') - } - } + # 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++ + } - return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings + 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 } diff --git a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 index 08e0f93..c2241ab 100644 --- a/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 +++ b/Winget-AutoUpdate/functions/Get-WAUAvailableVersion.ps1 @@ -1,22 +1,25 @@ -# Function to get the latest WAU available version on Github +#Function to get the latest WAU available version on Github -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' +function Get-WAUAvailableVersion { - # 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' - } + #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", "") - # 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 03fe939..e0be4e4 100644 --- a/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetCmd.ps1 @@ -1,53 +1,41 @@ -# 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 -{ +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') - }) + #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') } - if ($ResolveWingetPath) - { - # If multiple version, pick last one - $WingetPath = $ResolveWingetPath[-1].Path - } + 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 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" + } + }else{ + #Get Winget Location in User context + $WingetCmd = Get-Command winget.exe -ErrorAction SilentlyContinue + if ($WingetCmd) { + $Script:Winget = $WingetCmd.Source + } + } - if ($WingetCmd) - { - $Script:Winget = $WingetCmd.Source - } - } + If(!($Script:Winget)){ + Write-ToLog "Winget not installed or detected !" "Red" + return $false + } - if (!($Script:Winget)) - { - Write-ToLog 'Winget not installed or detected !' 'Red' + #Run winget to list apps and accept source agrements (necessary on first run) + & $Winget list --accept-source-agreements -s winget | Out-Null - return $false - } + #Log Winget installed version + $WingetVer = & $Winget --version + Write-ToLog "Winget Version: $WingetVer" - # 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 + return $true } diff --git a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 index c2d1b9e..59eaffa 100644 --- a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 @@ -1,92 +1,76 @@ -# 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 -FilterScript { - $_ - } + #Split winget output to lines + $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object { $_ } - # 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 = @() + # 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 - for ($i = $fl + 2; $i -lt $lines.Length; $i++) - { - $line = $lines[$i] -replace '[\u2026]', ' ' #Fix "..." in long names + #Get header titles [without remove seperator] + $index = $lines[$fl] -split '(?<=\s)(?!\s)' - if ($line.StartsWith('-----')) - { - # Get header line - $fl = $i - 1 + # 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 + } + } - # Get header titles [without remove seperator] - $index = $lines[$fl] -split '(?<=\s)(?!\s)' + #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 } + } - # 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 - } + return $upgradeList | Sort-Object { Get-Random } } diff --git a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 index e7df94b..8f653ea 100644 --- a/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetSystemApps.ps1 @@ -1,17 +1,18 @@ -function Get-WingetSystemApps -{ - # Json File, where to export system installed apps - $jsonFile = ('{0}\winget_system_apps.txt' -f $WorkingDir) +function Get-WingetSystemApps { - # Get list of installed Winget apps to json file - $null = (& $Winget export -o $jsonFile --accept-source-agreements -s winget) + #Json File, where to export system installed apps + $jsonFile = "$WorkingDir\winget_system_apps.txt" - # Convert json file to txt file with app ids - $InstalledApps = (Get-Content -Path $jsonFile | ConvertFrom-Json) + #Get list of installed Winget apps to json file + & $Winget export -o $jsonFile --accept-source-agreements -s winget | Out-Null - # Save app list - $null = (Set-Content -Value $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile -Force -Confirm:$False -ErrorAction SilentlyContinue) + #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 - # 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 35d17c8..82edf17 100644 --- a/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-LogRotation.ps1 @@ -1,118 +1,95 @@ -# Function to rotate the logs +#Function to rotate the logs -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 - ) +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 + #> - 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 - # 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) + # 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 } - 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 - } + } + } + catch { + Return $False + } } diff --git a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 index 2e8fad2..1b56707 100644 --- a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 @@ -1,82 +1,65 @@ -# 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 -{ - [CmdletBinding()] - param - ( - [string] - $ModsPath - ) +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" - 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 + $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) + 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 - # Remove any existing rules - $acl.Access | ForEach-Object -Process { - $acl.RemoveAccessRule($_) - } + #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 - # 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) + #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 - # 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) + #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 - # 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' - } -} + return $True + } + return $False + } + catch { + return "Error" + } +} \ No newline at end of file diff --git a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 index 3631660..b001bd8 100644 --- a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 @@ -1,246 +1,198 @@ -# Function to make actions after WAU update +#Function to make actions after WAU update -function Invoke-PostUpdateActions -{ - # log - Write-ToLog -LogMsg 'Running Post Update actions:' -LogColor 'yellow' +function Invoke-PostUpdateActions { - # 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 - } + #log + Write-ToLog "Running Post Update actions:" "yellow" - # 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 -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 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 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) + } - # 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)) + #Check Package Install + Write-ToLog "-> Checking if Winget is installed/up to date" "yellow" + $TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" } - # 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' - } + #Current: v1.5.2201 = 1.20.2201.0 = 2023.808.2243.0 + If ([Version]$TestWinGet.Version -ge "2023.808.2243.0") { - # Remove WinGet MSIXBundle - Remove-Item -Path ('{0}\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle' -f $WAUConfig.InstallLocation) -Force -Confirm:$False -ErrorAction Continue - } + Write-ToLog "-> WinGet is Installed/up to date" "green" - # 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') - } + } + Else { - if ($ResolveWingetPath) - { - # If multiple version, pick last one - $WingetPath = $ResolveWingetPath[-1].Path - & $WingetPath source reset --force + #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") - # log - Write-ToLog -LogMsg '-> Winget sources reseted.' -LogColor 'green' - } + #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" + } - # Create WAU Regkey if not present - $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate' + #Remove WinGet MSIXBundle + Remove-Item -Path "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue - 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) + } - #log - Write-ToLog -LogMsg ('-> {0} created.' -f $regPath) -LogColor 'green' - } + #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 - # Fix Notif where WAU_NotificationLevel is not set - $regNotif = Get-ItemProperty -Path $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue + #log + Write-ToLog "-> Winget sources reseted." "green" + } - if (!$regNotif) - { - New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value Full -Force + #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 - # log - Write-ToLog -LogMsg "-> Notification level setting was missing. Fixed with 'Full' option." - } + #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 - # Set WAU_MaxLogFiles/WAU_MaxLogSize if not set - $MaxLogFiles = Get-ItemProperty -Path $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue + #log + Write-ToLog "-> Notification level setting was missing. Fixed with 'Full' option." + } - 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) + #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 - # log - Write-ToLog -LogMsg '-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB).' - } + #log + Write-ToLog "-> 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 + #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 - if (!$ListPath) - { - $null = (New-ItemProperty -Path $regPath -Name WAU_ListPath -Force -Confirm:$False -ErrorAction SilentlyContinue) + #log + Write-ToLog "-> ListPath setting was missing. Fixed with empty string." + } - # log - Write-ToLog -LogMsg '-> ListPath setting was missing. Fixed with empty string.' - } + #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 - # Set WAU_ModsPath if not set - $ModsPath = (Get-ItemProperty -Path $regPath -Name WAU_ModsPath -ErrorAction SilentlyContinue) + #log + Write-ToLog "-> ModsPath setting was missing. Fixed with empty string." + } - if (!$ModsPath) - { - $null = (New-ItemProperty -Path $regPath -Name WAU_ModsPath -Force -Confirm:$False -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" + } - # log - Write-ToLog -LogMsg '-> ModsPath setting was missing. Fixed with empty string.' - } + #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 - # Security check - Write-ToLog -LogMsg '-> Checking Mods Directory:' -LogColor 'yellow' - $Protected = Invoke-ModsProtect ('{0}\mods' -f $WAUConfig.InstallLocation) + #Remove file once converted + Remove-Item $WAUAboutPath -Force -Confirm:$false - 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' - } + #log + Write-ToLog "-> $WAUAboutPath converted." "green" + } - # Convert about.xml if exists (old WAU versions) to reg - $WAUAboutPath = ('{0}\config\about.xml' -f $WorkingDir) + #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 } - 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 + Remove-Item $WAUConfigPath -Force -Confirm:$false - # Remove file once converted - $null = (Remove-Item -Path $WAUAboutPath -Force -Confirm:$False) + #log + Write-ToLog "-> $WAUConfigPath converted." "green" + } - #log - Write-ToLog -LogMsg ('-> {0} converted.' -f $WAUAboutPath) -LogColor 'green' - } + #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 - # Convert config.xml if exists (previous WAU versions) to reg - $WAUConfigPath = ('{0}\config\config.xml' -f $WorkingDir) + #log + Write-ToLog "-> $FileName removed." "green" + } + } - if (Test-Path -Path $WAUConfigPath -ErrorAction SilentlyContinue) - { - [xml]$Config = (Get-Content -Path $WAUConfigPath -Encoding UTF8 -ErrorAction SilentlyContinue) + #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 ($Config.app.WAUautoupdate -eq 'False') - { - $null = (New-ItemProperty -Path $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force -Confirm:$False -ErrorAction SilentlyContinue) - } + #Reset WAU_UpdatePostActions Value + $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 0 -Force - if ($Config.app.NotificationLevel) - { - $null = (New-ItemProperty -Path $regPath -Name WAU_NotificationLevel -Value $Config.app.NotificationLevel -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.UseWAUWhiteList -eq 'True') - { - $null = (New-ItemProperty -Path $regPath -Name WAU_UseWhiteList -Value 1 -PropertyType DWord -Force -Confirm:$False -ErrorAction SilentlyContinue) - } + #log + Write-ToLog "Post Update actions finished" "green" - 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 9b74de2..b937ceb 100644 --- a/Winget-AutoUpdate/functions/Start-Init.ps1 +++ b/Winget-AutoUpdate/functions/Start-Init.ps1 @@ -1,71 +1,65 @@ # Initialisation -function Start-Init -{ - # Config console output encoding - [Console]::OutputEncoding = [Text.Encoding]::UTF8 +function Start-Init { - # Workaround for ARM64 (Access Denied / Win32 internal Server error) - $Script:ProgressPreference = 'SilentlyContinue' - $caller = ((Get-ChildItem -Path $MyInvocation.PSCommandPath).Name) + #Config console output encoding + [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 - 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) - } + # Workaround for ARM64 (Access Denied / Win32 internal Server error) + $Script:ProgressPreference = 'SilentlyContinue' - 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) - } + $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" + } - # 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 - } + 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-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) - } + #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 + } - 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 4bb561f..6ffae41 100644 --- a/Winget-AutoUpdate/functions/Start-NotifTask.ps1 +++ b/Winget-AutoUpdate/functions/Start-NotifTask.ps1 @@ -1,192 +1,175 @@ -# Function to send the notifications to user +#Function to send the notifications to user -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 - ) +function Start-NotifTask { - 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("") + 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 + ) - # Creation of visual node - $XMLvisual = $ToastTemplate.CreateElement('visual') + if (($WAUConfig.WAU_NotificationLevel -eq "Full") -or ($WAUConfig.WAU_NotificationLevel -eq "SuccessOnly" -and $MessageType -eq "Success") -or ($UserRun)) { - # 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) + # XML Toast template creation + [xml]$ToastTemplate = New-Object system.Xml.XmlDocument + $ToastTemplate.LoadXml("") - $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 visual node + $XMLvisual = $ToastTemplate.CreateElement("visual") - if ($Title) - { - # Creation of a text node - $XMLtitle = $ToastTemplate.CreateElement('text') - $XMLtitleText = $ToastTemplate.CreateTextNode($Title) - $null = $XMLtitle.AppendChild($XMLtitleText) - $null = $XMLbinding.AppendChild($XMLtitle) - } + # 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 ($Message) - { - # Creation of a text node - $XMLtext = $ToastTemplate.CreateElement('text') - $XMLtextText = $ToastTemplate.CreateTextNode($Message) - $null = $XMLtext.AppendChild($XMLtextText) - $null = $XMLbinding.AppendChild($XMLtext) - } + $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 ($Body) - { - # Creation of a group node - $XMLgroup = $ToastTemplate.CreateElement('group') - $null = $XMLbinding.AppendChild($XMLgroup) + 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 + } - # Creation of a subgroup node - $XMLsubgroup = $ToastTemplate.CreateElement('subgroup') - $null = $XMLgroup.AppendChild($XMLsubgroup) + 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 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) - } + if ($Body) { + # Creation of a group node + $XMLgroup = $ToastTemplate.CreateElement("group") + $XMLbinding.AppendChild($XMLgroup) | Out-Null - # Creation of actions node - $XMLactions = $ToastTemplate.CreateElement('actions') + # Creation of a subgroup node + $XMLsubgroup = $ToastTemplate.CreateElement("subgroup") + $XMLgroup.AppendChild($XMLsubgroup) | 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 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 ($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) - } + # Creation of actions node + $XMLactions = $ToastTemplate.CreateElement("actions") - # Creation of tag node - $XMLtag = $ToastTemplate.CreateElement('tag') - $XMLtagText = $ToastTemplate.CreateTextNode($Balise) - $null = $XMLtag.AppendChild($XMLtagText) + 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 + } + } - # Add the visual node to the xml - $null = $ToastTemplate.LastChild.AppendChild($XMLvisual) - $null = $ToastTemplate.LastChild.AppendChild($XMLactions) - $null = $ToastTemplate.LastChild.AppendChild($XMLtag) + 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 + } - if ($OnClickAction) - { - $null = $ToastTemplate.toast.SetAttribute('activationType', 'Protocol') - $null = $ToastTemplate.toast.SetAttribute('launch', $OnClickAction) - } + # Creation of tag node + $XMLtag = $ToastTemplate.CreateElement("tag") + $XMLtagText = $ToastTemplate.CreateTextNode($Balise) + $XMLtag.AppendChild($XMLtagText) | 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) - } + # 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 - $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 = [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 - # Prepare and Create Toast - $ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXml) - $ToastMessage.Tag = $ToastTemplate.toast.tag - [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($LauncherID).Show($ToastMessage) - } + } + #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 + + } - # 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 a527ec1..2ec3d7b 100644 --- a/Winget-AutoUpdate/functions/Test-ListPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ListPath.ps1 @@ -1,121 +1,83 @@ -# Function to check Block/Allow List External Path +#Function to check Block/Allow List External Path -function Test-ListPath -{ - # URL, UNC or Local Path - [CmdletBinding()] - param - ( - [string] - $ListPath, - [string] - $UseWhiteList, - [string] - $WingetUpdatePath - ) +function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) { + # URL, UNC or Local Path + if ($UseWhiteList) { + $ListType = "included_apps.txt" + } + else { + $ListType = "excluded_apps.txt" + } - 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 -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) + # 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 } - catch - { - $Script:ReachNoPath = $True - return $False + } + 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 + } } - 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 + catch { + $Script:ReachNoPath = $True + return $False } - else - { - $Script:ReachNoPath = $True - return $False + } + } + # 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") } - } - catch - { + 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 { $Script:ReachNoPath = $True - 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 - } + } + return $False + } } diff --git a/Winget-AutoUpdate/functions/Test-Mods.ps1 b/Winget-AutoUpdate/functions/Test-Mods.ps1 index 81bf593..f46d4da 100644 --- a/Winget-AutoUpdate/functions/Test-Mods.ps1 +++ b/Winget-AutoUpdate/functions/Test-Mods.ps1 @@ -1,50 +1,34 @@ -# Function to check if modification exists within 'mods' directory +#Function to check if modification exists within 'mods' directory -function Test-Mods -{ - # Takes care of a null situation - [CmdletBinding()] - param - ( - [string] - $app - ) +function Test-Mods ($app) { - $ModsPreInstall = $null - $ModsOverride = $null - $ModsUpgrade = $null - $ModsInstall = $null - $ModsInstalled = $null - $Mods = ('{0}\mods' -f $WorkingDir) + #Takes care of a null situation + $ModsPreInstall = $null + $ModsOverride = $null + $ModsUpgrade = $null + $ModsInstall = $null + $ModsInstalled = $null - 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) - } + $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" + } + } - 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 - } + return $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled - 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 6385d84..9f468b1 100644 --- a/Winget-AutoUpdate/functions/Test-ModsPath.ps1 +++ b/Winget-AutoUpdate/functions/Test-ModsPath.ps1 @@ -1,310 +1,233 @@ #Function to check mods External Path -function Test-ModsPath -{ - # URL, UNC or Local Path - # Get local and external Mods paths +function Test-ModsPath ($ModsPath, $WingetUpdatePath, $AzureBlobSASURL) { + # URL, UNC or Local Path + # Get local and external Mods paths + $LocalMods = -join ($WingetUpdatePath, "\", "mods") + $ExternalMods = "$ModsPath" - [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 - # Check for bins, download if newer. Delete if not external - $ExternalBins = ('{0}/bins' -f $ModsPath) + #If there's a directory path in the HREF:s, delete it (IIS) + $CleanLinks = $ModLinks -replace "/.*/", "" - 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 + '' + #Modify strings to HREF:s + $index = 0 + foreach ($Mod in $CleanLinks) { + if ($Mod) { + $CleanLinks[$index] = ' ' + $Mod + '' } $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) + #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++ } - $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') - { - $dateExternalBin = '' - $dateLocalBin = '' - $null = $wc.OpenRead(('{0}/{1}' -f $ExternalBins, $_)).Close() - $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString('yyyy-MM-dd HH:mm:ss') + $CleanLinks = $ModLinks -replace "/.*/", "" - if (Test-Path -Path $LocalMods"\bins\"$_) - { - $dateLocalBin = (Get-Item -Path ('{0}\bins\{1}' -f $LocalMods, $_)).LastWriteTime.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 ($dateExternalBin -gt $dateLocalBin) - { - $SaveBin = Join-Path -Path ('{0}\bins' -f $LocalMods) -ChildPath $_ - Invoke-WebRequest -Uri ('{0}/{1}' -f $ExternalBins, $_) -OutFile $SaveBin.Replace('%20', ' ') -UseBasicParsing - } + 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 + } + } } - } - } + } + 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" - # 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 + $AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync "$AzureBlobSASURL" "$LocalMods" --from-to BlobLocal --delete-destination=true + $AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine) - foreach ($Mod in $CleanLinks) - { - if ($Mod) - { - $CleanLinks[$index] = ' ' + $Mod + '' - } - $index++ - } + 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:") - # Delete Local Mods that don't exist Externally - $DeletedMods = 0 - $index = 0 - $CleanLinks = $ModLinks -replace '/.*/', '' + $AZCopyAdditions = [int] $AZCopySyncAdditionsRegex.Match($_).Value + $AZCopyDeletions = [int] $AZCopySyncDeletionsRegex.Match($_).Value - foreach ($Mod in $InternalModsNames) - { - if ($CleanLinks -notcontains $Mod) - { - $null = (Remove-Item -Path $LocalMods\$Mod -Force -Confirm:$False -ErrorAction SilentlyContinue) - $DeletedMods++ - } - $index++ - } + if ($AZCopyAdditions -ne 0) { + $ModsUpdated = $AZCopyAdditions + } - $CleanLinks = $ModLinks -replace '/.*/', '' + if ($AZCopyDeletions -ne 0) { + $DeletedMods = $AZCopyDeletions + } - # 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 - } - } + if ($AZCopySyncErrorRegex.Match($_).Value) { + Write-ToLog "AZCopy Sync Error! $_" + } } - catch - { - if (($_ -like '*.ps1') -or ($_ -like '*.txt')) - { - $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 + } } - } - } - 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 + #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 + } + } + } - # 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' + 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 - $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 + #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++ + } } - if ($AZCopyDeletions -ne 0) - { - $DeletedMods = $AZCopyDeletions + #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 ($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 - } + } + else { + $Script:ReachNoPath = $True + } + return $ModsUpdated, $DeletedMods + } } diff --git a/Winget-AutoUpdate/functions/Test-Network.ps1 b/Winget-AutoUpdate/functions/Test-Network.ps1 index 22b3877..9910d26 100644 --- a/Winget-AutoUpdate/functions/Test-Network.ps1 +++ b/Winget-AutoUpdate/functions/Test-Network.ps1 @@ -1,77 +1,82 @@ -# Function to check the connectivity +#Function to check the connectivity -function Test-Network -{ - #Init +function Test-Network { - $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*") { - 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' + 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 ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) - { - Write-ToLog -LogMsg 'WAU is configured to bypass update checking on metered connection' - return $false } - else - { - Write-ToLog -LogMsg 'WAU is configured to force update checking on metered connection' - return $true + else { + + return $true + } - } - else - { - return $true - } - } - else - { - 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' + } + else { - # 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 - } - } - } + Start-Sleep 10 + $timeout += 10 - # Send Timeout Notif if no connection for 30 min - Write-ToLog -LogMsg 'Timeout. No internet connection !' -LogColor 'Red' + #Send Warning Notif if no connection for 5 min + if ($timeout -eq 300) { + #Log + Write-ToLog "Notify 'No connection' sent." "Yellow" - # 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 + #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 - return $false } diff --git a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 index 0e371f7..bb1d52e 100644 --- a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 +++ b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 @@ -1,34 +1,25 @@ -# Function to check if there is a Pending Reboot +#Function to check if there is a Pending Reboot -function Test-PendingReboot -{ - $Computer = $env:COMPUTERNAME - $PendingReboot = $false +function Test-PendingReboot { - $HKLM = [UInt32] '0x80000002' - $WMI_Reg = [WMIClass] ('\\{0}\root\default:StdRegProv' -f $Computer) + $Computer = $env:COMPUTERNAME + $PendingReboot = $false - 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 - } + $HKLM = [UInt32] "0x80000002" + $WMI_Reg = [WMIClass] "\\$Computer\root\default:StdRegProv" - # 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 - } - } - } + 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 - return $PendingReboot } diff --git a/Winget-AutoUpdate/functions/Update-App.ps1 b/Winget-AutoUpdate/functions/Update-App.ps1 index d7e0a4c..7006b10 100644 --- a/Winget-AutoUpdate/functions/Update-App.ps1 +++ b/Winget-AutoUpdate/functions/Update-App.ps1 @@ -1,137 +1,123 @@ -# Function to update an App +#Function to update an App -function Update-App -{ - # Get App Info - [CmdletBinding()] - param - ( - $app - ) - $ReleaseNoteURL = Get-AppInfo $app.Id - if ($ReleaseNoteURL) - { - $Button1Text = $NotifLocale.local.outputs.output[10].message - } +Function Update-App ($app) { - # 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 + #Get App Info + $ReleaseNoteURL = Get-AppInfo $app.Id + if ($ReleaseNoteURL) { + $Button1Text = $NotifLocale.local.outputs.output[10].message + } - # Check if mods exist for preinstall/install/upgrade - $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) + #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 - # Winget upgrade - Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' + #Check if mods exist for preinstall/install/upgrade + $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) - # If PreInstall script exist - if ($ModsPreInstall) - { - Write-ToLog -LogMsg ('Modifications for {0} before upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' - & "$ModsPreInstall" - } + #Winget upgrade + Write-ToLog "########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '$($App.Id)' ##########" "Gray" - # 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 - } + #If PreInstall script exist + if ($ModsPreInstall) { + Write-ToLog "Modifications for $($app.Id) before upgrade are being applied..." "Yellow" + & "$ModsPreInstall" + } - if ($ModsUpgrade) - { - Write-ToLog -LogMsg ('Modifications for {0} during upgrade are being applied...' -f $app.Id) -LogColor 'Yellow' - & "$ModsUpgrade" - } + #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 + } - # Check if application updated properly - $FailedToUpgrade = $false - $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) + if ($ModsUpgrade) { + Write-ToLog "Modifications for $($app.Id) during upgrade are being applied..." "Yellow" + & "$ModsUpgrade" + } - 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 - } + #Check if application updated properly + $FailedToUpgrade = $false + $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - # 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 ($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 ($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 app failed to upgrade, run Install command + Write-ToLog "-> An upgrade for $($app.Name) failed, now trying an install instead..." "Yellow" - if ($ModsInstall) - { - Write-ToLog -LogMsg ('Modifications for {0} during install are being applied...' -f $app.Id) -LogColor 'Yellow' - & "$ModsInstall" - } + 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 + } - # Check if application installed properly - $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) - if ($ConfirmInstall -eq $false) - { - $FailedToUpgrade = $true - } - } + if ($ModsInstall) { + Write-ToLog "Modifications for $($app.Id) during install are being applied..." "Yellow" + & "$ModsInstall" + } - if ($FailedToUpgrade -eq $false) - { - if ($ModsInstalled) - { - Write-ToLog -LogMsg ('Modifications for {0} after upgrade/install are being applied...' -f $app.Id) -LogColor 'Yellow' - & "$ModsInstalled" - } - } + #Check if application installed properly + $ConfirmInstall = Confirm-Installation $($app.Id) $($app.AvailableVersion) + if ($ConfirmInstall -eq $false) { + $FailedToUpgrade = $true + } + } - Write-ToLog -LogMsg ("########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '{0}' ##########" -f $app.Id) -LogColor 'Gray' + if ($FailedToUpgrade -eq $false) { + if ($ModsInstalled) { + Write-ToLog "Modifications for $($app.Id) after upgrade/install are being applied..." "Yellow" + & "$ModsInstalled" + } + } - # 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' + Write-ToLog "########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '$($App.Id)' ##########" "Gray" - # 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' + #Notify installation + if ($FailedToUpgrade -eq $false) { - # 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 - } -} + #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 diff --git a/Winget-AutoUpdate/functions/Update-WAU.ps1 b/Winget-AutoUpdate/functions/Update-WAU.ps1 index 57c6f49..123deb9 100644 --- a/Winget-AutoUpdate/functions/Update-WAU.ps1 +++ b/Winget-AutoUpdate/functions/Update-WAU.ps1 @@ -1,74 +1,77 @@ -# Function to update WAU +#Function to update WAU -function Update-WAU -{ - $OnClickAction = 'https://github.com/Romanitho/Winget-AutoUpdate/releases' - $Button1Text = $NotifLocale.local.outputs.output[10].message +function Update-WAU { - #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 + $OnClickAction = "https://github.com/Romanitho/Winget-AutoUpdate/releases" + $Button1Text = $NotifLocale.local.outputs.output[10].message - # 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 + #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 - # 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) + #Run WAU update + try { - # 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) + #Force to create a zip file + $ZipFile = "$WorkingDir\WAU_update.zip" + New-Item $ZipFile -ItemType File -Force | Out-Null - # 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) - } + #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 - # 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) + #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 - # 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 + #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 Post Update actions to 1 - $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -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 - # 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 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 - # Rerun with newer version - Write-ToLog -LogMsg 'Re-run WAU' - Start-Process -FilePath powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" + #Set Post Update actions to 1 + $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force - 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' - } -} + #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 diff --git a/Winget-AutoUpdate/functions/Write-ToLog.ps1 b/Winget-AutoUpdate/functions/Write-ToLog.ps1 index 772c437..db1116e 100644 --- a/Winget-AutoUpdate/functions/Write-ToLog.ps1 +++ b/Winget-AutoUpdate/functions/Write-ToLog.ps1 @@ -1,22 +1,14 @@ -# Write to Log Function +#Write to Log Function -function Write-ToLog -{ - # Get log - [CmdletBinding()] - param - ( - [string] - $LogMsg, - [string] - $LogColor = 'White' - ) +function Write-ToLog ($LogMsg, $LogColor = "White") { - $Log = ('{0} - {1}' -f (Get-Date -UFormat '%T'), $LogMsg) + #Get log + $Log = "$(Get-Date -UFormat "%T") - $LogMsg" - #Echo log - $Log | Write-Host -ForegroundColor $LogColor + #Echo log + $Log | Write-host -ForegroundColor $LogColor + + #Write log to file + $Log | Out-File -FilePath $LogFile -Append - #Write log to file - $Log | Out-File -FilePath $LogFile -Append -Force -Confirm:$false }