diff --git a/Winget-AutoUpdate-Install.ps1 b/Winget-AutoUpdate-Install.ps1 index f4b1087..b836d5a 100644 --- a/Winget-AutoUpdate-Install.ps1 +++ b/Winget-AutoUpdate-Install.ps1 @@ -367,7 +367,7 @@ function Install-WingetAutoUpdate { New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force | Out-Null } - #Set ACL for users on logfile + #Set ACL for Authenticated Users on logfile $LogFile = "$WingetUpdatePath\logs\updates.log" if (test-path $LogFile) { $NewAcl = Get-Acl -Path $LogFile @@ -380,6 +380,20 @@ function Install-WingetAutoUpdate { Set-Acl -Path $LogFile -AclObject $NewAcl } + #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 + } + #Create Shortcuts if ($StartMenuShortcut) { if (!(Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) { diff --git a/Winget-AutoUpdate/Winget-Upgrade.ps1 b/Winget-AutoUpdate/Winget-Upgrade.ps1 index 55a2e24..39e4285 100644 --- a/Winget-AutoUpdate/Winget-Upgrade.ps1 +++ b/Winget-AutoUpdate/Winget-Upgrade.ps1 @@ -203,71 +203,73 @@ if (Test-Network) { Write-Log "Checking application updates on Winget Repository..." "yellow" $outdated = Get-WingetOutdatedApps - #If something is wrong with the winget source, exit - if ($outdated -like "Problem:*") { - Write-Log "Critical: An error occured, exiting..." "red" - Write-Log "$outdated" "red" - New-Item "$WorkingDir\logs\error.txt" -Value "$outdated" -Force - Exit 1 + #If something unusual happened + if ($outdated -like "An unusual*") { + Write-Log "$outdated" "cyan" + $outdated = $False } - #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 $true) { - Write-Log "Bypass system list in user context is Enabled." - $UseWhiteList = $false - $toSkip = $null - } - - #If White List - if ($UseWhiteList) { - #For each app, notify and update + #Run only if $outdated is populated! + if ($outdated) { + #Log list of app to 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-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" - } - #if app is in "excluded list" - else { - Write-Log "$($app.Name) : Skipped upgrade because it is not in the included app list" "Gray" + #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 $true) { + Write-Log "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-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" + } + #if app is in "excluded list" + else { + Write-Log "$($app.Name) : Skipped upgrade because it is not in the included app list" "Gray" + } } } - } - #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-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" - } - #if app is in "excluded list" - else { - Write-Log "$($app.Name) : Skipped upgrade because it is in the excluded app list" "Gray" + #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-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" + } + #if app is in "excluded list" + else { + Write-Log "$($app.Name) : Skipped upgrade because it is in the excluded app list" "Gray" + } } } + + if ($InstallOK -gt 0) { + Write-Log "$InstallOK apps updated ! No more update." "Green" + } } - if ($InstallOK -gt 0) { - Write-Log "$InstallOK apps updated ! No more update." "Green" - } - if ($InstallOK -eq 0) { + if ($InstallOK -eq 0 -or !$InstallOK) { Write-Log "No new update." "Green" } diff --git a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 index ae6aa50..53cc0a7 100644 --- a/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 +++ b/Winget-AutoUpdate/functions/Get-WingetOutdatedApps.ps1 @@ -13,7 +13,7 @@ function Get-WingetOutdatedApps { #Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) if (!($upgradeResult -match "-----")) { - return "Problem:`n$upgradeResult" + return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult" } #Split winget output to lines diff --git a/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 new file mode 100644 index 0000000..b800571 --- /dev/null +++ b/Winget-AutoUpdate/functions/Invoke-ModsProtect.ps1 @@ -0,0 +1,65 @@ +#Function to check if Mods Directory is secured. +#Security: Mods directory must be protected (Users could create scripts of their own - then they'll run in System Context)! +#Check if Local Users have write rights in Mods directory or not (and take action if necessary): + +function Invoke-ModsProtect ($ModsPath) { + try { + $directory = Get-Item -Path $ModsPath -ErrorAction SilentlyContinue + $acl = Get-Acl -Path $directory.FullName + #Local Users - S-1-5-32-545 + $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-545") + #Translate SID to Locale Name + $ntAccount = $userSID.Translate([System.Security.Principal.NTAccount]) + $userName = $ntAccount.Value + $userRights = [System.Security.AccessControl.FileSystemRights]"Write" + + $hasWriteAccess = $False + + foreach ($access in $acl.Access) { + if ($access.IdentityReference.Value -eq $userName -and $access.FileSystemRights -eq $userRights) { + $hasWriteAccess = $True + break + } + } + + if ($hasWriteAccess) { + #Disable inheritance + $acl.SetAccessRuleProtection($True, $True) + # Remove any existing rules + $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } + #SYSTEM Full - S-1-5-18 + $userSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-18") + $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSID,"FullControl","ContainerInherit,ObjectInherit","None","Allow") + $acl.SetAccessRule($rule) + # Save the updated ACL + Set-Acl -Path $directory.FullName -AclObject $acl + + #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 + + #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 + + #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 + + 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 e9eeb5d..5bfe644 100644 --- a/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 +++ b/Winget-AutoUpdate/functions/Invoke-PostUpdateActions.ps1 @@ -53,6 +53,37 @@ function Invoke-PostUpdateActions { Write-Log "-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB)." } + #Set WAU_ListPath if not set + $ListPath = Get-ItemProperty $regPath -Name WAU_ListPath -ErrorAction SilentlyContinue + if (!$ListPath) { + New-ItemProperty $regPath -Name WAU_ListPath -Force | Out-Null + + #log + Write-Log "-> 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 + + #log + Write-Log "-> ModsPath setting was missing. Fixed with empty string." + } + + #Security check + Write-Log "-> Checking Mods Directory:" "yellow" + $Protected = Invoke-ModsProtect "$($WAUConfig.InstallLocation)\mods" + if ($Protected -eq $True) { + Write-Log "-> The mods directory is now secured!" "green" + } + elseif ($Protected -eq $False) { + Write-Log "-> The mods directory was already secured!" "green" + } + else { + Write-Log "-> Error: The mods directory couldn't be verified as secured!" "red" + } + #Convert about.xml if exists (previous WAU versions) to reg $WAUAboutPath = "$WorkingDir\config\about.xml" if (test-path $WAUAboutPath) {