diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index 794c6d7..312b519 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -25,6 +25,9 @@ Use White List instead of Black List. This setting will not create the "exclude_ .PARAMETER Uninstall Remove scheduled tasks and scripts. +.PARAMETER NoClean +Keep critical files when installing/uninstalling + .PARAMETER NotificationLevel Specify the Notification level: Full (Default, displays all notification), SuccessOnly (Only displays notification for success) or None (Does not show any popup). @@ -46,6 +49,9 @@ Run WAU on metered connection. Default No. .EXAMPLE .\winget-install-and-update.ps1 -Silent -UpdatesAtLogon -UpdatesInterval Weekly +.EXAMPLE +.\Winget-AutoUpdate-Install.ps1 -Silent -Uninstall -NoClean + #> [CmdletBinding()] @@ -56,6 +62,7 @@ param( [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] $UseWhiteList = $false, [Parameter(Mandatory = $False)] [ValidateSet("Full", "SuccessOnly", "None")] [String] $NotificationLevel = "Full", [Parameter(Mandatory = $False)] [Switch] $UpdatesAtLogon = $false, @@ -176,21 +183,34 @@ function Install-WingetAutoUpdate { New-Item -ItemType Directory -Force -Path $WingetUpdatePath | Out-Null } else { - Remove-Item -Path "$WingetUpdatePath\*" -Exclude *.log -Recurse -Force + 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 #White List or Black List apps if ($UseWhiteList) { - if (Test-Path "$PSScriptRoot\included_apps.txt") { - Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + if (!$NoClean) { + if ((Test-Path "$PSScriptRoot\included_apps.txt")) { + Copy-Item -Path "$PSScriptRoot\included_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } + else { + New-Item -Path $WingetUpdatePath -Name "included_apps.txt" -ItemType "file" -ErrorAction SilentlyContinue | Out-Null + } } - else { + elseif (!(Test-Path "$WingetUpdatePath\included_apps.txt")) { New-Item -Path $WingetUpdatePath -Name "included_apps.txt" -ItemType "file" -ErrorAction SilentlyContinue | Out-Null } } else { - Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + if (!$NoClean) { + Copy-Item -Path "$PSScriptRoot\excluded_apps.txt" -Destination $WingetUpdatePath -Recurse -Force -ErrorAction SilentlyContinue + } } # Set dummy regkeys for notification name and icon @@ -282,7 +302,14 @@ function Uninstall-WingetAutoUpdate { #Check if installed location exists and delete if (Test-Path ($InstallLocation)) { - Remove-Item $InstallLocation -Force -Recurse + + if (!$NoClean) { + Remove-Item $InstallLocation -Force -Recurse + } + 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 & reg delete "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /f | Out-Null diff --git a/Winget-AutoUpdate/WAU-Uninstall.ps1 b/Winget-AutoUpdate/WAU-Uninstall.ps1 index 3701b1f..9ce09c7 100644 --- a/Winget-AutoUpdate/WAU-Uninstall.ps1 +++ b/Winget-AutoUpdate/WAU-Uninstall.ps1 @@ -1,3 +1,24 @@ +<# +.SYNOPSIS +Uninstall Winget-AutoUpdate + +.DESCRIPTION +Uninstall Winget-AutoUpdate (DEFAULT: clean old install) +https://github.com/Romanitho/Winget-AutoUpdate + +.PARAMETER NoClean +Uninstall Winget-AutoUpdate (keep critical files) + +.EXAMPLE +.\WAU-Uninstall.ps1 -NoClean + +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $False)] [Switch] $NoClean = $false +) + Write-Host "`n" Write-Host "`t 888 888 d8888 888 888" -ForegroundColor Magenta Write-Host "`t 888 o 888 d88888 888 888" -ForegroundColor Magenta @@ -18,7 +39,14 @@ try { #Check if installed location exists and delete if (Test-Path ($InstallLocation)) { - Remove-Item "$InstallLocation\*" -Force -Recurse -Exclude "*.log" + + 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 & reg delete "HKCR\AppUserModelId\Windows.SystemToast.Winget.Notification" /f | Out-Null diff --git a/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 new file mode 100644 index 0000000..795be9c --- /dev/null +++ b/Winget-AutoUpdate/functions/Test-PendingReboot.ps1 @@ -0,0 +1,29 @@ +#Function to check if there's a Pending Reboot + +function Test-PendingReboot { + + $Computer = $env:COMPUTERNAME + $PendingReboot = $false + + $HKLM = [UInt32] "0x80000002" + $WMI_Reg = [WMIClass] "\\$Computer\root\default:StdRegProv" + + if ($WMI_Reg) { + if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\")).sNames -contains 'RebootPending') {$PendingReboot = $true} + if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\")).sNames -contains 'RebootRequired') {$PendingReboot = $true} + + #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} + } + + # [PSCustomObject]@{ + # ComputerName = $Computer.ToUpper() + # PendingReboot = $PendingReboot + # } + } + + return $PendingReboot + +} diff --git a/Winget-AutoUpdate/functions/Update-App.ps1 b/Winget-AutoUpdate/functions/Update-App.ps1 index 55cdefb..2fda09e 100644 --- a/Winget-AutoUpdate/functions/Update-App.ps1 +++ b/Winget-AutoUpdate/functions/Update-App.ps1 @@ -28,7 +28,17 @@ Function Update-App ($app) { foreach ($CheckApp in $CheckOutdated) { if ($($CheckApp.Id) -eq $($app.Id)) { + #Upgrade failed! + #Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities) + $PendingReboot = Test-PendingReboot + if ($PendingReboot -eq $true) { + Write-Log "A Pending Reboot lingers and probably prohibited $($app.Name) from upgrading...`n...an install for $($app.Name) is NOT executed!" "Red" + $FailedToUpgrade = $true + break + } + #If app failed to upgrade, run Install command + Write-Log "An upgrade for $($app.Name) failed, now trying an install..." "Yellow" & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -file $LogFile -Append #Set mods to apply as an install