Merge pull request #329 from Romanitho/temp

Update user-approval branch
pull/339/head^2
Romain 2023-04-23 11:32:51 +02:00 committed by GitHub
commit 833339ab84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1113 additions and 393 deletions

View File

@ -11,6 +11,10 @@
'PSPossibleIncorrectComparisonWithNull', 'PSPossibleIncorrectComparisonWithNull',
'PSAvoidTrailingWhitespace', 'PSAvoidTrailingWhitespace',
'PSUseApprovedVerbs', 'PSUseApprovedVerbs',
'PSAvoidUsingWMICmdlet' 'PSAvoidUsingWMICmdlet',
'PSReviewUnusedParameter',
'PSUseDeclaredVarsMoreThanAssignment',
'PSUseShouldProcessForStateChangingFunctions',
'PSUseDeclaredVarsMoreThanAssignments'
) )
} }

View File

@ -1,8 +1,11 @@
---
name: Close inactive issues name: Close inactive issues
on: on:
schedule: schedule:
- cron: "30 1 * * *" - cron: "30 1 * * *"
permissions: read-all
jobs: jobs:
close-issues: close-issues:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -10,7 +13,7 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v4 - uses: actions/stale@v8
with: with:
days-before-issue-stale: 30 days-before-issue-stale: 30
days-before-issue-close: 14 days-before-issue-close: 14

View File

@ -0,0 +1,102 @@
---
name: WAU - Auto Create Pre-Release Version
on:
schedule:
- cron: "0 0 * * *"
permissions:
contents: write
jobs:
check_merged:
name: Compare latest merge and tag
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.should_run.outputs.SHOULD_RUN }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Check if latest merged is older than latest tag
id: should_run
run: |
echo "Latest tag:"
git log --tags --pretty="%ci - %h - %s %d" -n 1
LATEST_TAG_DATE=$(git log --tags -n 1 --pretty="%ct")
echo $LATEST_TAG_DATE
echo "Latest merge:"
git log --merges --pretty="%ci - %h - %s %d" -n 1
LATEST_MERGE_DATE=$(git log --merges -n 1 --pretty="%ct")
echo $LATEST_MERGE_DATE
if [[ $LATEST_MERGE_DATE -gt $LATEST_TAG_DATE ]]; then
echo "Latest tag is older than latest merge. Nightly will be created."
echo "SHOULD_RUN=true" >> $GITHUB_OUTPUT
else
echo "Latest merge is not older than latest tag. No new release needed."
echo "SHOULD_RUN=false" >> $GITHUB_OUTPUT
fi
build:
name: Create Release Asset
needs: [check_merged]
if: ${{ needs.check_merged.outputs.should_run == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
lfs: "true"
fetch-depth: 0
- name: Auto Increment Semver Action
uses: MCKanpolat/auto-semver-action@1.0.9
id: versioning
with:
releaseType: prerelease
incrementPerCommit: false
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Next Release Number
id: WAU_version
run: |
echo "Next Release version: ${{ steps.versioning.outputs.version }}"
- name: Overwrite Version.txt file
uses: DamianReeves/write-file-action@v1.2
with:
path: Winget-AutoUpdate/Version.txt
write-mode: overwrite
contents: ${{ steps.versioning.outputs.version }}
- name: Commit & Push
uses: actions-js/push@v1.4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
force: true
message: "Changed version to ${{ steps.versioning.outputs.version }}"
- name: Build project
run: |
zip -r WAU Winget-AutoUpdate/*
zip -r WAU Winget-AutoUpdate-Install.ps1
zip -r WAU excluded_apps.txt
zip -r WAU install.bat
zip -r WAU uninstall.bat
- name: Create release
uses: "ncipollo/release-action@v1"
id: release
with:
tag: "v${{ steps.versioning.outputs.version }}"
prerelease: true
generateReleaseNotes: true
name: "v${{ steps.versioning.outputs.version }} [Nightly Build]"
artifacts: "WAU.zip"
- name: URL to release
run: echo "Release -> ${{ steps.release.outputs.html_url }}"

View File

@ -0,0 +1,71 @@
---
name: WAU - Create New Version
on:
workflow_dispatch:
inputs:
version:
type: choice
default: "Patch"
description: Select next release type
options:
- Patch
- Minor
- Major
required: true
pre-release:
type: boolean
description: Set as Pre-release version
permissions:
contents: write
jobs:
build:
name: Create Release Asset
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
lfs: "true"
- name: Auto Increment Semver Action
uses: MCKanpolat/auto-semver-action@1.0.9
id: versioning
with:
releaseType: ${{ github.event.inputs.version }}
incrementPerCommit: false
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Overwrite Version.txt file
uses: DamianReeves/write-file-action@v1.2
with:
path: Winget-AutoUpdate/Version.txt
write-mode: overwrite
contents: "${{ steps.versioning.outputs.version }}"
- name: Commit & Push
uses: actions-js/push@v1.4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
force: true
message: "Changed version to ${{ steps.versioning.outputs.version }}"
- name: Build project
run: |
zip -r WAU Winget-AutoUpdate/*
zip -r WAU Winget-AutoUpdate-Install.ps1
zip -r WAU excluded_apps.txt
zip -r WAU install.bat
zip -r WAU uninstall.bat
- name: Create release
uses: "ncipollo/release-action@v1"
with:
tag: "v${{ steps.versioning.outputs.version }}"
prerelease: ${{ github.event.inputs.pre-release }}
generateReleaseNotes: true
name: "v${{ steps.versioning.outputs.version }}"
artifacts: "WAU.zip"

View File

@ -5,7 +5,7 @@ name: MegaLinter
on: on:
# Trigger mega-linter at every push. Action will also be visible from Pull Requests to main # Trigger mega-linter at every push. Action will also be visible from Pull Requests to main
push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) #push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions)
pull_request: pull_request:
branches: [master, main] branches: [master, main]
@ -41,16 +41,16 @@ jobs:
id: ml id: ml
# You can override MegaLinter flavor used to have faster performances # You can override MegaLinter flavor used to have faster performances
# More info at https://megalinter.github.io/flavors/ # More info at https://megalinter.github.io/flavors/
uses: megalinter/megalinter@v6 uses: oxsecurity/megalinter@v6
env: env:
# All available variables are described in documentation # All available variables are described in documentation
# https://megalinter.github.io/configuration/ # https://megalinter.github.io/configuration/
VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SPELL_CSPELL_CONFIG_FILE: .github/cspell.json SPELL_CSPELL_CONFIG_FILE: .github/cspell.json
POWERSHELL_POWERSHELL_CONFIG_FILE: .github/.powershell-psscriptanalyzer.psd1 POWERSHELL_POWERSHELL_CONFIG_FILE: .github/.powershell-psscriptanalyzer.psd1
DISABLE_ERRORS_LINTERS: REPOSITORY_DEVSKIM,SPELL_CSPELL,SPELL_PROSELINT,COPYPASTE_JSCPD,MARKDOWN_MARKDOWN_LINK_CHECK DISABLE_ERRORS_LINTERS: REPOSITORY_DEVSKIM,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,SPELL_CSPELL,SPELL_PROSELINT,COPYPASTE_JSCPD,MARKDOWN_MARKDOWN_LINK_CHECK
FILTER_REGEX_EXCLUDE: (.github/workflows/) FILTER_REGEX_EXCLUDE: (workflows/)
# Upload MegaLinter artifacts # Upload MegaLinter artifacts
- name: Archive production artifacts - name: Archive production artifacts
@ -67,7 +67,7 @@ jobs:
- name: Create Pull Request with applied fixes - name: Create Pull Request with applied fixes
id: cpr id: cpr
if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix')
uses: peter-evans/create-pull-request@v4 uses: peter-evans/create-pull-request@v5
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "[MegaLinter] Apply linters automatic fixes" commit-message: "[MegaLinter] Apply linters automatic fixes"

58
.github/workflows/powershell-tests.yaml vendored Normal file
View File

@ -0,0 +1,58 @@
---
name: WAU Powershell Test Runs
# yamllint disable-line rule:truthy
on:
pull_request:
branches: [master, main]
workflow_dispatch:
permissions:
contents: read
pull-requests: read
jobs:
powershell-tests:
name: Pester test and PSScriptAnalyzer
runs-on: windows-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Perform a Pester test for the WAU installation
shell: powershell
run: |
$command = New-PesterContainer -Path Winget-AutoUpdate-Install.ps1 -Data @{ Silent = $true }
Invoke-Pester -PassThru -Container $command -ErrorAction Continue
- name: Perform a Pester test for WAU run
shell: powershell
run: |
$command = New-PesterContainer -Path C:\ProgramData\Winget-AutoUpdate\user-run.ps1
Invoke-Pester -PassThru -Container $command -ErrorAction Continue
#- name: Read WAU Log
# id: package
# uses: juliangruber/read-file-action@v1
# with:
# path: 'C:\ProgramData\Winget-AutoUpdate\Logs\updates.log'
#- name: Display WAU Log
# run: type "${{ steps.package.outputs.content }}"
- name: Install PSScriptAnalyzer module from PSGallery
shell: powershell
run: |
Set-PSRepository PSGallery -InstallationPolicy Trusted
Install-Module PSScriptAnalyzer -ErrorAction Stop
- name: Lint with PSScriptAnalyzer
shell: powershell
run: |
Invoke-ScriptAnalyzer -Path *.ps1 -Recurse -Outvariable issues
$errors = $issues.Where({$_.Severity -eq 'Error'})
$warnings = $issues.Where({$_.Severity -eq 'Warning'})
if ($($errors.Count) -gt 0) {
$ErrorAction = "Stop"
} else {
$ErrorAction = "Continue"
}
if ($errors) {
Write-Error "There were $($errors.Count) errors and $($warnings.Count) warnings total." -ErrorAction $ErrorAction
} else {
Write-Output "There were $($errors.Count) errors and $($warnings.Count) warnings total."
}

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="4.7" xsi:schemaLocation="" schemaVersion="1.0" xmlns="http://www.microsoft.com/GroupPolicy/PolicyDefinitions"> <policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="4.8" xsi:schemaLocation="" schemaVersion="1.0" xmlns="http://www.microsoft.com/GroupPolicy/PolicyDefinitions">
<policyNamespaces> <policyNamespaces>
<target prefix="WAU" namespace="Romanitho.Policies.WAU"/> <target prefix="WAU" namespace="Romanitho.Policies.WAU"/>
</policyNamespaces> </policyNamespaces>
<resources minRequiredRevision="4.7" fallbackCulture="en-us"/> <resources minRequiredRevision="4.8" fallbackCulture="en-us"/>
<supportedOn> <supportedOn>
<definitions> <definitions>
<definition name="SUPPORTED_WAU_1_16_0" displayName="$(string.SUPPORTED_WAU_1_16_0)"/> <definition name="SUPPORTED_WAU_1_16_0" displayName="$(string.SUPPORTED_WAU_1_16_0)"/>
<definition name="SUPPORTED_WAU_1_16_5" displayName="$(string.SUPPORTED_WAU_1_16_5)"/>
</definitions> </definitions>
</supportedOn> </supportedOn>
<categories><category displayName="$(string.WAU)" name="WAU"/></categories> <categories><category displayName="$(string.WAU)" name="WAU"/></categories>
@ -99,6 +100,13 @@
<text id="ModsPath" valueName="WAU_ModsPath" /> <text id="ModsPath" valueName="WAU_ModsPath" />
</elements> </elements>
</policy> </policy>
<policy name="BlobURL_Enable" class="Machine" displayName="$(string.BlobURL_Name)" explainText="$(string.BlobURL_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.BlobURL)" >
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_16_5"/>
<elements>
<text id="BlobURL" valueName="WAU_AzureBlobSASURL" />
</elements>
</policy>
<policy name="NotificationLevel_Enable" class="Machine" displayName="$(string.NotificationLevel_Name)" explainText="$(string.NotificationLevel_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.NotificationLevel)"> <policy name="NotificationLevel_Enable" class="Machine" displayName="$(string.NotificationLevel_Name)" explainText="$(string.NotificationLevel_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.NotificationLevel)">
<parentCategory ref="WAU"/> <parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_16_0"/> <supportedOn ref="WAU:SUPPORTED_WAU_1_16_0"/>

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="4.7" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions"> <policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="4.8" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<displayName>WinGet-AutoUpdate</displayName> <displayName>WinGet-AutoUpdate</displayName>
<description>WinGet-AutoUpdate GPO Management</description> <description>WinGet-AutoUpdate GPO Management</description>
<resources > <resources >
<stringTable > <stringTable >
<string id="WAU">Winget-AutoUpdate</string> <string id="WAU">Winget-AutoUpdate</string>
<string id="SUPPORTED_WAU_1_16_0">Winget-AutoUpdate version 1.16.0 or later</string> <string id="SUPPORTED_WAU_1_16_0">Winget-AutoUpdate version 1.16.0 or later</string>
<string id="SUPPORTED_WAU_1_16_5">Winget-AutoUpdate version 1.16.5 or later</string>
<string id="ActivateGPOManagement_Name">Activate WAU GPO Management</string> <string id="ActivateGPOManagement_Name">Activate WAU GPO Management</string>
<string id="ActivateGPOManagement_Explain">This policy setting is an overriding toggle for GPO Management of Winget-AutoUpdate.</string> <string id="ActivateGPOManagement_Explain">This policy setting is an overriding toggle for GPO Management of Winget-AutoUpdate.</string>
<string id="BypassListForUsers_Name">Bypass Black/White list for User</string> <string id="BypassListForUsers_Name">Bypass Black/White list for User</string>
@ -43,10 +44,16 @@ If this policy is disabled or not configured, the default is No.</string>
If "Application GPO Blacklist/Whitelist" is set in this GPO the Path can be: GPO If "Application GPO Blacklist/Whitelist" is set in this GPO the Path can be: GPO
If this policy is disabled or not configured, the default ListPath is used (WAU InstallLocation).</string> If this policy is disabled or not configured, the default ListPath is used (WAU InstallLocation).</string>
<string id="ModsPath_Name">Get Mods from external Path (URL/UNC/Local)</string> <string id="ModsPath_Name">Get Mods from external Path (URL/UNC/Local/AzureBlob)</string>
<string id="ModsPath_Explain">If this policy is enabled, you can set a (URL/UNC/Local) Path to external mods other than the default. <string id="ModsPath_Explain">If this policy is enabled, you can set a (URL/UNC/Local/AzureBlob) Path to external mods other than the default.
If this policy is disabled or not configured, the default ModsPath is used (WAU InstallLocation).</string> If this policy is disabled or not configured, the default ModsPath is used (WAU InstallLocation).
Note: When set to 'AzureBlob', ensure you also configure 'Set Azure Blob URL with SAS token'.</string>
<string id="BlobURL_Name">Set Azure Blob URL with SAS Token</string>
<string id="BlobURL_Explain">If this policy is enabled, you can set an Azure Storage Blob URL with SAS token for use with the 'Mods' feature. The URL must include the SAS token and have 'read' and 'list' permissions.
If this policy is disabled or not configured, the value is blank and Azure Blob storage will NOT work.</string>
<string id="NotificationLevel_Name">Notification Level</string> <string id="NotificationLevel_Name">Notification Level</string>
<string id="NotificationLevel_Explain">If this policy is enabled, you can configure the Notification Level: <string id="NotificationLevel_Explain">If this policy is enabled, you can configure the Notification Level:
1. Full (Default) 1. Full (Default)
@ -148,8 +155,13 @@ If this policy is disabled or not configured, the default size is used.</string>
</presentation> </presentation>
<presentation id="ModsPath"> <presentation id="ModsPath">
<textBox refId="ModsPath"> <textBox refId="ModsPath">
<label>(URL/UNC/Local) Path:</label> <label>(URL/UNC/Local/AzureBlob) Path:</label>
</textBox> </textBox>
</presentation>
<presentation id="BlobURL">
<textBox refId="BlobURL">
<label>Azure Storage URL with SAS token:</label>
</textBox>
</presentation> </presentation>
<presentation id="NotificationLevel"> <presentation id="NotificationLevel">
<dropdownList refId="NotificationLevel"/> <dropdownList refId="NotificationLevel"/>

View File

@ -4,7 +4,7 @@ This project uses the Winget tool to daily update apps (with system context) and
![image](https://user-images.githubusercontent.com/96626929/150645599-9460def4-0818-4fe9-819c-dd7081ff8447.png) ![image](https://user-images.githubusercontent.com/96626929/150645599-9460def4-0818-4fe9-819c-dd7081ff8447.png)
## Intallation ## Intallation
Just [download latest release (source code)](https://github.com/Romanitho/Winget-AutoUpdate/releases), unzip, run "install.bat" as admin to install by default. Just [download latest release (WAU.zip)](https://github.com/Romanitho/Winget-AutoUpdate/releases/latest/download/WAU.zip), unzip, run "install.bat" as admin to install by default.
## Configurations ## Configurations
### Keep some apps out of Winget-AutoUpdate ### Keep some apps out of Winget-AutoUpdate
@ -29,7 +29,8 @@ By default, scripts and components will be placed in ProgramData location (insid
From version 1.9.0 (on new installations) WAU runs everyday at 6AM. You can now configure the frequency with `-UpdatesInterval` option (Daily, BiDaily, Weekly, BiWeekly or Monthly). You can also add `-UpdatesAtLogon` parameter to run at user logon and keep this option activated like previous versions (recommanded). From version 1.9.0 (on new installations) WAU runs everyday at 6AM. You can now configure the frequency with `-UpdatesInterval` option (Daily, BiDaily, Weekly, BiWeekly or Monthly). You can also add `-UpdatesAtLogon` parameter to run at user logon and keep this option activated like previous versions (recommanded).
### Log location ### Log location
You can find logs in install location, in logs folder. You can find logs in install location, in logs folder.
If **Intune Management Extension** is installed, a **SymLink** (WAU-updates.log) is created under **C:\ProgramData\Microsoft\IntuneManagementExtension\Logs**
### "Unknown" App version ### "Unknown" App version
As explained in this [post](https://github.com/microsoft/winget-cli/issues/1255), Winget cannot detect the current version of some installed apps. We decided to skip managing these apps with WAU to avoid retries each time WAU runs: As explained in this [post](https://github.com/microsoft/winget-cli/issues/1255), Winget cannot detect the current version of some installed apps. We decided to skip managing these apps with WAU to avoid retries each time WAU runs:
@ -96,12 +97,15 @@ Disable Winget-AutoUpdate update checking. By default, WAU auto updates if new v
Use White List instead of Black List. This setting will not create the "excluded_apps.txt" but "included_apps.txt". Use White List instead of Black List. This setting will not create the "excluded_apps.txt" but "included_apps.txt".
**-ListPath** **-ListPath**
Get Black/White List from external Path (**URL/UNC/GPO/Local**) - download/copy to Winget-AutoUpdate installation location if external list is newer. Get Black/White List from external Path (**URL/UNC/Local/GPO**) - download/copy to Winget-AutoUpdate installation location if external list is newer.
**PATH** must end with a Directory, not a File...
...if the external Path is an **URL** and the web host doesn't respond with a date/time header for the file (i.e **GitHub**) then the file is always downloaded!
If `-ListPath` is set to **GPO** the Black/White List can be managed from within the GPO itself under **Application GPO Blacklist**/**Application GPO Whitelist**. If `-ListPath` is set to **GPO** the Black/White List can be managed from within the GPO itself under **Application GPO Blacklist**/**Application GPO Whitelist**.
Thanks to [Weatherlights](https://github.com/Weatherlights) in [#256 (reply in thread)](https://github.com/Romanitho/Winget-AutoUpdate/discussions/256#discussioncomment-4710599)! Thanks to [Weatherlights](https://github.com/Weatherlights) in [#256 (reply in thread)](https://github.com/Romanitho/Winget-AutoUpdate/discussions/256#discussioncomment-4710599)!
**-ModsPath** **-ModsPath**
Get Mods from external Path (**URL/UNC/Local**) - download/copy to `mods` in Winget-AutoUpdate installation location if external mods are newer. Get Mods from external Path (**URL/UNC/Local/AzureBlob**) - download/copy to `mods` in Winget-AutoUpdate installation location if external mods are newer.
For **URL**: This requires a site directory with **Directory Listing Enabled** and no index page overriding the listing of files (or an index page with href listing of all the **Mods** to be downloaded): For **URL**: This requires a site directory with **Directory Listing Enabled** and no index page overriding the listing of files (or an index page with href listing of all the **Mods** to be downloaded):
``` ```
@ -118,6 +122,11 @@ Validated on **IIS/Apache**.
- The extension **.ps1** must be added as **MIME Types** (text/powershell-script) otherwise it's displayed in the listing but can't be opened - The extension **.ps1** must be added as **MIME Types** (text/powershell-script) otherwise it's displayed in the listing but can't be opened
- Files with special characters in the filename can't be opened by default from an IIS server - config must be administrated: **Enable Allow double escaping** in '**Request Filtering**' - Files with special characters in the filename can't be opened by default from an IIS server - config must be administrated: **Enable Allow double escaping** in '**Request Filtering**'
For **AzureBlob**: This requires the parameter **-AzureBlobURL** to be set with an appropriate Azure Blob Storage URL including the SAS token. See **-AzureBlobURL** for more information.
**-AzureBlobURL**
Used in conjunction with the **-ModsPath** parameter to provide the Azure Storage Blob URL with SAS token. The SAS token must, at a minimum, have 'Read' and 'List' permissions. It is recommended to set the permisions at the container level and rotate the SAS token on a regular basis. Ensure the container reflects the same structure as found under the initial `mods` folder. (From version 1.16.4).
**-InstallUserContext** **-InstallUserContext**
Install WAU with system and **user** context executions (From version 1.15.3). Install WAU with system and **user** context executions (From version 1.15.3).

View File

@ -4,7 +4,7 @@ Configure Winget to daily update installed apps.
.DESCRIPTION .DESCRIPTION
Install powershell scripts and scheduled task to daily run Winget upgrade and notify connected users. Install powershell scripts and scheduled task to daily run Winget upgrade and notify connected users.
Possible to exclude apps from auto-update Posibility to exclude apps from auto-update
https://github.com/Romanitho/Winget-AutoUpdate https://github.com/Romanitho/Winget-AutoUpdate
.PARAMETER Silent .PARAMETER Silent
@ -29,10 +29,13 @@ Disable Winget-AutoUpdate update checking. By default, WAU auto update if new ve
Use White List instead of Black List. This setting will not create the "exclude_apps.txt" but "include_apps.txt" Use White List instead of Black List. This setting will not create the "exclude_apps.txt" but "include_apps.txt"
.PARAMETER ListPath .PARAMETER ListPath
Get Black/White List from Path (URL/UNC/Local) Get Black/White List from Path (URL/UNC/GPO/Local)
.PARAMETER ModsPath .PARAMETER ModsPath
Get mods from Path (URL/UNC/Local) 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 Uninstall .PARAMETER Uninstall
Remove scheduled tasks and scripts. Remove scheduled tasks and scripts.
@ -93,6 +96,7 @@ param(
[Parameter(Mandatory = $False)] [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate", [Parameter(Mandatory = $False)] [Alias('Path')] [String] $WingetUpdatePath = "$env:ProgramData\Winget-AutoUpdate",
[Parameter(Mandatory = $False)] [Alias('List')] [String] $ListPath, [Parameter(Mandatory = $False)] [Alias('List')] [String] $ListPath,
[Parameter(Mandatory = $False)] [Alias('Mods')] [String] $ModsPath, [Parameter(Mandatory = $False)] [Alias('Mods')] [String] $ModsPath,
[Parameter(Mandatory = $False)] [Alias('AzureBlobURL')] [String] $AzureBlobSASURL,
[Parameter(Mandatory = $False)] [Switch] $DoNotUpdate = $false, [Parameter(Mandatory = $False)] [Switch] $DoNotUpdate = $false,
[Parameter(Mandatory = $False)] [Switch] $DisableWAUAutoUpdate = $false, [Parameter(Mandatory = $False)] [Switch] $DisableWAUAutoUpdate = $false,
[Parameter(Mandatory = $False)] [Switch] $RunOnMetered = $false, [Parameter(Mandatory = $False)] [Switch] $RunOnMetered = $false,
@ -107,13 +111,10 @@ param(
[Parameter(Mandatory = $False)] [DateTime] $UpdatesAtTime = ("06am"), [Parameter(Mandatory = $False)] [DateTime] $UpdatesAtTime = ("06am"),
[Parameter(Mandatory = $False)] [Switch] $BypassListForUsers = $false, [Parameter(Mandatory = $False)] [Switch] $BypassListForUsers = $false,
[Parameter(Mandatory = $False)] [Switch] $InstallUserContext = $false, [Parameter(Mandatory = $False)] [Switch] $InstallUserContext = $false,
[Parameter(Mandatory = $False)] [ValidateRange(0,99)] [int32] $MaxLogFiles = 3, [Parameter(Mandatory = $False)] [ValidateRange(0, 99)] [int32] $MaxLogFiles = 3,
[Parameter(Mandatory = $False)] [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB [Parameter(Mandatory = $False)] [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB
) )
<# APP INFO #>
$WAUVersion = "1.15.3"
<# FUNCTIONS #> <# FUNCTIONS #>
@ -158,7 +159,7 @@ function Install-Prerequisites {
$SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe" $SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe"
$Installer = $WingetUpdatePath + "\VC_redist.$OSArch.exe" $Installer = $WingetUpdatePath + "\VC_redist.$OSArch.exe"
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest $SourceURL -OutFile (New-Item -Path $Installer -Force) Invoke-WebRequest $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force)
Write-host "-> Installing VC_redist.$OSArch.exe..." Write-host "-> Installing VC_redist.$OSArch.exe..."
Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait
Remove-Item $Installer -ErrorAction Ignore Remove-Item $Installer -ErrorAction Ignore
@ -344,8 +345,6 @@ function Install-WingetAutoUpdate {
New-ItemProperty $regPath -Name QuietUninstallString -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 NoModify -Value 1 -Force | Out-Null
New-ItemProperty $regPath -Name NoRepair -Value 1 -Force | Out-Null New-ItemProperty $regPath -Name NoRepair -Value 1 -Force | Out-Null
New-ItemProperty $regPath -Name VersionMajor -Value ([version]$WAUVersion).Major -Force | Out-Null
New-ItemProperty $regPath -Name VersionMinor -Value ([version]$WAUVersion).Minor -Force | Out-Null
New-ItemProperty $regPath -Name Publisher -Value "Romanitho" -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 URLInfoAbout -Value "https://github.com/Romanitho/Winget-AutoUpdate" -Force | Out-Null
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $NotificationLevel -Force | Out-Null New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $NotificationLevel -Force | Out-Null
@ -368,21 +367,29 @@ function Install-WingetAutoUpdate {
if ($ModsPath) { if ($ModsPath) {
New-ItemProperty $regPath -Name WAU_ModsPath -Value $ModsPath -Force | Out-Null 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) { if ($BypassListForUsers) {
New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value 1 -PropertyType DWord -Force | Out-Null
} }
#Set ACL for users on logfile #Log file and symlink initialization
$LogFile = "$WingetUpdatePath\logs\updates.log" . "$WingetUpdatePath\functions\Start-Init.ps1"
if (test-path $LogFile) { Start-Init
$NewAcl = Get-Acl -Path $LogFile
$identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11 #Security check
$fileSystemRights = "Modify" Write-host "`nChecking Mods Directory:" -ForegroundColor Yellow
$type = "Allow" . "$WingetUpdatePath\functions\Invoke-ModsProtect.ps1"
$fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type $Protected = Invoke-ModsProtect "$WingetUpdatePath\mods"
$fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList if ($Protected -eq $True) {
$NewAcl.SetAccessRule($fileSystemAccessRule) Write-Host "The mods directory is now secured!`n" -ForegroundColor Green
Set-Acl -Path $LogFile -AclObject $NewAcl }
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 #Create Shortcuts
@ -425,6 +432,9 @@ function Uninstall-WingetAutoUpdate {
if (!$NoClean) { if (!$NoClean) {
Remove-Item $InstallLocation -Force -Recurse 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
}
} }
else { else {
#Keep critical files #Keep critical files
@ -506,6 +516,12 @@ function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) {
$Shortcut.Save() $Shortcut.Save()
} }
<# APP INFO #>
$WAUVersion = Get-Content "$PSScriptRoot\Winget-AutoUpdate\Version.txt" -ErrorAction SilentlyContinue
<# MAIN #> <# MAIN #>
#If running as a 32-bit process on an x64 system, re-launch as a 64-bit process #If running as a 32-bit process on an x64 system, re-launch as a 64-bit process
@ -540,5 +556,6 @@ else {
Uninstall-WingetAutoUpdate Uninstall-WingetAutoUpdate
} }
Remove-Item "$WingetUpdatePath\Version.txt" -Force
Write-host "`nEnd of process." -ForegroundColor Cyan Write-host "`nEnd of process." -ForegroundColor Cyan
Start-Sleep 3 Start-Sleep 3

View File

@ -55,7 +55,7 @@ if ($Logs) {
#Not available yet #Not available yet
$Message = $NotifLocale.local.outputs.output[5].message $Message = $NotifLocale.local.outputs.output[5].message
$MessageType = "warning" $MessageType = "warning"
Start-NotifTask -Message $Message -MessageType $MessageType Start-NotifTask -Message $Message -MessageType $MessageType -UserRun
} }
} }
elseif ($Help) { elseif ($Help) {
@ -79,7 +79,7 @@ else {
if (Test-WAUisRunning) { if (Test-WAUisRunning) {
$Message = $NotifLocale.local.outputs.output[8].message $Message = $NotifLocale.local.outputs.output[8].message
$MessageType = "warning" $MessageType = "warning"
Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun
break break
} }
#Run scheduled task #Run scheduled task
@ -87,7 +87,7 @@ else {
#Starting check - Send notification #Starting check - Send notification
$Message = $NotifLocale.local.outputs.output[6].message $Message = $NotifLocale.local.outputs.output[6].message
$MessageType = "info" $MessageType = "info"
Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun
#Sleep until the task is done #Sleep until the task is done
While (Test-WAUisRunning) { While (Test-WAUisRunning) {
Start-Sleep 3 Start-Sleep 3
@ -105,12 +105,12 @@ else {
$MessageType = "success" $MessageType = "success"
$Message = $NotifLocale.local.outputs.output[9].message $Message = $NotifLocale.local.outputs.output[9].message
} }
Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun
} }
catch { catch {
#Check failed - Just send notification #Check failed - Just send notification
$Message = $NotifLocale.local.outputs.output[7].message $Message = $NotifLocale.local.outputs.output[7].message
$MessageType = "error" $MessageType = "error"
Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss Start-NotifTask -Message $Message -MessageType $MessageType -Button1Text $Button1Text -Button1Action $OnClickAction -ButtonDismiss -UserRun
} }
} }

View File

@ -0,0 +1 @@
1.17.4

View File

@ -3,7 +3,7 @@
Uninstall Winget-AutoUpdate Uninstall Winget-AutoUpdate
.DESCRIPTION .DESCRIPTION
Uninstall Winget-AutoUpdate (DEFAULT: clean old install) Uninstalls Winget-AutoUpdate (DEFAULT: clean old install)
https://github.com/Romanitho/Winget-AutoUpdate https://github.com/Romanitho/Winget-AutoUpdate
.PARAMETER NoClean .PARAMETER NoClean

View File

@ -1,4 +1,4 @@
#Send Notif Script #Send Notify Script
#get xml notif config #get xml notif config
$WAUinstalledPath = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\" -Name InstallLocation $WAUinstalledPath = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate\" -Name InstallLocation

View File

@ -1,6 +1,6 @@
<# LOAD FUNCTIONS #> <# LOAD FUNCTIONS #>
#Get Working Dir #Get the Working Dir
$Script:WorkingDir = $PSScriptRoot $Script:WorkingDir = $PSScriptRoot
#Get Functions #Get Functions
Get-ChildItem "$WorkingDir\functions" | ForEach-Object { . $_.FullName } Get-ChildItem "$WorkingDir\functions" | ForEach-Object { . $_.FullName }
@ -19,17 +19,17 @@ $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Cur
#Log running context and more... #Log running context and more...
if ($IsSystem) { if ($IsSystem) {
Write-Log "Running in System context" Write-ToLog "Running in System context"
#Get and set Domain/Local Policies (GPO) #Get and set Domain/Local Policies (GPO)
$ActivateGPOManagement, $ChangedSettings = Get-Policies $ActivateGPOManagement, $ChangedSettings = Get-Policies
if ($ActivateGPOManagement) { if ($ActivateGPOManagement) {
Write-Log "Activated WAU GPO Management detected, comparing..." Write-ToLog "Activated WAU GPO Management detected, comparing..."
if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) {
Write-Log "Changed settings detected and applied" "Yellow" Write-ToLog "Changed settings detected and applied" "Yellow"
} }
else { else {
Write-Log "No Changed settings detected" "Yellow" Write-ToLog "No Changed settings detected" "Yellow"
} }
} }
@ -54,7 +54,7 @@ if ($IsSystem) {
#LogRotation if System #LogRotation if System
$LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize $LogRotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize
if ($LogRotate -eq $False) { if ($LogRotate -eq $False) {
Write-Log "An Exception occured during Log Rotation..." Write-ToLog "An Exception occured during Log Rotation..."
} }
#Run post update actions if necessary if run as System #Run post update actions if necessary if run as System
@ -66,12 +66,12 @@ if ($IsSystem) {
Add-ScopeMachine $SettingsPath Add-ScopeMachine $SettingsPath
} }
else { else {
Write-Log "Running in User context" Write-ToLog "Running in User context"
} }
#Get Notif Locale function #Get Notif Locale function
$LocaleDisplayName = Get-NotifLocale $LocaleDisplayName = Get-NotifLocale
Write-Log "Notification Level: $($WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" "Cyan" Write-ToLog "Notification Level: $($WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" "Cyan"
#Check network connectivity #Check network connectivity
if (Test-Network) { if (Test-Network) {
@ -81,26 +81,26 @@ if (Test-Network) {
if ($TestWinget) { if ($TestWinget) {
#Get Current Version #Get Current Version
$WAUCurrentVersion = $WAUConfig.DisplayVersion $WAUCurrentVersion = $WAUConfig.DisplayVersion
Write-Log "WAU current version: $WAUCurrentVersion" Write-ToLog "WAU current version: $WAUCurrentVersion"
if ($IsSystem) { if ($IsSystem) {
#Check if WAU update feature is enabled or not if run as System #Check if WAU update feature is enabled or not if run as System
$WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate $WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate
#If yes then check WAU update if run as System #If yes then check WAU update if run as System
if ($WAUDisableAutoUpdate -eq 1) { if ($WAUDisableAutoUpdate -eq 1) {
Write-Log "WAU AutoUpdate is Disabled." "Grey" Write-ToLog "WAU AutoUpdate is Disabled." "Gray"
} }
else { else {
Write-Log "WAU AutoUpdate is Enabled." "Green" Write-ToLog "WAU AutoUpdate is Enabled." "Green"
#Get Available Version #Get Available Version
$WAUAvailableVersion = Get-WAUAvailableVersion $Script:WAUAvailableVersion = Get-WAUAvailableVersion
#Compare #Compare
if ([version]$WAUAvailableVersion -gt [version]$WAUCurrentVersion) { if ([version]$WAUAvailableVersion.Replace("-", ".") -ne [version]$WAUCurrentVersion.Replace("-", ".")) {
#If new version is available, update it #If new version is available, update it
Write-Log "WAU Available version: $WAUAvailableVersion" "Yellow" Write-ToLog "WAU Available version: $WAUAvailableVersion" "Yellow"
Update-WAU Update-WAU
} }
else { else {
Write-Log "WAU is up to date." "Green" Write-ToLog "WAU is up to date." "Green"
} }
} }
@ -111,25 +111,36 @@ if (Test-Network) {
#Get External ListPath if run as System #Get External ListPath if run as System
if ($WAUConfig.WAU_ListPath) { if ($WAUConfig.WAU_ListPath) {
Write-Log "WAU uses External Lists from: $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/"))" $ListPathClean = $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/"))
if ($($WAUConfig.WAU_ListPath) -ne "GPO") { Write-ToLog "WAU uses External Lists from: $ListPathClean"
$NewList = Test-ListPath $WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/") $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(" ", "\") if ($ListPathClean -ne "GPO") {
$NewList = Test-ListPath $ListPathClean $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(" ", "\")
if ($ReachNoPath) { if ($ReachNoPath) {
Write-Log "Couldn't reach/find/compare/copy from $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/"))..." "Red" 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 $Script:ReachNoPath = $False
} }
if ($NewList) { if ($NewList) {
Write-Log "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))" "Yellow" Write-ToLog "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))" "Yellow"
} }
else { else {
if ($WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\included_apps.txt")) { if ($WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\included_apps.txt")) {
Write-Log "List (white) is up to date." "Green" Write-ToLog "List (white) is up to date." "Green"
} }
elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\excluded_apps.txt")) { elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\excluded_apps.txt")) {
Write-Log "List (black) is up to date." "Green" Write-ToLog "List (black) is up to date." "Green"
} }
else { else {
Write-Log "Critical: White/Black List doesn't exist, exiting..." "Red" 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 New-Item "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist" -Force
Exit 1 Exit 1
} }
@ -139,25 +150,31 @@ if (Test-Network) {
#Get External ModsPath if run as System #Get External ModsPath if run as System
if ($WAUConfig.WAU_ModsPath) { if ($WAUConfig.WAU_ModsPath) {
Write-Log "WAU uses External Mods from: $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/"))" $ModsPathClean = $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/"))
$NewMods, $DeletedMods = Test-ModsPath $WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/") $WAUConfig.InstallLocation.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) { if ($ReachNoPath) {
Write-Log "Couldn't reach/find/compare/copy from $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/"))..." "Red" Write-ToLog "Couldn't reach/find/compare/copy from $ModsPathClean..." "Red"
$Script:ReachNoPath = $False $Script:ReachNoPath = $False
} }
if ($NewMods -gt 0) { if ($NewMods -gt 0) {
Write-Log "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Yellow" Write-ToLog "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Yellow"
} }
else { else {
if (Test-Path "$WorkingDir\mods\*.ps1") { if (Test-Path "$WorkingDir\mods\*.ps1") {
Write-Log "Mods are up to date." "Green" Write-ToLog "Mods are up to date." "Green"
} }
else { else {
Write-Log "No Mods are implemented..." "Yellow" Write-ToLog "No Mods are implemented..." "Yellow"
} }
} }
if ($DeletedMods -gt 0) { if ($DeletedMods -gt 0) {
Write-Log "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Red" Write-ToLog "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Red"
} }
} }
} }
@ -168,12 +185,12 @@ if (Test-Network) {
#Get White or Black list #Get White or Black list
if ($WAUConfig.WAU_UseWhiteList -eq 1) { if ($WAUConfig.WAU_UseWhiteList -eq 1) {
Write-Log "WAU uses White List config" Write-ToLog "WAU uses White List config"
$toUpdate = Get-IncludedApps $toUpdate = Get-IncludedApps
$UseWhiteList = $true $UseWhiteList = $true
} }
else { else {
Write-Log "WAU uses Black List config" Write-ToLog "WAU uses Black List config"
$toSkip = Get-ExcludedApps $toSkip = Get-ExcludedApps
} }
@ -182,7 +199,7 @@ if (Test-Network) {
if ($UseWhiteList) { if ($UseWhiteList) {
$WhiteList = $toUpdate.GetUpperBound(0) $WhiteList = $toUpdate.GetUpperBound(0)
if ($null -eq $WhiteList) { if ($null -eq $WhiteList) {
Write-Log "Critical: Whitelist doesn't exist in GPO, exiting..." "Red" 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 New-Item "$WorkingDir\logs\error.txt" -Value "Whitelist doesn't exist in GPO" -Force
Exit 1 Exit 1
} }
@ -191,7 +208,7 @@ if (Test-Network) {
else { else {
$BlackList = $toSkip.GetUpperBound(0) $BlackList = $toSkip.GetUpperBound(0)
if ($null -eq $BlackList) { if ($null -eq $BlackList) {
Write-Log "Critical: Blacklist doesn't exist in GPO, exiting..." "Red" 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 New-Item "$WorkingDir\logs\error.txt" -Value "Blacklist doesn't exist in GPO" -Force
Exit 1 Exit 1
} }
@ -200,114 +217,114 @@ if (Test-Network) {
} }
#Get outdated Winget packages #Get outdated Winget packages
Write-Log "Checking application updates on Winget Repository..." "yellow" Write-ToLog "Checking application updates on Winget Repository..." "yellow"
$outdated = Get-WingetOutdatedApps $outdated = Get-WingetOutdatedApps
#If something is wrong with the winget source, exit #If something unusual happened
if ($outdated -like "Problem:*") { if ($outdated -like "An unusual*") {
Write-Log "Critical: An error occured, exiting..." "red" Write-ToLog "$outdated" "cyan"
Write-Log "$outdated" "red" $outdated = $False
New-Item "$WorkingDir\logs\error.txt" -Value "$outdated" -Force
Exit 1
} }
#Log list of app to update #Run only if $outdated is populated!
foreach ($app in $outdated) { if ($outdated) {
#List available updates #Log list of app to update
$Log = "-> Available update : $($app.Name). Current version : $($app.Version). Available version : $($app.AvailableVersion)." foreach ($app in $outdated) {
$Log | Write-host #List available updates
$Log | out-file -filepath $LogFile -Append $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 #Count good update installations
$Script:InstallOK = 0 $Script:InstallOK = 0
#Trick under user context when -BypassListForUsers is used #Trick under user context when -BypassListForUsers is used
if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq $true) { if ($IsSystem -eq $false -and $WAUConfig.WAU_BypassListForUsers -eq $true) {
Write-Log "Bypass system list in user context is Enabled." Write-ToLog "Bypass system list in user context is Enabled."
$UseWhiteList = $false $UseWhiteList = $false
$toSkip = $null $toSkip = $null
} }
#If White List #If White List
if ($UseWhiteList) { if ($UseWhiteList) {
#For each app, notify and update #For each app, notify and update
foreach ($app in $outdated) { foreach ($app in $outdated) {
if (($toUpdate -contains $app.Id) -and $($app.Version) -ne "Unknown") { if (($toUpdate -contains $app.Id) -and $($app.Version) -ne "Unknown") {
Update-App $app Update-App $app
} }
#if current app version is unknown #if current app version is unknown
elseif ($($app.Version) -eq "Unknown") { elseif ($($app.Version) -eq "Unknown") {
Write-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray"
} }
#if app is in "excluded list" #if app is in "excluded list"
else { else {
Write-Log "$($app.Name) : Skipped upgrade because it is not in the included app list" "Gray" Write-ToLog "$($app.Name) : Skipped upgrade because it is not in the included app list" "Gray"
}
} }
} }
} #If Black List or default
#If Black List or default else {
else { #For each app, notify and update
#For each app, notify and update foreach ($app in $outdated) {
foreach ($app in $outdated) { if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne "Unknown") {
if (-not ($toSkip -contains $app.Id) -and $($app.Version) -ne "Unknown") { Update-App $app
Update-App $app }
} #if current app version is unknown
#if current app version is unknown elseif ($($app.Version) -eq "Unknown") {
elseif ($($app.Version) -eq "Unknown") { Write-ToLog "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray"
Write-Log "$($app.Name) : Skipped upgrade because current version is 'Unknown'" "Gray" }
} #if app is in "excluded list"
#if app is in "excluded list" else {
else { Write-ToLog "$($app.Name) : Skipped upgrade because it is in the excluded app list" "Gray"
Write-Log "$($app.Name) : Skipped upgrade because it is in the excluded app list" "Gray" }
} }
} }
if ($InstallOK -gt 0) {
Write-ToLog "$InstallOK apps updated ! No more update." "Green"
}
} }
if ($InstallOK -gt 0) { if ($InstallOK -eq 0 -or !$InstallOK) {
Write-Log "$InstallOK apps updated ! No more update." "Green" Write-ToLog "No new update." "Green"
}
if ($InstallOK -eq 0) {
Write-Log "No new update." "Green"
} }
#Check if any user is logged on if System and run User task (if installed) #Check if any user is logged on if System and run User task (if installed)
if ($IsSystem) { if ($IsSystem) {
#User check routine from: https://stackoverflow.com/questions/23219718/powershell-script-to-see-currently-logged-in-users-domain-and-machine-status #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) $explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue)
If ($explorerprocesses.Count -eq 0) If ($explorerprocesses.Count -eq 0) {
{ Write-ToLog "No explorer process found / Nobody interactively logged on..."
Write-Log "No explorer process found / Nobody interactively logged on..."
} }
Else Else {
{
#Run WAU in user context if the user task exist #Run WAU in user context if the user task exist
$UserScheduledTask = Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue $UserScheduledTask = Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue
if ($UserScheduledTask) { if ($UserScheduledTask) {
#Get Winget system apps to excape them befor running user context #Get Winget system apps to excape them befor running user context
Write-Log "User logged on, get a list of installed Winget apps in System context..." Write-ToLog "User logged on, get a list of installed Winget apps in System context..."
Get-WingetSystemApps Get-WingetSystemApps
#Run user context scheduled task #Run user context scheduled task
Write-Log "Starting WAU in User context" Write-ToLog "Starting WAU in User context"
Start-ScheduledTask $UserScheduledTask.TaskName -ErrorAction SilentlyContinue Start-ScheduledTask $UserScheduledTask.TaskName -ErrorAction SilentlyContinue
Exit 0 Exit 0
} }
elseif (!$UserScheduledTask){ elseif (!$UserScheduledTask) {
Write-Log "User context execution not installed..." Write-ToLog "User context execution not installed..."
} }
} }
} }
} }
else { else {
Write-Log "Critical: Winget not installed or detected, exiting..." "red" Write-ToLog "Critical: Winget not installed or detected, exiting..." "red"
New-Item "$WorkingDir\logs\error.txt" -Value "Winget not installed or detected" -Force New-Item "$WorkingDir\logs\error.txt" -Value "Winget not installed or detected" -Force
Write-Log "End of process!" "Cyan" Write-ToLog "End of process!" "Cyan"
Exit 1 Exit 1
} }
} }
#End #End
Write-Log "End of process!" "Cyan" Write-ToLog "End of process!" "Cyan"
Start-Sleep 3 Start-Sleep 3

View File

@ -1,4 +1,4 @@
#Function to configure prefered scope option as Machine #Function to configure the prefered scope option as Machine
function Add-ScopeMachine ($SettingsPath) { function Add-ScopeMachine ($SettingsPath) {
if (Test-Path $SettingsPath) { if (Test-Path $SettingsPath) {

View File

@ -1,4 +1,4 @@
#Function for creating shortcuts #Function to create shortcuts
function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) { function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) {
$WScriptShell = New-Object -ComObject WScript.Shell $WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($Shortcut) $Shortcut = $WScriptShell.CreateShortcut($Shortcut)

View File

@ -0,0 +1,50 @@
#Function to get AZCopy, if it doesn't exist and update it, if it does
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
if ($null -eq $AZCopyLatestVersion -or "" -eq $AZCopyLatestVersion) {
$AZCopyLatestVersion = "0.0.0"
}
if (Test-Path -Path "$WingetUpdatePath\azcopy.exe" -PathType Leaf) {
$AZCopyCurrentVersion = & "$WingetUpdatePath\azcopy.exe" -v
$AZCopyCurrentVersion = $AZCopyVersionRegex.Match($AZCopyCurrentVersion).Value
Write-ToLog "AZCopy version $AZCopyCurrentVersion found"
}
else {
Write-ToLog "AZCopy not already installed"
$AZCopyCurrentVersion = "0.0.0"
}
if (([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"
Expand-archive -Path "$WingetUpdatePath\azcopyv10.zip" -Destinationpath "$WingetUpdatePath" -Force
$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"
}
}

View File

@ -1,4 +1,4 @@
#Get App Info #Get the winget App Information
Function Get-AppInfo ($AppID) { Function Get-AppInfo ($AppID) {
#Get AppID Info #Get AppID Info

View File

@ -1,26 +1,26 @@
#Function to get Black List apps #Function to get the Block List apps
function Get-ExcludedApps { function Get-ExcludedApps {
if ($GPOList) { if ($GPOList) {
if (Test-Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList") { if (Test-Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList") {
$Key = 'HKEY_LOCAL_MACHINE\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 $ValueNames = (Get-Item -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\BlackList").Property
foreach ($ValueName in $ValueNames) { foreach ($ValueName in $ValueNames) {
$AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false)
[PSCustomObject]@{ [PSCustomObject]@{
Value = $ValueName Value = $ValueName
Data = $AppIDs.Trim() Data = $AppIDs.Trim()
} }
} }
} }
return $AppIDs return $AppIDs
} }
elseif (Test-Path "$WorkingDir\excluded_apps.txt") { elseif (Test-Path "$WorkingDir\excluded_apps.txt") {

View File

@ -1,4 +1,4 @@
#Function to get White List apps #Function to get the allow List apps
function Get-IncludedApps { function Get-IncludedApps {
@ -9,15 +9,15 @@ function Get-IncludedApps {
$Key = 'HKEY_LOCAL_MACHINE\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 $ValueNames = (Get-Item -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate\WhiteList").Property
foreach ($ValueName in $ValueNames) { foreach ($ValueName in $ValueNames) {
$AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false) $AppIDs = [Microsoft.Win32.Registry]::GetValue($Key, $ValueName, $false)
[PSCustomObject]@{ [PSCustomObject]@{
Value = $ValueName Value = $ValueName
Data = $AppIDs.Trim() Data = $AppIDs.Trim()
} }
} }
} }
return $AppIDs return $AppIDs

View File

@ -1,9 +1,9 @@
#Function to get locale file for Notification. #Function to get the locale file for notifications
Function Get-NotifLocale { Function Get-NotifLocale {
#Get OS locale #Get OS locale
$OSLocale = (Get-Culture).Parent $OSLocale = (Get-UICulture).Parent
#Test if OS locale notif file exists #Test if OS locale notif file exists
$TestOSLocalPath = "$WorkingDir\locale\$($OSLocale.Name).xml" $TestOSLocalPath = "$WorkingDir\locale\$($OSLocale.Name).xml"

View File

@ -1,4 +1,4 @@
#Function to get Domain/Local Policies (GPO) #Function to get the Domain/Local Policies (GPO)
Function Get-Policies { Function Get-Policies {
#Get WAU Policies and set the Configurations Registry Accordingly #Get WAU Policies and set the Configurations Registry Accordingly
@ -15,7 +15,7 @@ Function Get-Policies {
Remove-ItemProperty $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue | Out-Null Remove-ItemProperty $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) { if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) {
New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -24,7 +24,7 @@ Function Get-Policies {
Remove-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue | Out-Null Remove-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) { if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) {
New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -33,7 +33,7 @@ Function Get-Policies {
New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) { if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) {
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -42,7 +42,7 @@ Function Get-Policies {
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) { if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) {
New-ItemProperty $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -51,7 +51,7 @@ Function Get-Policies {
Remove-ItemProperty $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue | Out-Null Remove-ItemProperty $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) { if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) {
New-ItemProperty $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(" ", "\", "/")) -Force | Out-Null New-ItemProperty $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -60,7 +60,7 @@ Function Get-Policies {
Remove-ItemProperty $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue | Out-Null Remove-ItemProperty $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++ $ChangedSettings++
} }
if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) { if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) {
New-ItemProperty $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(" ", "\", "/")) -Force | Out-Null New-ItemProperty $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++ $ChangedSettings++
@ -69,6 +69,14 @@ Function Get-Policies {
Remove-ItemProperty $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue | Out-Null Remove-ItemProperty $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++ $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++
}
if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) { if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) {
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force | Out-Null New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force | Out-Null
@ -87,14 +95,14 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){ if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) {
$PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0,11) $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11)
$PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19,6) $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6)
$Boundary = $PreStartBoundary + $($WAUPolicies.WAU_UpdatesAtTime) + $PostStartBoundary $Boundary = $PreStartBoundary + $($WAUPolicies.WAU_UpdatesAtTime) + $PostStartBoundary
$definition.Triggers.Item($triggerId).StartBoundary = $Boundary $definition.Triggers.Item($triggerId).StartBoundary = $Boundary
break break
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
@ -108,14 +116,14 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){ if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) {
$PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0,11) $PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0, 11)
$PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19,6) $PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19, 6)
$Boundary = $PreStartBoundary + "06:00:00" + $PostStartBoundary $Boundary = $PreStartBoundary + "06:00:00" + $PostStartBoundary
$definition.Triggers.Item($triggerId).StartBoundary = $Boundary $definition.Triggers.Item($triggerId).StartBoundary = $Boundary
break break
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
@ -129,11 +137,11 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){ if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) {
$UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11,8) $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8)
$definition.Triggers.Remove($triggerId) $definition.Triggers.Remove($triggerId)
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
@ -152,11 +160,11 @@ Function Get-Policies {
$definition = $task.Definition $definition = $task.Definition
$definition.Triggers.Count | Out-Null $definition.Triggers.Count | Out-Null
switch ($($WAUPolicies.WAU_UpdatesInterval)) { switch ($($WAUPolicies.WAU_UpdatesInterval)) {
"Daily" {$tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime); break} "Daily" { $tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime); break }
"BiDaily" {$tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) -DaysInterval 2; 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} "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} "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} "Monthly" { $tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 4; break }
} }
if ($definition.Triggers.Count -gt 0) { if ($definition.Triggers.Count -gt 0) {
$triggers = @() $triggers = @()
@ -177,11 +185,11 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){ if (($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")) {
$UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11,8) $UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11, 8)
$definition.Triggers.Remove($triggerId) $definition.Triggers.Remove($triggerId)
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
@ -223,15 +231,17 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
$definition.Triggers.Count | Out-Null $triggerLogon = $false
if ($definition.Triggers.Count -gt 0) { foreach ($trigger in $definition.Triggers) {
if ($trigger.Type -eq "9") {
$triggerLogon = $true
break
}
}
if (!$triggerLogon) {
$triggers += New-ScheduledTaskTrigger -AtLogon $triggers += New-ScheduledTaskTrigger -AtLogon
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers
} }
else {
$tasktrigger = New-ScheduledTaskTrigger -AtLogon
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger
}
} }
else { else {
New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null
@ -241,10 +251,10 @@ Function Get-Policies {
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
$definition.Triggers.Count | Out-Null $definition.Triggers.Count | Out-Null
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if($definition.Triggers.Item($triggerId).Type -eq "9"){ if ($definition.Triggers.Item($triggerId).Type -eq "9") {
$definition.Triggers.Remove($triggerId) $definition.Triggers.Remove($triggerId)
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
@ -258,10 +268,10 @@ Function Get-Policies {
$folder = $service.GetFolder('\') $folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate") $task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition $definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){ for ($triggerId = 1; $triggerId -le $definition.Triggers.Count; $triggerId++) {
if($definition.Triggers.Item($triggerId).Type -eq "9"){ if ($definition.Triggers.Item($triggerId).Type -eq "9") {
$definition.Triggers.Remove($triggerId) $definition.Triggers.Remove($triggerId)
$triggerId-=1 $triggerId -= 1
} }
} }
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null $folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null

View File

@ -1,4 +1,4 @@
#Function to get latest WAU available version on Github #Function to get the latest WAU available version on Github
function Get-WAUAvailableVersion { function Get-WAUAvailableVersion {
@ -6,7 +6,7 @@ function Get-WAUAvailableVersion {
if ($WAUConfig.WAU_UpdatePrerelease -eq 1) { if ($WAUConfig.WAU_UpdatePrerelease -eq 1) {
#Log #Log
Write-log "WAU AutoUpdate Pre-release versions is Enabled" "Cyan" Write-ToLog "WAU AutoUpdate Pre-release versions is Enabled" "Cyan"
#Get latest pre-release info #Get latest pre-release info
$WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases' $WAUurl = 'https://api.github.com/repos/Romanitho/Winget-AutoUpdate/releases'
@ -19,6 +19,7 @@ function Get-WAUAvailableVersion {
} }
#Return version
return ((Invoke-WebRequest $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace("v", "") return ((Invoke-WebRequest $WAUurl -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace("v", "")
} }

View File

@ -1,4 +1,4 @@
#Function to get Winget Command regarding execution context (User, System...) #Function to get the winget command regarding execution context (User, System...)
Function Get-WingetCmd { Function Get-WingetCmd {
@ -21,7 +21,7 @@ Function Get-WingetCmd {
$Script:Winget = "$WingetPath\winget.exe" $Script:Winget = "$WingetPath\winget.exe"
} }
else { else {
Write-Log "Winget not installed or detected !" "Red" Write-ToLog "Winget not installed or detected !" "Red"
return $false return $false
} }
@ -30,7 +30,7 @@ Function Get-WingetCmd {
#Log Winget installed version #Log Winget installed version
$WingetVer = & $Winget --version $WingetVer = & $Winget --version
Write-Log "Winget Version: $WingetVer" Write-ToLog "Winget Version: $WingetVer"
return $true return $true

View File

@ -1,4 +1,4 @@
#Function to get outdated app list, in formatted array #Function to get the outdated app list, in formatted array
function Get-WingetOutdatedApps { function Get-WingetOutdatedApps {
class Software { class Software {
@ -13,11 +13,11 @@ function Get-WingetOutdatedApps {
#Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling) #Start Convertion of winget format to an array. Check if "-----" exists (Winget Error Handling)
if (!($upgradeResult -match "-----")) { if (!($upgradeResult -match "-----")) {
return "Problem:`n$upgradeResult" return "An unusual thing happened (maybe all apps are upgraded):`n$upgradeResult"
} }
#Split winget output to lines #Split winget output to lines
$lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object { $_ -and $_ -notmatch "--include-unknown" } $lines = $upgradeResult.Split([Environment]::NewLine) | Where-Object { $_ }
# Find the line that starts with "------" # Find the line that starts with "------"
$fl = 0 $fl = 0
@ -38,9 +38,22 @@ function Get-WingetOutdatedApps {
# Now cycle in real package and split accordingly # Now cycle in real package and split accordingly
$upgradeList = @() $upgradeList = @()
For ($i = $fl + 2; $i -lt $lines.Length - 1; $i++) { For ($i = $fl + 2; $i -lt $lines.Length; $i++) {
$line = $lines[$i] $line = $lines[$i]
if ($line) { if ($line.StartsWith("-----")) {
#Get header line
$fl = $i - 1
#Get header titles
$index = $lines[$fl] -split '\s+'
# Line $fl has the header, we can find char where we find ID and Version
$idStart = $lines[$fl].IndexOf($index[1])
$versionStart = $lines[$fl].IndexOf($index[2])
$availableStart = $lines[$fl].IndexOf($index[3])
}
#(Alphanumeric | Literal . | Alphanumeric) - the only unique thing in common for lines with applications
if ($line -match "\w\.\w") {
$software = [Software]::new() $software = [Software]::new()
$software.Name = $line.Substring(0, $idStart).TrimEnd() $software.Name = $line.Substring(0, $idStart).TrimEnd()
$software.Id = $line.Substring($idStart, $versionStart - $idStart).TrimEnd() $software.Id = $line.Substring($idStart, $versionStart - $idStart).TrimEnd()

View File

@ -1,6 +1,6 @@
function Get-WingetSystemApps { function Get-WingetSystemApps {
#Json File where to export system installed apps #Json File, where to export system installed apps
$jsonFile = "$WorkingDir\winget_system_apps.txt" $jsonFile = "$WorkingDir\winget_system_apps.txt"
#Get list of installed Winget apps to json file #Get list of installed Winget apps to json file

View File

@ -1,4 +1,4 @@
#Function rotate the logs #Function to rotate the logs
function Invoke-LogRotation ($LogFile, $MaxLogFiles, $MaxLogSize) { function Invoke-LogRotation ($LogFile, $MaxLogFiles, $MaxLogSize) {
<# <#
@ -73,17 +73,17 @@ function Invoke-LogRotation ($LogFile, $MaxLogFiles, $MaxLogSize) {
#Log Header #Log Header
$Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################" $Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################"
$Log | out-file -filepath $LogFile -Append $Log | out-file -filepath $LogFile -Append
Write-Log "Running in System context" Write-ToLog "Running in System context"
if ($ActivateGPOManagement) { if ($ActivateGPOManagement) {
Write-Log "Activated WAU GPO Management detected, comparing..." Write-ToLog "Activated WAU GPO Management detected, comparing..."
if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) { if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) {
Write-Log "Changed settings detected and applied" "Yellow" Write-ToLog "Changed settings detected and applied" "Yellow"
} }
else { else {
Write-Log "No Changed settings detected" "Yellow" Write-ToLog "No Changed settings detected" "Yellow"
} }
} }
Write-Log "Max Log Size reached: $MaxLogSize bytes - Rotated Logs" Write-ToLog "Max Log Size reached: $MaxLogSize bytes - Rotated Logs"
Return $True Return $True
} }

View File

@ -0,0 +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 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"
}
}

View File

@ -1,9 +1,82 @@
#Function to make actions post WAU update #Function to make actions after WAU update
function Invoke-PostUpdateActions { function Invoke-PostUpdateActions {
#log #log
Write-Log "Running Post Update actions..." "yellow" Write-ToLog "Running Post Update actions:" "yellow"
#Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink
if ((Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs") -and !(Test-Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log")) {
Write-ToLog "-> Creating SymLink for log file in Intune Management Extension log folder" "yellow"
New-Item -Path "${env:ProgramData}\Microsoft\IntuneManagementExtension\Logs\WAU-updates.log" -ItemType SymbolicLink -Value $LogFile -Force -ErrorAction SilentlyContinue | Out-Null
}
Write-ToLog "-> Checking prerequisites..." "yellow"
#Check if Visual C++ 2019 or 2022 installed
$Visual2019 = "Microsoft Visual C++ 2015-2019 Redistributable*"
$Visual2022 = "Microsoft Visual C++ 2015-2022 Redistributable*"
$path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.GetValue("DisplayName") -like $Visual2019 -or $_.GetValue("DisplayName") -like $Visual2022 }
#If not installed, install
if (!($path)) {
try {
if ((Get-CimInStance Win32_OperatingSystem).OSArchitecture -like "*64*") {
$OSArch = "x64"
}
else {
$OSArch = "x86"
}
Write-ToLog "-> Downloading VC_redist.$OSArch.exe..."
$SourceURL = "https://aka.ms/vs/17/release/VC_redist.$OSArch.exe"
$Installer = "$($WAUConfig.InstallLocation)\VC_redist.$OSArch.exe"
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest $SourceURL -UseBasicParsing -OutFile (New-Item -Path $Installer -Force)
Write-ToLog "-> Installing VC_redist.$OSArch.exe..."
Start-Process -FilePath $Installer -Args "/quiet /norestart" -Wait
Remove-Item $Installer -ErrorAction Ignore
Write-ToLog "-> MS Visual C++ 2015-2022 installed successfully" "green"
}
catch {
Write-ToLog "-> MS Visual C++ 2015-2022 installation failed." "red"
}
}
else {
Write-ToLog "-> Prerequisites checked. OK" "green"
}
#Check Package Install
Write-ToLog "-> Checking if Winget is installed/up to date" "yellow"
$TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" }
#Current: v1.4.10173 = 1.19.10173.0 = 2023.118.406.0
If ([Version]$TestWinGet.Version -ge "2023.118.406.0") {
Write-ToLog "-> WinGet is Installed/up to date" "green"
}
Else {
#Download WinGet MSIXBundle
Write-ToLog "-> Not installed/up to date. Downloading WinGet..."
$WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.4.10173/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($WinGetURL, "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle")
#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"
}
#Remove WinGet MSIXBundle
Remove-Item -Path "$($WAUConfig.InstallLocation)\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -Force -ErrorAction Continue
}
#Reset Winget Sources #Reset Winget Sources
$ResolveWingetPath = Resolve-Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } $ResolveWingetPath = Resolve-Path "$env:programfiles\WindowsApps\Microsoft.DesktopAppInstaller_*_*__8wekyb3d8bbwe\winget.exe" | Sort-Object { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') }
@ -13,7 +86,7 @@ function Invoke-PostUpdateActions {
& $WingetPath source reset --force & $WingetPath source reset --force
#log #log
Write-Log "-> Winget sources reseted." "green" Write-ToLog "-> Winget sources reseted." "green"
} }
#Create WAU Regkey if not present #Create WAU Regkey if not present
@ -32,7 +105,7 @@ function Invoke-PostUpdateActions {
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force
#log #log
Write-Log "-> $regPath created." "green" Write-ToLog "-> $regPath created." "green"
} }
#Fix Notif where WAU_NotificationLevel is not set #Fix Notif where WAU_NotificationLevel is not set
$regNotif = Get-ItemProperty $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue $regNotif = Get-ItemProperty $regPath -Name WAU_NotificationLevel -ErrorAction SilentlyContinue
@ -40,7 +113,7 @@ function Invoke-PostUpdateActions {
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value Full -Force New-ItemProperty $regPath -Name WAU_NotificationLevel -Value Full -Force
#log #log
Write-Log "-> Notification level setting was missing. Fixed with 'Full' option." Write-ToLog "-> Notification level setting was missing. Fixed with 'Full' option."
} }
#Set WAU_MaxLogFiles/WAU_MaxLogSize if not set #Set WAU_MaxLogFiles/WAU_MaxLogSize if not set
@ -50,22 +123,51 @@ function Invoke-PostUpdateActions {
New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force | Out-Null New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force | Out-Null
#log #log
Write-Log "-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB)." Write-ToLog "-> MaxLogFiles/MaxLogSize setting was missing. Fixed with 3/1048576 (in bytes, default is 1048576 = 1 MB)."
} }
#Convert about.xml if exists (previous WAU versions) to reg #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-ToLog "-> 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-ToLog "-> ModsPath setting was missing. Fixed with empty string."
}
#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"
}
#Convert about.xml if exists (old WAU versions) to reg
$WAUAboutPath = "$WorkingDir\config\about.xml" $WAUAboutPath = "$WorkingDir\config\about.xml"
if (test-path $WAUAboutPath) { if (test-path $WAUAboutPath) {
[xml]$About = Get-Content $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue [xml]$About = Get-Content $WAUAboutPath -Encoding UTF8 -ErrorAction SilentlyContinue
New-ItemProperty $regPath -Name DisplayVersion -Value $About.app.version -Force New-ItemProperty $regPath -Name DisplayVersion -Value $About.app.version -Force
New-ItemProperty $regPath -Name VersionMajor -Value ([version]$About.app.version).Major -Force
New-ItemProperty $regPath -Name VersionMinor -Value ([version]$About.app.version).Minor -Force
#Remove file once converted #Remove file once converted
Remove-Item $WAUAboutPath -Force -Confirm:$false Remove-Item $WAUAboutPath -Force -Confirm:$false
#log #log
Write-Log "-> $WAUAboutPath converted." "green" Write-ToLog "-> $WAUAboutPath converted." "green"
} }
#Convert config.xml if exists (previous WAU versions) to reg #Convert config.xml if exists (previous WAU versions) to reg
@ -81,21 +183,34 @@ function Invoke-PostUpdateActions {
Remove-Item $WAUConfigPath -Force -Confirm:$false Remove-Item $WAUConfigPath -Force -Confirm:$false
#log #log
Write-Log "-> $WAUConfigPath converted." "green" Write-ToLog "-> $WAUConfigPath converted." "green"
} }
#Remove old functions #Remove old functions / files
$FileNames = @( $FileNames = @(
"$WorkingDir\functions\Get-WAUConfig.ps1", "$WorkingDir\functions\Get-WAUConfig.ps1",
"$WorkingDir\functions\Get-WAUCurrentVersion.ps1", "$WorkingDir\functions\Get-WAUCurrentVersion.ps1",
"$WorkingDir\functions\Get-WAUUpdateStatus.ps1" "$WorkingDir\functions\Get-WAUUpdateStatus.ps1",
"$WorkingDir\functions\Write-Log.ps1",
"$WorkingDir\Version.txt"
) )
foreach ($FileName in $FileNames) { foreach ($FileName in $FileNames) {
if (Test-Path $FileName) { if (Test-Path $FileName) {
Remove-Item $FileName -Force -Confirm:$false Remove-Item $FileName -Force -Confirm:$false
#log #log
Write-Log "-> $FileName removed." "green" Write-ToLog "-> $FileName removed." "green"
}
}
#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
} }
} }
@ -120,6 +235,6 @@ function Invoke-PostUpdateActions {
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate" $Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
#log #log
Write-Log "Post Update actions finished" "green" Write-ToLog "Post Update actions finished" "green"
} }

View File

@ -1,20 +1,25 @@
#Initialisation # Initialisation
function Start-Init { function Start-Init {
#Config console output encoding #Config console output encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
#Log Header $caller = Get-ChildItem $MyInvocation.PSCommandPath | Select-Object -Expand Name
$Log = "`n##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################" if ($caller -eq "Winget-Upgrade.ps1") {
$Log | Write-host #Log Header
$Log = "`n##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################"
#Logs initialisation $Log | Write-host
$Script:LogFile = "$WorkingDir\logs\updates.log" #Logs initialisation
$Script:LogFile = "$WorkingDir\logs\updates.log"
}
elseif ($caller -eq "Winget-AutoUpdate-Install.ps1") {
$Script:LogFile = "$WingetUpdatePath\logs\updates.log"
}
if (!(Test-Path $LogFile)) { if (!(Test-Path $LogFile)) {
#Create file if doesn't exist #Create file if doesn't exist
New-Item -ItemType File -Path $LogFile -Force New-Item -ItemType File -Path $LogFile -Force | Out-Null
#Set ACL for users on logfile #Set ACL for users on logfile
$NewAcl = Get-Acl -Path $LogFile $NewAcl = Get-Acl -Path $LogFile
@ -26,8 +31,28 @@ function Start-Init {
$NewAcl.SetAccessRule($fileSystemAccessRule) $NewAcl.SetAccessRule($fileSystemAccessRule)
Set-Acl -Path $LogFile -AclObject $NewAcl 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
}
#Log file #Check if Intune Management Extension Logs folder and WAU-updates.log exists, make symlink
$Log | out-file -filepath $LogFile -Append 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 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
}
if ($caller -eq "Winget-Upgrade.ps1") {
#Log file
$Log | out-file -filepath $LogFile -Append
}
} }

View File

@ -1,4 +1,4 @@
#Function to send notifications to user #Function to send the notifications to user
function Start-NotifTask { function Start-NotifTask {
@ -11,7 +11,8 @@ function Start-NotifTask {
[String]$Body, [String]$Body,
[String]$Button1Text, [String]$Button1Text,
[String]$Button1Action, [String]$Button1Action,
[Switch]$ButtonDismiss = $false [Switch]$ButtonDismiss = $false,
[Switch]$UserRun = $false
) )
if (($WAUConfig.WAU_NotificationLevel -eq "Full") -or ($WAUConfig.WAU_NotificationLevel -eq "SuccessOnly" -and $MessageType -eq "Success") -or (!$IsSystem)) { if (($WAUConfig.WAU_NotificationLevel -eq "Full") -or ($WAUConfig.WAU_NotificationLevel -eq "SuccessOnly" -and $MessageType -eq "Success") -or (!$IsSystem)) {
@ -31,7 +32,7 @@ function Start-NotifTask {
$XMLbinding.Attributes.Append($XMLbindingAtt1) | Out-Null $XMLbinding.Attributes.Append($XMLbindingAtt1) | Out-Null
$XMLimagepath = "$WorkingDir\icons\$MessageType.png" $XMLimagepath = "$WorkingDir\icons\$MessageType.png"
if (Test-Path $XMLimagepath){ if (Test-Path $XMLimagepath) {
# Creation of a image node # Creation of a image node
$XMLimage = $ToastTemplate.CreateElement("image") $XMLimage = $ToastTemplate.CreateElement("image")
$XMLbinding.AppendChild($XMLimage) | Out-Null $XMLbinding.AppendChild($XMLimage) | Out-Null
@ -43,7 +44,7 @@ function Start-NotifTask {
$XMLimage.Attributes.Append($XMLimageAtt2) | Out-Null $XMLimage.Attributes.Append($XMLimageAtt2) | Out-Null
} }
if ($Title){ if ($Title) {
# Creation of a text node # Creation of a text node
$XMLtitle = $ToastTemplate.CreateElement("text") $XMLtitle = $ToastTemplate.CreateElement("text")
$XMLtitleText = $ToastTemplate.CreateTextNode($Title) $XMLtitleText = $ToastTemplate.CreateTextNode($Title)
@ -51,7 +52,7 @@ function Start-NotifTask {
$XMLbinding.AppendChild($XMLtitle) | Out-Null $XMLbinding.AppendChild($XMLtitle) | Out-Null
} }
if ($Message){ if ($Message) {
# Creation of a text node # Creation of a text node
$XMLtext = $ToastTemplate.CreateElement("text") $XMLtext = $ToastTemplate.CreateElement("text")
$XMLtextText = $ToastTemplate.CreateTextNode($Message) $XMLtextText = $ToastTemplate.CreateTextNode($Message)
@ -59,7 +60,7 @@ function Start-NotifTask {
$XMLbinding.AppendChild($XMLtext) | Out-Null $XMLbinding.AppendChild($XMLtext) | Out-Null
} }
if ($Body){ if ($Body) {
# Creation of a group node # Creation of a group node
$XMLgroup = $ToastTemplate.CreateElement("group") $XMLgroup = $ToastTemplate.CreateElement("group")
$XMLbinding.AppendChild($XMLgroup) | Out-Null $XMLbinding.AppendChild($XMLgroup) | Out-Null
@ -91,7 +92,7 @@ function Start-NotifTask {
$XMLactionAtt1 = $ToastTemplate.CreateAttribute("content") $XMLactionAtt1 = $ToastTemplate.CreateAttribute("content")
$XMLactionAtt1.Value = $Button1Text $XMLactionAtt1.Value = $Button1Text
$XMLaction.Attributes.Append($XMLactionAtt1) | Out-Null $XMLaction.Attributes.Append($XMLactionAtt1) | Out-Null
if ($Button1Action){ if ($Button1Action) {
$XMLactionAtt2 = $ToastTemplate.CreateAttribute("arguments") $XMLactionAtt2 = $ToastTemplate.CreateAttribute("arguments")
$XMLactionAtt2.Value = $Button1Action $XMLactionAtt2.Value = $Button1Action
$XMLaction.Attributes.Append($XMLactionAtt2) | Out-Null $XMLaction.Attributes.Append($XMLactionAtt2) | Out-Null
@ -126,7 +127,7 @@ function Start-NotifTask {
$ToastTemplate.LastChild.AppendChild($XMLactions) | Out-Null $ToastTemplate.LastChild.AppendChild($XMLactions) | Out-Null
$ToastTemplate.LastChild.AppendChild($XMLtag) | Out-Null $ToastTemplate.LastChild.AppendChild($XMLtag) | Out-Null
if ($OnClickAction){ if ($OnClickAction) {
$ToastTemplate.toast.SetAttribute("activationType", "Protocol") | Out-Null $ToastTemplate.toast.SetAttribute("activationType", "Protocol") | Out-Null
$ToastTemplate.toast.SetAttribute("launch", $OnClickAction) | Out-Null $ToastTemplate.toast.SetAttribute("launch", $OnClickAction) | Out-Null
} }

View File

@ -1,4 +1,4 @@
#Function to check Black/White List External Path #Function to check Block/Allow List External Path
function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) { function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) {
# URL, UNC or Local Path # URL, UNC or Local Path
@ -37,8 +37,21 @@ function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) {
} }
} }
catch { catch {
$Script:ReachNoPath = $True try {
return $False $content = $wc.DownloadString("$ExternalList")
if ($null -ne $content -and $content -match "\w\.\w") {
$wc.DownloadFile($ExternalList, $LocalList)
return $true
}
else {
$Script:ReachNoPath = $True
return $False
}
}
catch {
$Script:ReachNoPath = $True
return $False
}
} }
} }
# If path is UNC or local # If path is UNC or local

View File

@ -1,4 +1,4 @@
#Function to check if modification exists in 'mods' directory #Function to check if modification exists within 'mods' directory
function Test-Mods ($app) { function Test-Mods ($app) {

View File

@ -1,6 +1,6 @@
#Function to check Mods External Path #Function to check mods External Path
function Test-ModsPath ($ModsPath, $WingetUpdatePath) { function Test-ModsPath ($ModsPath, $WingetUpdatePath, $AzureBlobSASURL) {
# URL, UNC or Local Path # URL, UNC or Local Path
# Get local and external Mods paths # Get local and external Mods paths
$LocalMods = -join ($WingetUpdatePath, "\", "mods") $LocalMods = -join ($WingetUpdatePath, "\", "mods")
@ -30,7 +30,7 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
# Collect the external list of href links # Collect the external list of href links
$BinLinks = $BinResponse.Links | Select-Object -ExpandProperty HREF $BinLinks = $BinResponse.Links | Select-Object -ExpandProperty HREF
#If there's a directory path in the HREF:s, delete it (IIS) #If there's a directory path in the HREF:s, delete it (IIS)
$CleanBinLinks = $BinLinks -replace "/.*/","" $CleanBinLinks = $BinLinks -replace "/.*/", ""
#Modify strings to HREF:s #Modify strings to HREF:s
$index = 0 $index = 0
foreach ($Bin in $CleanBinLinks) { foreach ($Bin in $CleanBinLinks) {
@ -41,14 +41,14 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
} }
#Delete Local Bins that don't exist Externally #Delete Local Bins that don't exist Externally
$index = 0 $index = 0
$CleanLinks = $BinLinks -replace "/.*/","" $CleanLinks = $BinLinks -replace "/.*/", ""
foreach ($Bin in $InternalBinsNames) { foreach ($Bin in $InternalBinsNames) {
If ($CleanLinks -notcontains "$Bin") { If ($CleanLinks -notcontains "$Bin") {
Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null
} }
$index++ $index++
} }
$CleanBinLinks = $BinLinks -replace "/.*/","" $CleanBinLinks = $BinLinks -replace "/.*/", ""
$Bin = "" $Bin = ""
#Loop through all links #Loop through all links
$wc = New-Object System.Net.WebClient $wc = New-Object System.Net.WebClient
@ -56,7 +56,7 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
#Check for .exe in listing/HREF:s in an index page pointing to .exe #Check for .exe in listing/HREF:s in an index page pointing to .exe
if ($_ -like "*.exe") { if ($_ -like "*.exe") {
$dateExternalBin = "" $dateExternalBin = ""
$dateLocalBin ="" $dateLocalBin = ""
$wc.OpenRead("$ExternalBins/$_").Close() | Out-Null $wc.OpenRead("$ExternalBins/$_").Close() | Out-Null
$dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss") $dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss")
if (Test-Path -Path $LocalMods"\bins\"$_) { if (Test-Path -Path $LocalMods"\bins\"$_) {
@ -64,7 +64,7 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
} }
if ($dateExternalBin -gt $dateLocalBin) { if ($dateExternalBin -gt $dateLocalBin) {
$SaveBin = Join-Path -Path "$LocalMods\bins" -ChildPath $_ $SaveBin = Join-Path -Path "$LocalMods\bins" -ChildPath $_
Invoke-WebRequest -Uri "$ExternalBins/$_" -OutFile $SaveBin.Replace("%20"," ") -UseBasicParsing Invoke-WebRequest -Uri "$ExternalBins/$_" -OutFile $SaveBin.Replace("%20", " ") -UseBasicParsing
} }
} }
} }
@ -74,8 +74,8 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
$ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF $ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF
#If there's a directory path in the HREF:s, delete it (IIS) #If there's a directory path in the HREF:s, delete it (IIS)
$CleanLinks = $ModLinks -replace "/.*/","" $CleanLinks = $ModLinks -replace "/.*/", ""
#Modify strings to HREF:s #Modify strings to HREF:s
$index = 0 $index = 0
foreach ($Mod in $CleanLinks) { foreach ($Mod in $CleanLinks) {
@ -88,7 +88,7 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
#Delete Local Mods that don't exist Externally #Delete Local Mods that don't exist Externally
$DeletedMods = 0 $DeletedMods = 0
$index = 0 $index = 0
$CleanLinks = $ModLinks -replace "/.*/","" $CleanLinks = $ModLinks -replace "/.*/", ""
foreach ($Mod in $InternalModsNames) { foreach ($Mod in $InternalModsNames) {
If ($CleanLinks -notcontains "$Mod") { If ($CleanLinks -notcontains "$Mod") {
Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null
@ -96,8 +96,8 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
} }
$index++ $index++
} }
$CleanLinks = $ModLinks -replace "/.*/","" $CleanLinks = $ModLinks -replace "/.*/", ""
#Loop through all links #Loop through all links
$wc = New-Object System.Net.WebClient $wc = New-Object System.Net.WebClient
@ -106,13 +106,13 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
if (($_ -like "*.ps1") -or ($_ -like "*.txt")) { if (($_ -like "*.ps1") -or ($_ -like "*.txt")) {
try { try {
$dateExternalMod = "" $dateExternalMod = ""
$dateLocalMod ="" $dateLocalMod = ""
$wc.OpenRead("$ExternalMods/$_").Close() | Out-Null $wc.OpenRead("$ExternalMods/$_").Close() | Out-Null
$dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss") $dateExternalMod = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss")
if (Test-Path -Path $LocalMods"\"$_) { if (Test-Path -Path $LocalMods"\"$_) {
$dateLocalMod = (Get-Item "$LocalMods\$_").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") $dateLocalMod = (Get-Item "$LocalMods\$_").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
} }
if ($dateExternalMod -gt $dateLocalMod) { if ($dateExternalMod -gt $dateLocalMod) {
try { try {
$SaveMod = Join-Path -Path "$LocalMods\" -ChildPath $_ $SaveMod = Join-Path -Path "$LocalMods\" -ChildPath $_
@ -134,21 +134,60 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
} }
return $ModsUpdated, $DeletedMods return $ModsUpdated, $DeletedMods
} }
# If Path is Azure Blob
elseif ($ExternalMods -like "AzureBlob") {
Write-ToLog "Azure Blob Storage set as mod source"
Write-ToLog "Checking AZCopy"
Get-AZCopy $WingetUpdatePath
#Safety check to make sure we really do have azcopy.exe and a Blob URL
if ((Test-Path -Path "$WingetUpdatePath\azcopy.exe" -PathType Leaf) -and ($null -ne $AzureBlobSASURL)) {
Write-ToLog "Syncing Blob storage with local storage"
$AZCopySyncOutput = & $WingetUpdatePath\azcopy.exe sync "$AzureBlobSASURL" "$LocalMods" --from-to BlobLocal --delete-destination=true
$AZCopyOutputLines = $AZCopySyncOutput.Split([Environment]::NewLine)
foreach ( $_ in $AZCopyOutputLines) {
$AZCopySyncAdditionsRegex = [regex]::new("(?<=Number of Copy Transfers Completed:\s+)\d+")
$AZCopySyncDeletionsRegex = [regex]::new("(?<=Number of Deletions at Destination:\s+)\d+")
$AZCopySyncErrorRegex = [regex]::new("^Cannot perform sync due to error:")
$AZCopyAdditions = [int] $AZCopySyncAdditionsRegex.Match($_).Value
$AZCopyDeletions = [int] $AZCopySyncDeletionsRegex.Match($_).Value
if ($AZCopyAdditions -ne 0) {
$ModsUpdated = $AZCopyAdditions
}
if ($AZCopyDeletions -ne 0) {
$DeletedMods = $AZCopyDeletions
}
if ($AZCopySyncErrorRegex.Match($_).Value) {
Write-ToLog "AZCopy Sync Error! $_"
}
}
}
else {
Write-ToLog "Error 'azcopy.exe' or SAS Token not found!"
}
return $ModsUpdated, $DeletedMods
}
# If path is UNC or local # If path is UNC or local
else { else {
$ExternalBins = "$ModsPath\bins" $ExternalBins = "$ModsPath\bins"
if (Test-Path -Path $ExternalBins"\*.exe") { if (Test-Path -Path $ExternalBins"\*.exe") {
$ExternalBinsNames = Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe $ExternalBinsNames = Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe
#Delete Local Bins that don't exist Externally #Delete Local Bins that don't exist Externally
foreach ($Bin in $InternalBinsNames){ foreach ($Bin in $InternalBinsNames) {
If ($Bin -notin $ExternalBinsNames ){ If ($Bin -notin $ExternalBinsNames ) {
Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null
} }
} }
#Copy newer external bins #Copy newer external bins
foreach ($Bin in $ExternalBinsNames){ foreach ($Bin in $ExternalBinsNames) {
$dateExternalBin = "" $dateExternalBin = ""
$dateLocalBin ="" $dateLocalBin = ""
if (Test-Path -Path $LocalMods"\bins\"$Bin) { if (Test-Path -Path $LocalMods"\bins\"$Bin) {
$dateLocalBin = (Get-Item "$LocalMods\bins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") $dateLocalBin = (Get-Item "$LocalMods\bins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
} }
@ -162,20 +201,20 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) { if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) {
#Get File Names Externally #Get File Names Externally
$ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt $ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt
#Delete Local Mods that don't exist Externally #Delete Local Mods that don't exist Externally
$DeletedMods = 0 $DeletedMods = 0
foreach ($Mod in $InternalModsNames){ foreach ($Mod in $InternalModsNames) {
If ($Mod -notin $ExternalModsNames ){ If ($Mod -notin $ExternalModsNames ) {
Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null
$DeletedMods++ $DeletedMods++
} }
} }
#Copy newer external mods #Copy newer external mods
foreach ($Mod in $ExternalModsNames){ foreach ($Mod in $ExternalModsNames) {
$dateExternalMod = "" $dateExternalMod = ""
$dateLocalMod ="" $dateLocalMod = ""
if (Test-Path -Path $LocalMods"\"$Mod) { if (Test-Path -Path $LocalMods"\"$Mod) {
$dateLocalMod = (Get-Item "$LocalMods\$Mod").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") $dateLocalMod = (Get-Item "$LocalMods\$Mod").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
} }

View File

@ -1,4 +1,4 @@
#Function to check connectivity #Function to check the connectivity
function Test-Network { function Test-Network {
@ -9,7 +9,7 @@ function Test-Network {
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
#Test connectivity during 30 min then timeout #Test connectivity during 30 min then timeout
Write-Log "Checking internet connection..." "Yellow" Write-ToLog "Checking internet connection..." "Yellow"
While ($timeout -lt 1800) { While ($timeout -lt 1800) {
$URLtoTest = "https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE" $URLtoTest = "https://raw.githubusercontent.com/Romanitho/Winget-AutoUpdate/main/LICENSE"
@ -17,7 +17,7 @@ function Test-Network {
if ($URLcontent -like "*MIT License*") { if ($URLcontent -like "*MIT License*") {
Write-Log "Connected !" "Green" Write-ToLog "Connected !" "Green"
#Check for metered connection #Check for metered connection
[void][Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime] [void][Windows.Networking.Connectivity.NetworkInformation, Windows, ContentType = WindowsRuntime]
@ -25,17 +25,17 @@ function Test-Network {
if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne "Unrestricted")) { if ($cost.ApproachingDataLimit -or $cost.OverDataLimit -or $cost.Roaming -or $cost.BackgroundDataUsageRestricted -or ($cost.NetworkCostType -ne "Unrestricted")) {
Write-Log "Metered connection detected." "Yellow" Write-ToLog "Metered connection detected." "Yellow"
if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) { if ($WAUConfig.WAU_DoNotRunOnMetered -eq 1) {
Write-Log "WAU is configured to bypass update checking on metered connection" Write-ToLog "WAU is configured to bypass update checking on metered connection"
return $false return $false
} }
else { else {
Write-Log "WAU is configured to force update checking on metered connection" Write-ToLog "WAU is configured to force update checking on metered connection"
return $true return $true
} }
@ -56,7 +56,7 @@ function Test-Network {
#Send Warning Notif if no connection for 5 min #Send Warning Notif if no connection for 5 min
if ($timeout -eq 300) { if ($timeout -eq 300) {
#Log #Log
Write-Log "Notify 'No connection' sent." "Yellow" Write-ToLog "Notify 'No connection' sent." "Yellow"
#Notif #Notif
$Title = $NotifLocale.local.outputs.output[0].title $Title = $NotifLocale.local.outputs.output[0].title
@ -71,7 +71,7 @@ function Test-Network {
} }
#Send Timeout Notif if no connection for 30 min #Send Timeout Notif if no connection for 30 min
Write-Log "Timeout. No internet connection !" "Red" Write-ToLog "Timeout. No internet connection !" "Red"
#Notif #Notif
$Title = $NotifLocale.local.outputs.output[1].title $Title = $NotifLocale.local.outputs.output[1].title

View File

@ -1,4 +1,4 @@
#Function to check if there's a Pending Reboot #Function to check if there is a Pending Reboot
function Test-PendingReboot { function Test-PendingReboot {

View File

@ -1,15 +1,15 @@
#Function to Update an App #Function to update an App
Function Update-App ($app) { Function Update-App ($app) {
#Get App Info #Get App Info
$ReleaseNoteURL = Get-AppInfo $app.Id $ReleaseNoteURL = Get-AppInfo $app.Id
if ($ReleaseNoteURL){ if ($ReleaseNoteURL) {
$Button1Text = $NotifLocale.local.outputs.output[10].message $Button1Text = $NotifLocale.local.outputs.output[10].message
} }
#Send available update notification #Send available update notification
Write-Log "Updating $($app.Name) from $($app.Version) to $($app.AvailableVersion)..." "Cyan" Write-ToLog "Updating $($app.Name) from $($app.Version) to $($app.AvailableVersion)..." "Cyan"
$Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name) $Title = $NotifLocale.local.outputs.output[2].title -f $($app.Name)
$Message = $NotifLocale.local.outputs.output[2].message -f $($app.Version), $($app.AvailableVersion) $Message = $NotifLocale.local.outputs.output[2].message -f $($app.Version), $($app.AvailableVersion)
$MessageType = "info" $MessageType = "info"
@ -20,26 +20,26 @@ Function Update-App ($app) {
$ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id) $ModsPreInstall, $ModsOverride, $ModsUpgrade, $ModsInstall, $ModsInstalled = Test-Mods $($app.Id)
#Winget upgrade #Winget upgrade
Write-Log "########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '$($App.Id)' ##########" "Gray" Write-ToLog "########## WINGET UPGRADE PROCESS STARTS FOR APPLICATION ID '$($App.Id)' ##########" "Gray"
#If PreInstall script exist #If PreInstall script exist
if ($ModsPreInstall) { if ($ModsPreInstall) {
Write-Log "Modifications for $($app.Id) before upgrade are being applied..." "Yellow" Write-ToLog "Modifications for $($app.Id) before upgrade are being applied..." "Yellow"
& "$ModsPreInstall" & "$ModsPreInstall"
} }
#Run Winget Upgrade command #Run Winget Upgrade command
if ($ModsOverride) { if ($ModsOverride) {
Write-Log "-> Running (overriding default): Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $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 & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -file $LogFile -Append
} }
else { else {
Write-Log "-> Running: Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h" 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 & $Winget upgrade --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -file $LogFile -Append
} }
if ($ModsUpgrade) { if ($ModsUpgrade) {
Write-Log "Modifications for $($app.Id) during upgrade are being applied..." "Yellow" Write-ToLog "Modifications for $($app.Id) during upgrade are being applied..." "Yellow"
& "$ModsUpgrade" & "$ModsUpgrade"
} }
@ -53,25 +53,25 @@ Function Update-App ($app) {
#Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities) #Test for a Pending Reboot (Component Based Servicing/WindowsUpdate/CCM_ClientUtilities)
$PendingReboot = Test-PendingReboot $PendingReboot = Test-PendingReboot
if ($PendingReboot -eq $true) { 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" 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 $FailedToUpgrade = $true
break break
} }
#If app failed to upgrade, run Install command #If app failed to upgrade, run Install command
Write-Log "-> An upgrade for $($app.Name) failed, now trying an install instead..." "Yellow" Write-ToLog "-> An upgrade for $($app.Name) failed, now trying an install instead..." "Yellow"
if ($ModsOverride) { if ($ModsOverride) {
Write-Log "-> Running (overriding default): Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride" Write-ToLog "-> Running (overriding default): Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride"
& $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -file $LogFile -Append & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements --override $ModsOverride | Tee-Object -file $LogFile -Append
} }
else { else {
Write-Log "-> Running: Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements -h" Write-ToLog "-> Running: Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements -h"
& $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -file $LogFile -Append & $Winget install --id $($app.Id) --accept-package-agreements --accept-source-agreements -h | Tee-Object -file $LogFile -Append
} }
if ($ModsInstall) { if ($ModsInstall) {
Write-Log "Modifications for $($app.Id) during install are being applied..." "Yellow" Write-ToLog "Modifications for $($app.Id) during install are being applied..." "Yellow"
& "$ModsInstall" & "$ModsInstall"
} }
@ -87,18 +87,18 @@ Function Update-App ($app) {
if ($FailedToUpgrade -eq $false) { if ($FailedToUpgrade -eq $false) {
if ($ModsInstalled) { if ($ModsInstalled) {
Write-Log "Modifications for $($app.Id) after upgrade/install are being applied..." "Yellow" Write-ToLog "Modifications for $($app.Id) after upgrade/install are being applied..." "Yellow"
& "$ModsInstalled" & "$ModsInstalled"
} }
} }
Write-Log "########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '$($App.Id)' ##########" "Gray" Write-ToLog "########## WINGET UPGRADE PROCESS FINISHED FOR APPLICATION ID '$($App.Id)' ##########" "Gray"
#Notify installation #Notify installation
if ($FailedToUpgrade -eq $false) { if ($FailedToUpgrade -eq $false) {
#Send success updated app notification #Send success updated app notification
Write-Log "$($app.Name) updated to $($app.AvailableVersion) !" "Green" Write-ToLog "$($app.Name) updated to $($app.AvailableVersion) !" "Green"
#Send Notif #Send Notif
$Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name) $Title = $NotifLocale.local.outputs.output[3].title -f $($app.Name)
@ -113,7 +113,7 @@ Function Update-App ($app) {
else { else {
#Send failed updated app notification #Send failed updated app notification
Write-Log "$($app.Name) update failed." "Red" Write-ToLog "$($app.Name) update failed." "Red"
#Send Notif #Send Notif
$Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name) $Title = $NotifLocale.local.outputs.output[4].title -f $($app.Name)

View File

@ -1,4 +1,4 @@
#Function to Update WAU #Function to update WAU
function Update-WAU { function Update-WAU {
@ -19,44 +19,44 @@ function Update-WAU {
New-Item $ZipFile -ItemType File -Force | Out-Null New-Item $ZipFile -ItemType File -Force | Out-Null
#Download the zip #Download the zip
Write-Log "Downloading the GitHub Repository version $WAUAvailableVersion" "Cyan" Write-ToLog "Downloading the GitHub Repository version $WAUAvailableVersion" "Cyan"
Invoke-RestMethod -Uri "https://github.com/Romanitho/Winget-AutoUpdate/archive/refs/tags/v$($WAUAvailableVersion).zip/" -OutFile $ZipFile Invoke-RestMethod -Uri "https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v$($WAUAvailableVersion)/WAU.zip" -OutFile $ZipFile
#Extract Zip File #Extract Zip File
Write-Log "Unzipping the WAU GitHub Repository" "Cyan" Write-ToLog "Unzipping the WAU Update package" "Cyan"
$location = "$WorkingDir\WAU_update" $location = "$WorkingDir\WAU_update"
Expand-Archive -Path $ZipFile -DestinationPath $location -Force Expand-Archive -Path $ZipFile -DestinationPath $location -Force
Get-ChildItem -Path $location -Recurse | Unblock-File Get-ChildItem -Path $location -Recurse | Unblock-File
#Update scritps #Update scritps
Write-Log "Updating WAU" "Yellow" Write-ToLog "Updating WAU..." "Yellow"
$TempPath = (Resolve-Path "$location\*\Winget-AutoUpdate\")[0].Path $TempPath = (Resolve-Path "$location\Winget-AutoUpdate\")[0].Path
if ($TempPath) { if ($TempPath) {
Copy-Item -Path "$TempPath\*" -Destination "$WorkingDir\" -Exclude "icons" -Recurse -Force Copy-Item -Path "$TempPath\*" -Destination "$WorkingDir\" -Exclude "icons" -Recurse -Force
} }
#Remove update zip file and update temp folder #Remove update zip file and update temp folder
Write-Log "Done. Cleaning temp files" "Cyan" Write-ToLog "Done. Cleaning temp files..." "Cyan"
Remove-Item -Path $ZipFile -Force -ErrorAction SilentlyContinue Remove-Item -Path $ZipFile -Force -ErrorAction SilentlyContinue
Remove-Item -Path $location -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path $location -Recurse -Force -ErrorAction SilentlyContinue
#Set new version to registry #Set new version to registry
$WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force $WAUConfig | New-ItemProperty -Name DisplayVersion -Value $WAUAvailableVersion -Force
$WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion).Major -Force $WAUConfig | New-ItemProperty -Name VersionMajor -Value ([version]$WAUAvailableVersion.Replace("-", ".")).Major -Force
$WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion).Minor -Force $WAUConfig | New-ItemProperty -Name VersionMinor -Value ([version]$WAUAvailableVersion.Replace("-", ".")).Minor -Force
#Set Post Update actions to 1 #Set Post Update actions to 1
$WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force $WAUConfig | New-ItemProperty -Name WAU_PostUpdateActions -Value 1 -Force
#Send success Notif #Send success Notif
Write-Log "WAU Update completed." "Green" Write-ToLog "WAU Update completed." "Green"
$Title = $NotifLocale.local.outputs.output[3].title -f "Winget-AutoUpdate" $Title = $NotifLocale.local.outputs.output[3].title -f "Winget-AutoUpdate"
$Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion $Message = $NotifLocale.local.outputs.output[3].message -f $WAUAvailableVersion
$MessageType = "success" $MessageType = "success"
Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text
#Rerun with newer version #Rerun with newer version
Write-Log "Re-run WAU" Write-ToLog "Re-run WAU"
Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`"" Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$WorkingDir\winget-upgrade.ps1`""
exit exit
@ -70,7 +70,7 @@ function Update-WAU {
$Message = $NotifLocale.local.outputs.output[4].message $Message = $NotifLocale.local.outputs.output[4].message
$MessageType = "error" $MessageType = "error"
Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text Start-NotifTask -Title $Title -Message $Message -MessageType $MessageType -Button1Action $OnClickAction -Button1Text $Button1Text
Write-Log "WAU Update failed" "Red" Write-ToLog "WAU Update failed" "Red"
} }

View File

@ -1,6 +1,6 @@
#Write Log Function #Write to Log Function
function Write-Log ($LogMsg, $LogColor = "White") { function Write-ToLog ($LogMsg, $LogColor = "White") {
#Get log #Get log
$Log = "$(Get-Date -UFormat "%T") - $LogMsg" $Log = "$(Get-Date -UFormat "%T") - $LogMsg"

View File

@ -49,6 +49,7 @@
<output id="9"> <output id="9">
<!--Manual check for updated apps completed--> <!--Manual check for updated apps completed-->
<message>Die manuelle suche nach Updates wurde abgeschlossen.</message> <message>Die manuelle suche nach Updates wurde abgeschlossen.</message>
</output>
<output id="10"> <output id="10">
<!--See changelog--> <!--See changelog-->
<message>See changelog</message> <message>See changelog</message>

View File

@ -43,8 +43,8 @@
<message>Couldn't start a manual check for updated apps!</message> <message>Couldn't start a manual check for updated apps!</message>
</output> </output>
<output id="8"> <output id="8">
<!--Check for updated apps already running--> <!--A check for updated apps already running-->
<message>Check for updated apps already running...</message> <message>A check for updated apps already running...</message>
</output> </output>
<output id="9"> <output id="9">
<!--Manual check for updated apps completed--> <!--Manual check for updated apps completed-->

View File

@ -0,0 +1,62 @@
<local>
<outputs>
<output id="0">
<!--Check network connection-->
<title>Sjekk nettverkstilkoblingen.</title>
<!--Unable to check for software updates at this time!-->
<message>Kan ikke se etter programvareoppdateringer for øyeblikket!</message>
</output>
<output id="1">
<!--No internet connection-->
<title>Ingen internettforbindelse.</title>
<!--Updates could not be verified-->
<message>Oppdateringer kunne ikke bekreftes.</message>
</output>
<output id="2">
<!--{App} will be updated-->
<title>{0} vil bli oppdatert!</title>
<!--{v1.0} to {v2.0}-->
<message>{0} til {1}</message>
</output>
<output id="3">
<!--{App} updated-->
<title>{0} oppdatert.</title>
<!--Installed version: {v1.0}-->
<message>Installert versjon: {0}</message>
</output>
<output id="4">
<!--{App} could not be updated-->
<title>{0} kunne ikke oppdateres!</title>
<!--Please contact support-->
<message>Vennligst kontakt support.</message>
</output>
<output id="5">
<!--Logs are not available yet-->
<message>Logger er ikke tilgjengelig ennå!</message>
</output>
<output id="6">
<!--Starting a manual check for updated apps-->
<message>Starter en manuell sjekk for oppdaterte apper...</message>
</output>
<output id="7">
<!--Couldn't start a manual check for updated apps-->
<message>Kunne ikke starte en manuell sjekk for oppdaterte apper!</message>
</output>
<output id="8">
<!--Check for updated apps already running-->
<message>Se etter oppdaterte apper kjører allerede...</message>
</output>
<output id="9">
<!--Manual check for updated apps completed-->
<message>Manuell sjekk for oppdaterte apper fullført...</message>
</output>
<output id="10">
<!--See changelog-->
<message>Se endringslogg</message>
</output>
<output id="11">
<!--Open log file-->
<message>Åpne loggfilen</message>
</output>
</outputs>
</local>

View File

@ -4,59 +4,59 @@
<!--Check network connection--> <!--Check network connection-->
<title>Controleer de netwerkverbinding.</title> <title>Controleer de netwerkverbinding.</title>
<!--Unable to check for software updates at this time!--> <!--Unable to check for software updates at this time!-->
<message>Er kan op dit moment niet gecontroleerd worden op software-updates!</message> <message>Er kan op dit moment niet gecontroleerd worden op software updates!</message>
</output> </output>
<output id="1"> <output id="1">
<!--No internet connction--> <!--No internet connction-->
<title>Geen internetverbinding.</title> <title>Geen internetverbinding.</title>
<!--Updates could not be verified--> <!--Updates could not be verified-->
<message>Updates kon niet worden gecontroleerd.</message> <message>Updates konden niet worden gecontroleerd.</message>
</output> </output>
<output id="2"> <output id="2">
<!--{App} will be updated--> <!--{App} will be updated-->
<title>{0} wordt geupdate!</title> <title>{0} zal geüpdatet worden !</title>
<!--{v1.0} to {v2.0}--> <!--{v1.0} to {v2.0}-->
<message>{0} to {1}</message> <message>{0} to {1}</message>
</output> </output>
<output id="3"> <output id="3">
<!--{App} updated--> <!--{App} updated-->
<title>{0} geupdate.</title> <title>{0} is geüpdatet.</title>
<!--Installed version: {v1.0}--> <!--Installed version: {v1.0}-->
<message>Geinstalleerde versie: {0}</message> <message>Geïnstalleerde versie: {0}</message>
</output> </output>
<output id="4"> <output id="4">
<!--{App} could not be updated--> <!--{App} could not be updated-->
<title>{0} kan niet worden geupdate!</title> <title>{0} kan niet worden geüpdatet!</title>
<!--Please contact support--> <!--Please contact support-->
<message>Neem contact op met support.</message> <message>Neem contact op met support.</message>
</output> </output>
<output id="5"> <output id="5">
<!--Logs are not available yet--> <!--Logs are not available yet-->
<message>Logs are not available yet!</message> <message>Logs zijn nog niet beschikbaar !</message>
</output> </output>
<output id="6"> <output id="6">
<!--Starting a manual check for updated apps--> <!--Starting a manual check for updated apps-->
<message>Starting a manual check for updated apps...</message> <message>Start een manuele controle op software updates...</message>
</output> </output>
<output id="7"> <output id="7">
<!--Couldn't start a manual check for updated apps--> <!--Couldn't start a manual check for updated apps-->
<message>Couldn't start a manual check for updated apps!</message> <message>Kon geen manuele controle op software updates starten!</message>
</output> </output>
<output id="8"> <output id="8">
<!--Check for updated apps already running--> <!--Check for updated apps already running-->
<message>Check for updated apps already running...</message> <message>Er wordt al naar software updates gezocht...</message>
</output> </output>
<output id="9"> <output id="9">
<!--Manual check for updated apps completed--> <!--Manual check for updated apps completed-->
<message>Manual check for updated apps completed...</message> <message>Manuele controle op software updates voltooid...</message>
</output> </output>
<output id="10"> <output id="10">
<!--See changelog--> <!--See changelog-->
<message>See changelog</message> <message>Zie changelog</message>
</output> </output>
<output id="11"> <output id="11">
<!--Open log file--> <!--Open log file-->
<message>Open log file</message> <message>Open logbestand</message>
</output> </output>
</outputs> </outputs>
</local> </local>

View File

@ -43,7 +43,7 @@
<message>Kunde inte starta en manuell koll efter uppdaterade appar!</message> <message>Kunde inte starta en manuell koll efter uppdaterade appar!</message>
</output> </output>
<output id="8"> <output id="8">
<!--Check for updated apps already running--> <!--A check for updated apps already running-->
<message>En koll efter uppdaterade appar körs redan...</message> <message>En koll efter uppdaterade appar körs redan...</message>
</output> </output>
<output id="9"> <output id="9">

View File

@ -1,6 +1,6 @@
<# ARRAYS/VARIABLES #> <# ARRAYS/VARIABLES #>
#App to Run (as SYSTEM) #App to Run (as SYSTEM)
#$RunWait = $False if it shouldn't be waited for completion. Example: #$RunWait = $False if it shouldn't be waited for completion. For example:
#$RunSystem = "$PSScriptRoot\bins\MsiZap.exe" #$RunSystem = "$PSScriptRoot\bins\MsiZap.exe"
#$RunSwitch = "tw! {GUID}" #$RunSwitch = "tw! {GUID}"
$RunSystem = "" $RunSystem = ""
@ -13,9 +13,18 @@ $Proc = @("")
#Beginning of Process Name to Wait for to End - optional wildcard (*) after, without .exe, multiple: "proc1","proc2" #Beginning of Process Name to Wait for to End - optional wildcard (*) after, without .exe, multiple: "proc1","proc2"
$Wait = @("") $Wait = @("")
#Install App from Winget Repo, multiple: "appID1","appID2". Example:
#$WingetIDInst = @("Microsoft.PowerToys")
$WingetIDInst = @("")
#WingetID to uninstall in default manifest mode (silent if supported)
#Multiple: "ID1","ID2". Example:
#$WingetIDUninst = @("Microsoft.PowerToys")
$WingetIDUninst = @("")
#Beginning of App Name string to Silently Uninstall (MSI/NSIS/INNO/EXE with defined silent uninstall in registry) #Beginning of App Name string to Silently Uninstall (MSI/NSIS/INNO/EXE with defined silent uninstall in registry)
#Multiple: "app1*","app2*", required wildcard (*) after; search is done with "-like"! #Multiple: "app1*","app2*", required wildcard (*) after; search is done with "-like"!
$App = @("") $AppUninst = @("")
#Beginning of Desktop Link Name to Remove - optional wildcard (*) after, without .lnk, multiple: "lnk1","lnk2" #Beginning of Desktop Link Name to Remove - optional wildcard (*) after, without .lnk, multiple: "lnk1","lnk2"
$Lnk = @("") $Lnk = @("")
@ -37,18 +46,23 @@ $AddType = ""
$DelKey = "" $DelKey = ""
$DelValue = "" $DelValue = ""
#Remove file/directory, multiple: "file1","file2" #Remove file/directory, multiple: "file1","file2" Example:
#$DelFile = @("${env:ProgramFiles}\PowerToys\PowerToys.Update.exe")
$DelFile = @("") $DelFile = @("")
#Copy file/directory #Rename file/directory. Example:
#Example: #$RenFile = "${env:ProgramFiles}\PowerToys\PowerToys.Update.exe"
#$NewName = "PowerToys.Update.org"
$RenFile = ""
$NewName = ""
#Copy file/directory. Example:
#$CopyFile = "C:\Logfiles" #$CopyFile = "C:\Logfiles"
#$CopyTo = "C:\Drawings\Logs" #$CopyTo = "C:\Drawings\Logs"
$CopyFile = "" $CopyFile = ""
$CopyTo = "" $CopyTo = ""
#Find/Replace text in file #Find/Replace text in file. Example:
#Example:
#$File = "C:\dummy.txt" #$File = "C:\dummy.txt"
#$FindText = 'brown fox' #$FindText = 'brown fox'
#$ReplaceText = 'white fox' #$ReplaceText = 'white fox'
@ -59,10 +73,6 @@ $ReplaceText = ''
#Grant "Modify" for directory/file to "Authenticated Users" - multiple: "dir1","dir2" #Grant "Modify" for directory/file to "Authenticated Users" - multiple: "dir1","dir2"
$GrantPath = @("") $GrantPath = @("")
#Install App from Winget Repo, multiple: "appID1","appID2". Example:
#$AppID = @("Microsoft.PowerToys")
$AppID = @("")
#App to Run (as current logged-on user) #App to Run (as current logged-on user)
$RunUser = "" $RunUser = ""
$User = $True $User = $True
@ -80,8 +90,14 @@ if ($Proc) {
if ($Wait) { if ($Wait) {
Wait-ModsProc $Wait Wait-ModsProc $Wait
} }
if ($App) { if ($WingetIDInst) {
Uninstall-ModsApp $App Install-WingetID $WingetIDInst
}
if ($WingetIDUninst) {
Uninstall-WingetID $WingetIDUninst
}
if ($AppUninst) {
Uninstall-ModsApp $AppUninst
} }
if ($Lnk) { if ($Lnk) {
Remove-ModsLnk $Lnk Remove-ModsLnk $Lnk
@ -95,6 +111,9 @@ if ($DelKey) {
if ($DelFile) { if ($DelFile) {
Remove-ModsFile $DelFile Remove-ModsFile $DelFile
} }
if ($RenFile -and $NewName) {
Rename-ModsFile $RenFile $NewName
}
if ($CopyFile -and $CopyTo) { if ($CopyFile -and $CopyTo) {
Copy-ModsFile $CopyFile $CopyTo Copy-ModsFile $CopyFile $CopyTo
} }
@ -104,9 +123,6 @@ if ($File -and $FindText -and $ReplaceText) {
if ($GrantPath) { if ($GrantPath) {
Grant-ModsPath $GrantPath Grant-ModsPath $GrantPath
} }
if ($AppID) {
Install-ModsApp $AppID
}
if ($RunUser) { if ($RunUser) {
Invoke-ModsApp $RunUser "" "" $User Invoke-ModsApp $RunUser "" "" $User
} }

View File

@ -1,45 +1,56 @@
#Common shared functions for mods handling #Common shared functions to handle the mods
function Invoke-ModsApp ($Run, $RunSwitch, $RunWait, $User) { function Invoke-ModsApp ($Run, $RunSwitch, $RunWait, $User) {
if (Test-Path "$Run") { if (Test-Path "$Run") {
if (!$RunSwitch) {$RunSwitch = " "} if (!$RunSwitch) { $RunSwitch = " " }
if (!$User) { if (!$User) {
if (!$RunWait) { if (!$RunWait) {
Start-Process $Run -ArgumentList $RunSwitch Start-Process $Run -ArgumentList $RunSwitch
} }
else { else {
Start-Process $Run -ArgumentList $RunSwitch -Wait Start-Process $Run -ArgumentList $RunSwitch -Wait
} }
} }
else { else {
Start-Process explorer $Run Start-Process explorer $Run
} }
} }
Return Return
} }
function Stop-ModsProc ($Proc) { function Stop-ModsProc ($Proc) {
foreach ($process in $Proc) foreach ($process in $Proc) {
{
Stop-Process -Name $process -Force -ErrorAction SilentlyContinue | Out-Null Stop-Process -Name $process -Force -ErrorAction SilentlyContinue | Out-Null
} }
Return Return
} }
function Wait-ModsProc ($Wait) { function Wait-ModsProc ($Wait) {
foreach ($process in $Wait) foreach ($process in $Wait) {
{
Get-Process $process -ErrorAction SilentlyContinue | Foreach-Object { $_.WaitForExit() } Get-Process $process -ErrorAction SilentlyContinue | Foreach-Object { $_.WaitForExit() }
} }
Return Return
} }
function Uninstall-ModsApp ($App) { function Install-WingetID ($WingetIDInst) {
foreach ($app in $App) foreach ($app in $WingetIDInst) {
{ & $Winget install --id $app --accept-package-agreements --accept-source-agreements -h
}
Return
}
function Uninstall-WingetID ($WingetIDUninst) {
foreach ($app in $WingetIDUninst) {
& $Winget uninstall --id $app -e --accept-source-agreements -h
}
Return
}
function Uninstall-ModsApp ($AppUninst) {
foreach ($app in $AppUninst) {
$InstalledSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" $InstalledSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
foreach ($obj in $InstalledSoftware){ foreach ($obj in $InstalledSoftware) {
if ($obj.GetValue('DisplayName') -like $App) { if ($obj.GetValue('DisplayName') -like $App) {
$UninstallString = $obj.GetValue('UninstallString') $UninstallString = $obj.GetValue('UninstallString')
$CleanedUninstallString = $UninstallString.Trim([char]0x0022) $CleanedUninstallString = $UninstallString.Trim([char]0x0022)
@ -95,7 +106,7 @@ function Uninstall-ModsApp ($App) {
} }
if (!$x64) { if (!$x64) {
$InstalledSoftware = Get-ChildItem "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" $InstalledSoftware = Get-ChildItem "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
foreach ($obj in $InstalledSoftware){ foreach ($obj in $InstalledSoftware) {
if ($obj.GetValue('DisplayName') -like $App) { if ($obj.GetValue('DisplayName') -like $App) {
$UninstallString = $obj.GetValue('UninstallString') $UninstallString = $obj.GetValue('UninstallString')
$CleanedUninstallString = $UninstallString.Trim([char]0x0022) $CleanedUninstallString = $UninstallString.Trim([char]0x0022)
@ -153,8 +164,7 @@ function Uninstall-ModsApp ($App) {
Return Return
} }
function Remove-ModsLnk ($Lnk) { function Remove-ModsLnk ($Lnk) {
foreach ($link in $Lnk) foreach ($link in $Lnk) {
{
Remove-Item -Path "${env:Public}\Desktop\$link.lnk" -Force -ErrorAction SilentlyContinue | Out-Null Remove-Item -Path "${env:Public}\Desktop\$link.lnk" -Force -ErrorAction SilentlyContinue | Out-Null
} }
Return Return
@ -162,7 +172,7 @@ function Remove-ModsLnk ($Lnk) {
function Add-ModsReg ($AddKey, $AddValue, $AddTypeData, $AddType) { function Add-ModsReg ($AddKey, $AddValue, $AddTypeData, $AddType) {
if ($AddKey -like "HKEY_LOCAL_MACHINE*") { if ($AddKey -like "HKEY_LOCAL_MACHINE*") {
$AddKey = $AddKey.replace("HKEY_LOCAL_MACHINE","HKLM:") $AddKey = $AddKey.replace("HKEY_LOCAL_MACHINE", "HKLM:")
} }
if (!(Test-Path "$AddKey")) { if (!(Test-Path "$AddKey")) {
New-Item $AddKey -Force -ErrorAction SilentlyContinue | Out-Null New-Item $AddKey -Force -ErrorAction SilentlyContinue | Out-Null
@ -173,7 +183,7 @@ function Add-ModsReg ($AddKey, $AddValue, $AddTypeData, $AddType) {
function Remove-ModsReg ($DelKey, $DelValue) { function Remove-ModsReg ($DelKey, $DelValue) {
if ($DelKey -like "HKEY_LOCAL_MACHINE*") { if ($DelKey -like "HKEY_LOCAL_MACHINE*") {
$DelKey = $DelKey.replace("HKEY_LOCAL_MACHINE","HKLM:") $DelKey = $DelKey.replace("HKEY_LOCAL_MACHINE", "HKLM:")
} }
if (Test-Path "$DelKey") { if (Test-Path "$DelKey") {
if (!$DelValue) { if (!$DelValue) {
@ -187,8 +197,7 @@ function Remove-ModsReg ($DelKey, $DelValue) {
} }
function Remove-ModsFile ($DelFile) { function Remove-ModsFile ($DelFile) {
foreach ($file in $DelFile) foreach ($file in $DelFile) {
{
if (Test-Path "$file") { if (Test-Path "$file") {
Remove-Item -Path $file -Force -Recurse -ErrorAction SilentlyContinue | Out-Null Remove-Item -Path $file -Force -Recurse -ErrorAction SilentlyContinue | Out-Null
} }
@ -196,6 +205,13 @@ function Remove-ModsFile ($DelFile) {
Return Return
} }
function Rename-ModsFile ($RenFile, $NewName) {
if (Test-Path "$RenFile") {
Rename-Item -Path $RenFile -NewName $NewName -Force -ErrorAction SilentlyContinue | Out-Null
}
Return
}
function Copy-ModsFile ($CopyFile, $CopyTo) { function Copy-ModsFile ($CopyFile, $CopyTo) {
if (Test-Path "$CopyFile") { if (Test-Path "$CopyFile") {
Copy-Item -Path $CopyFile -Destination $CopyTo -Recurse -Force -ErrorAction SilentlyContinue | Out-Null Copy-Item -Path $CopyFile -Destination $CopyTo -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
@ -205,14 +221,13 @@ function Copy-ModsFile ($CopyFile, $CopyTo) {
function Edit-ModsFile ($File, $FindText, $ReplaceText) { function Edit-ModsFile ($File, $FindText, $ReplaceText) {
if (Test-Path "$File") { if (Test-Path "$File") {
((Get-Content -path $File -Raw) -replace "$FindText","$ReplaceText") | Set-Content -Path $File -Force -ErrorAction SilentlyContinue | Out-Null ((Get-Content -path $File -Raw) -replace "$FindText", "$ReplaceText") | Set-Content -Path $File -Force -ErrorAction SilentlyContinue | Out-Null
} }
Return Return
} }
function Grant-ModsPath ($GrantPath) { function Grant-ModsPath ($GrantPath) {
foreach ($path in $GrantPath) foreach ($path in $GrantPath) {
{
if (Test-Path "$path") { if (Test-Path "$path") {
$NewAcl = Get-Acl -Path $path $NewAcl = Get-Acl -Path $path
$identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11 $identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11
@ -229,11 +244,3 @@ function Grant-ModsPath ($GrantPath) {
} }
Return Return
} }
function Install-ModsApp ($AppID) {
foreach ($app in $AppID)
{
& $Winget install --id $app --accept-package-agreements --accept-source-agreements -h
}
Return
}