Merge pull request #257 from KnifMelti/GPO

GPO Management and more...
pull/264/head v1.16.0
Romain 2023-01-17 11:14:51 +01:00 committed by GitHub
commit dd4cc700f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1475 additions and 153 deletions

9
Policies/README.md Normal file
View File

@ -0,0 +1,9 @@
### Add the administrative template to an individual computer
1. Copy the "**WAU.admx**" file to your Policy Definition template folder. (Example: `C:\Windows\PolicyDefinitions`)
2. Copy the "**WAU.adml**" file to the matching language folder in your Policy Definition folder. (Example: `C:\Windows\PolicyDefinitions\en-US`)
### Add the administrative template to Active Directory
1. On a domain controller or workstation with [RSAT](https://learn.microsoft.com/en-us/troubleshoot/windows-server/system-management-components/remote-server-administration-tools), go to the **PolicyDefinition** folder (also known as the _Central Store_) on any domain controller for your domain.
2. Copy the "**WAU.admx**" file to the PolicyDefinition folder. (Example: `%systemroot%\sysvol\domain\policies\PolicyDefinitions`)
3. Copy the "**WAU.adml**" file to the matching language folder in the PolicyDefinition folder. Create the folder if it doesn't already exist. (Example: `%systemroot%\sysvol\domain\policies\PolicyDefinitions\EN-US`)
4. If your domain has more than one domain controller, the new [ADMX files](https://learn.microsoft.com/en-us/troubleshoot/windows-client/group-policy/create-and-manage-central-store) will be replicated to them at the next domain replication interval.

337
Policies/WAU.admx Normal file
View File

@ -0,0 +1,337 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitions revision="4.4" schemaVersion="1.0">
<policyNamespaces>
<target prefix="WAU" namespace="Romanitho.Policies.WAU"/>
<using prefix="Romanitho" namespace="Romanitho.Policies"/>
</policyNamespaces>
<resources minRequiredRevision="4.4"/>
<supportedOn>
<definitions>
<definition name="SUPPORTED_WAU_1_15_3" displayName="$(string.SUPPORTED_WAU_1_15_3)"/>
</definitions>
</supportedOn>
<categories>
<category displayName="$(string.WAU)" name="WAU">
<parentCategory ref="Romanitho:Cat_Romanitho"/>
</category>
</categories>
<policies>
<policy name="ActivateGPOManagement_Enable" class="Machine" displayName="$(string.ActivateGPOManagement_Name)" explainText="$(string.ActivateGPOManagement_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_ActivateGPOManagement">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="BypassListForUsers_Enable" class="Machine" displayName="$(string.BypassListForUsers_Name)" explainText="$(string.BypassListForUsers_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_BypassListForUsers">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DisableAutoUpdate_Enable" class="Machine" displayName="$(string.DisableAutoUpdate_Name)" explainText="$(string.DisableAutoUpdate_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_DisableAutoUpdate">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DoNotRunOnMetered_Enable" class="Machine" displayName="$(string.DoNotRunOnMetered_Name)" explainText="$(string.DoNotRunOnMetered_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_DoNotRunOnMetered">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="0" />
</enabledValue>
<disabledValue>
<decimal value="1" />
</disabledValue>
</policy>
<policy name="UpdatePrerelease_Enable" class="Machine" displayName="$(string.UpdatePrerelease_Name)" explainText="$(string.UpdatePrerelease_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_UpdatePrerelease">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="UseWhiteList_Enable" class="Machine" displayName="$(string.UseWhiteList_Name)" explainText="$(string.UseWhiteList_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_UseWhiteList">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="ListPath_Enable" class="Machine" displayName="$(string.ListPath_Name)" explainText="$(string.ListPath_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.ListPath)" >
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<text id="ListPath" valueName="WAU_ListPath" />
</elements>
</policy>
<policy name="ModsPath_Enable" class="Machine" displayName="$(string.ModsPath_Name)" explainText="$(string.ModsPath_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.ModsPath)" >
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<text id="ModsPath" valueName="WAU_ModsPath" />
</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)">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<enum id="NotificationLevel" valueName="WAU_NotificationLevel">
<item displayName="$(string.NotificationLevel_Full)">
<value>
<string>Full</string>
</value>
</item>
<item displayName="$(string.NotificationLevel_SuccessOnly)">
<value>
<string>SuccessOnly</string>
</value>
</item>
<item displayName="$(string.NotificationLevel_None)">
<value>
<string>None</string>
</value>
</item>
</enum>
</elements>
</policy>
<policy name="UpdatesInterval_Enable" class="Machine" displayName="$(string.UpdatesInterval_Name)" explainText="$(string.UpdatesInterval_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.UpdatesInterval)">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<enum id="UpdatesInterval" valueName="WAU_UpdatesInterval">
<item displayName="$(string.UpdatesInterval_Daily)">
<value>
<string>Daily</string>
</value>
</item>
<item displayName="$(string.UpdatesInterval_BiDaily)">
<value>
<string>BiDaily</string>
</value>
</item>
<item displayName="$(string.UpdatesInterval_Weekly)">
<value>
<string>Weekly</string>
</value>
</item>
<item displayName="$(string.UpdatesInterval_BiWeekly)">
<value>
<string>BiWeekly</string>
</value>
</item>
<item displayName="$(string.UpdatesInterval_Monthly)">
<value>
<string>Monthly</string>
</value>
</item>
<item displayName="$(string.UpdatesInterval_Never)">
<value>
<string>Never</string>
</value>
</item>
</enum>
</elements>
</policy>
<policy name="UpdatesAtLogon_Enable" class="Machine" displayName="$(string.UpdatesAtLogon_Name)" explainText="$(string.UpdatesAtLogon_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_UpdatesAtLogon">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="UpdatesAtTime_Enable" class="Machine" displayName="$(string.UpdatesAtTime_Name)" explainText="$(string.UpdatesAtTime_Explain)" presentation="$(presentation.UpdatesAtTime)" key="Software\Policies\Romanitho\Winget-AutoUpdate">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<enum id="UpdatesAtTime" valueName="WAU_UpdatesAtTime">
<item displayName="$(string.UpdatesAtTime01)">
<value>
<string>01:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime02)">
<value>
<string>02:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime03)">
<value>
<string>03:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime04)">
<value>
<string>04:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime05)">
<value>
<string>05:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime06)">
<value>
<string>06:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime07)">
<value>
<string>07:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime08)">
<value>
<string>08:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime09)">
<value>
<string>09:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime10)">
<value>
<string>10:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime11)">
<value>
<string>11:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime12)">
<value>
<string>12:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime13)">
<value>
<string>13:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime14)">
<value>
<string>14:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime15)">
<value>
<string>15:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime16)">
<value>
<string>16:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime17)">
<value>
<string>17:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime18)">
<value>
<string>18:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime19)">
<value>
<string>19:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime20)">
<value>
<string>20:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime21)">
<value>
<string>21:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime22)">
<value>
<string>22:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime23)">
<value>
<string>23:00:00</string>
</value>
</item>
<item displayName="$(string.UpdatesAtTime24)">
<value>
<string>24:00:00</string>
</value>
</item>
</enum>
</elements>
</policy>
<policy name="UserContext_Enable" class="Machine" displayName="$(string.UserContext_Name)" explainText="$(string.UserContext_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_UserContext">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="DesktopShortcut_Enable" class="Machine" displayName="$(string.DesktopShortcut_Name)" explainText="$(string.DesktopShortcut_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_DesktopShortcut">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="StartMenuShortcut_Enable" class="Machine" displayName="$(string.StartMenuShortcut_Name)" explainText="$(string.StartMenuShortcut_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" valueName="WAU_StartMenuShortcut">
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
<policy name="MaxLogFiles_Name" class="Machine" displayName="$(string.MaxLogFiles_Name)" explainText="$(string.MaxLogFiles_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.MaxLogFiles)" >
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<text id="MaxLogFiles" valueName="WAU_MaxLogFiles" />
</elements>
</policy>
<policy name="MaxLogSize_Name" class="Machine" displayName="$(string.MaxLogSize_Name)" explainText="$(string.MaxLogSize_Explain)" key="Software\Policies\Romanitho\Winget-AutoUpdate" presentation="$(presentation.MaxLogSize)" >
<parentCategory ref="WAU"/>
<supportedOn ref="WAU:SUPPORTED_WAU_1_15_3"/>
<elements>
<text id="MaxLogSize" valueName="WAU_MaxLogSize" />
</elements>
</policy>
</policies>
</policyDefinitions>

160
Policies/en-US/WAU.adml Normal file
View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitionResources revision="4.4" schemaVersion="1.0" >
<displayName/>
<description/>
<resources >
<stringTable >
<string id="WAU">Winget-AutoUpdate</string>
<string id="SUPPORTED_WAU_1_15_3">Winget-AutoUpdate version 1.15.3 or later</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="BypassListForUsers_Name">Bypass Black/White list for User</string>
<string id="BypassListForUsers_Explain">This policy setting specifies whether to Bypass Black/White list when run in user context or not.
If this policy is disabled or not configured, the default is No.</string>
<string id="DisableAutoUpdate_Name">Disable WAU AutoUpdate</string>
<string id="DisableAutoUpdate_Explain">This policy setting specifies whether to Disable WAU AutoUpdate or not:
By default, WAU AutoUpdate is enabled.
It will not overwrite the configurations, icons (if personalised), excluded_apps list...
If this policy is disabled or not configured, the default is No.</string>
<string id="DoNotRunOnMetered_Name">Run WAU on metered connection</string>
<string id="DoNotRunOnMetered_Explain">This policy setting specifies whether to Run WAU on metered connection or not.
If this policy is disabled or not configured, the default is No.</string>
<string id="UpdatePrerelease_Name">Update WAU to PreRelease versions</string>
<string id="UpdatePrerelease_Explain">This policy setting specifies whether to update WAU to PreRelease versions or not (via WAU AutoUpdate).
If this policy is disabled or not configured, the default is No.</string>
<string id="UseWhiteList_Name">Use WhiteList instead of BlackList</string>
<string id="UseWhiteList_Explain">This policy setting specifies whether to use a WhiteList or not.
If this policy is disabled or not configured, the default is No.</string>
<string id="ListPath_Name">Get Black/White List from external Path (URL/UNC/Local)</string>
<string id="ListPath_Explain">If this policy is enabled, you can set a (URL/UNC/Local) Path to external lists other than the default.
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_Explain">If this policy is enabled, you can set a (URL/UNC/Local) Path to external mods other than the default.
If this policy is disabled or not configured, the default ModsPath is used (WAU InstallLocation).</string>
<string id="NotificationLevel_Name">Notification Level</string>
<string id="NotificationLevel_Explain">If this policy is enabled, you can configure the Notification Level:
1. Full (Default)
2. SuccessOnly
3. None
If this policy is not configured or disabled, Notification Level: (1. Full).</string>
<string id="NotificationLevel_Full">1. Full (Default)</string>
<string id="NotificationLevel_SuccessOnly">2. SuccessOnly</string>
<string id="NotificationLevel_None">3. None</string>
<string id="UpdatesInterval_Name">Updates Interval</string>
<string id="UpdatesInterval_Explain">If this policy is enabled, you can configure the Updates Interval:
1. Daily (Default)
2. BiDaily
3. Weekly
4. BiWeekly
5. Monthly
6. Never (e.g. in combination with 'Updates at Logon')
If this policy is not configured or disabled, Updates Interval: (1. Daily).</string>
<string id="UpdatesInterval_Daily">1. Daily (Default)</string>
<string id="UpdatesInterval_BiDaily">2. BiDaily</string>
<string id="UpdatesInterval_Weekly">3. Weekly</string>
<string id="UpdatesInterval_BiWeekly">4. BiWeekly</string>
<string id="UpdatesInterval_Monthly">5. Monthly</string>
<string id="UpdatesInterval_Never">6. Never (e.g. in combination with 'Updates Interval')</string>
<string id="UpdatesAtLogon_Name">Updates at Logon</string>
<string id="UpdatesAtLogon_Explain">This policy setting specifies whether to set WAU to run at user logon or not.
If this policy is disabled or not configured, the default is No.</string>
<string id="UpdatesAtTime_Name">Updates at Time</string>
<string id="UpdatesAtTime_Explain">If this policy is enabled, you can configure the Sheduled Task Update time:
From 01:00 to 24:00 (Military/24 Hour Time)
If this policy is not configured or disabled, Updates at Time: (06:00 AM).</string>
<string id="UpdatesAtTime01">01:00 AM</string>
<string id="UpdatesAtTime02">02:00</string>
<string id="UpdatesAtTime03">03:00</string>
<string id="UpdatesAtTime04">04:00</string>
<string id="UpdatesAtTime05">05:00</string>
<string id="UpdatesAtTime06">06:00 (Default)</string>
<string id="UpdatesAtTime07">07:00</string>
<string id="UpdatesAtTime08">08:00</string>
<string id="UpdatesAtTime09">09:00</string>
<string id="UpdatesAtTime10">10:00</string>
<string id="UpdatesAtTime11">11:00</string>
<string id="UpdatesAtTime12">12:00</string>
<string id="UpdatesAtTime13">13:00 PM</string>
<string id="UpdatesAtTime14">14:00</string>
<string id="UpdatesAtTime15">15:00</string>
<string id="UpdatesAtTime16">16:00</string>
<string id="UpdatesAtTime17">17:00</string>
<string id="UpdatesAtTime18">18:00</string>
<string id="UpdatesAtTime19">19:00</string>
<string id="UpdatesAtTime20">20:00</string>
<string id="UpdatesAtTime21">21:00</string>
<string id="UpdatesAtTime22">22:00</string>
<string id="UpdatesAtTime23">23:00</string>
<string id="UpdatesAtTime24">24:00</string>
<string id="UserContext_Name">User context execution</string>
<string id="UserContext_Explain">This policy setting specifies whether to enable User context execution or not.
If this policy is disabled or not configured, the default is No.</string>
<string id="DesktopShortcut_Name">Enable Deskop Shortcut</string>
<string id="DesktopShortcut_Explain">This policy setting specifies whether to enable a Desktop Shortcut or not:
WAU - Check for updated Apps
If this policy is disabled or not configured, the default is No.</string>
<string id="StartMenuShortcut_Name">Enable Start Menu Shortcuts</string>
<string id="StartMenuShortcut_Explain">This policy setting specifies whether to enable the Start Menu Shortcuts or not:
WAU - Check for updated Apps
WAU - Open logs
WAU - Web Help
If this policy is disabled or not configured, the default is No.</string>
<string id="MaxLogFiles_Name">Log: Number of allowed log files</string>
<string id="MaxLogFiles_Explain">If this policy is enabled, you can set a number of allowed log files:
Setting MaxLogFiles to 0 don't delete any old archived log files, 1 keeps the original one and just let it grow.
Default number is 3 (0-99)
If this policy is disabled or not configured, the default number is used.</string>
<string id="MaxLogSize_Name">Log: Size of the log file in bytes before rotating</string>
<string id="MaxLogSize_Explain">If this policy is enabled, you can set the size of the log file in bytes before rotating.
Default size is 1048576 = 1 MB
If this policy is disabled or not configured, the default size is used.</string>
</stringTable>
<presentationTable>
<presentation id="ListPath">
<textBox refId="ListPath">
<label>(URL/UNC/Local) Path:</label>
</textBox>
</presentation>
<presentation id="ModsPath">
<textBox refId="ModsPath">
<label>(URL/UNC/Local) Path:</label>
</textBox>
</presentation>
<presentation id="NotificationLevel">
<dropdownList refId="NotificationLevel"/>
</presentation>
<presentation id="UpdatesInterval">
<dropdownList refId="UpdatesInterval"/>
</presentation>
<presentation id="UpdatesAtTime">
<dropdownList refId="UpdatesAtTime"/>
</presentation>
<presentation id="MaxLogFiles">
<textBox refId="MaxLogFiles">
<label>Allowed log files:</label>
</textBox>
</presentation>
<presentation id="MaxLogSize">
<textBox refId="MaxLogSize">
<label>Size of the log file:</label>
</textBox>
</presentation>
</presentationTable>
</resources>
</policyDefinitionResources>

View File

@ -17,7 +17,7 @@ From 1.7.0 version, you can update only pre-selected apps. To do so, create an "
> You can use WiGui to create these lists: https://github.com/Romanitho/Winget-Install-GUI
### Notification Level
From version 1.9.0, you can choose which notification will be displayed: Full, Success only or none. Use `-NotificationLevel` parameter when you run `Winget-AutoUpdate-Install.ps1`
From version 1.9.0, you can choose which notification will be displayed: Full, Success only or none. Use `-NotificationLevel` parameter when you run `Winget-AutoUpdate-Install.ps1`.
### Notification language
You can easily translate toast notifications by creating your locale xml config file (and share it with us :) ).
@ -47,7 +47,7 @@ We might want to stop WAU on metered connection (to save cellular data on connec
To force WAU to run on metered connections anyway, run new installation with `-RunOnMetered` parameter.
### System & user context
From version 1.15.0, WAU run with system and user contexts. This way, even apps installed on User's scope are updated. Shorcuts for manually run can also be installed
From version 1.15.0, WAU run with system and user contexts. This way, even apps installed on User's scope are updated. Shorcuts for manually run can also be installed.
## Update WAU
### Manual Update
@ -55,7 +55,7 @@ Same process as new installation : download, unzip and run `install.bat`.
### Automatic Update
A new Auto-Update process has been released from version 1.5.0. By default, WAU AutoUpdate is enabled. It will not overwrite the configurations, icons (if personalised), excluded_apps list,...
To disable WAU AutoUpdate, run the `Winget-AutoUpdate-Install.ps1` with `-DisableWAUAutoUpdate` parameter
To disable WAU AutoUpdate, run the `Winget-AutoUpdate-Install.ps1` with `-DisableWAUAutoUpdate` parameter.
## Uninstall WAU
Simply uninstall it from your programs:
@ -71,10 +71,20 @@ Simply uninstall it from your programs:
You can run the `Winget-AutoUpdate-Install.ps1` script with parameters :
**-Silent**
Install Winget-AutoUpdate and prerequisites silently
Install Winget-AutoUpdate and prerequisites silently.
**-MaxLogFiles**
Specify number of allowed log files.
Default is 3 of 0-99:
Setting MaxLogFiles to 0 don't delete any old archived log files.
Setting it to 1 keeps the original one and just let it grow.
**-MaxLogSize**
Specify the size of the log file in bytes before rotating.
Default is 1048576 = 1 MB
**-WingetUpdatePath**
Specify Winget-AutoUpdate installation location. Default: `C:\ProgramData\Winget-AutoUpdate` (Recommended to leave default)
Specify Winget-AutoUpdate installation location. Default: `C:\ProgramData\Winget-AutoUpdate` (Recommended to leave default).
**-DoNotUpdate**
Do not run Winget-AutoUpdate after installation. By default, Winget-AutoUpdate is run just after installation.
@ -83,38 +93,43 @@ Do not run Winget-AutoUpdate after installation. By default, Winget-AutoUpdate i
Disable Winget-AutoUpdate update checking. By default, WAU auto updates if new version is available on Github.
**-UseWhiteList**
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**
Get Black/White List from Path (URL/UNC/Local) (download/copy to Winget-AutoUpdate installation location if external list is newer).
Get Black/White List from external Path (**URL/UNC/Local**) - download/copy to Winget-AutoUpdate installation location if external list is newer.
**-ModsPath**
Get Mods from Path (URL/UNC/Local) (download/copy to `mods` in Winget-AutoUpdate installation location if external mods are newer).
For URL: This requires a site directory with `Options +Indexes` in `.htaccess` and no index page overriding the listing of files.
Or an index page with href listing of all the Mods to be downloaded:
Get Mods from external Path (**URL/UNC/Local**) - 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):
```
<ul>
<li><a href="Adobe.Acrobat.Reader.32-bit-install.ps1"> Adobe.Acrobat.Reader.32-bit-install.ps1</a></li>
<li><a href="Notepad++.Notepad++-install.ps1"> Notepad++.Notepad++-install.ps1</a></li>
<li><a href="Notepad++.Notepad++-uninstall.ps1"> Notepad++.Notepad++-uninstall.ps1</a></li>
<li><a href="WinMerge.WinMerge-install.ps1"> WinMerge.WinMerge-install.ps1</a></li>
<li><a href="Adobe.Acrobat.Reader.32-bit-installed.ps1">Adobe.Acrobat.Reader.32-bit-installed.ps1</a></li>
<li><a href="Adobe.Acrobat.Reader.64-bit-override.txt">Adobe.Acrobat.Reader.64-bit-override.txt</a></li>
<li><a href="Notepad++.Notepad++-installed.ps1">Notepad++.Notepad++-installed.ps1</a></li>
<li><a href="Notepad++.Notepad++-uninstalled.ps1">Notepad++.Notepad++-uninstalled.ps1</a></li>
</ul>
```
Validated on **IIS/Apache**.
**Nota bene IIS** :
- 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**'
**-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).
**-BypassListForUsers**
Bypass Black/White list when run in user context (From version 1.15.0)
Bypass Black/White list when run in user context (From version 1.15.0).
**-NoClean**
Keep critical files when installing/uninstalling. This setting will keep "excluded_apps.txt", "included_apps.txt", "mods" and "logs" as they were.
**-DesktopShortcut**
Create a shortcut for user interaction on the Desktop to run task `Winget-AutoUpdate` (From version 1.15.0)
Create a shortcut for user interaction on the Desktop to run task `Winget-AutoUpdate` (From version 1.15.0).
**-StartMenuShortcut**
Create shortcuts for user interaction in the Start Menu to run task `Winget-AutoUpdate`, open Logs and Web Help (From version 1.15.0)
Create shortcuts for user interaction in the Start Menu to run task `Winget-AutoUpdate`, open Logs and Web Help (From version 1.15.0).
**-NotificationLevel**
Specify the Notification level: Full (Default, displays all notification), SuccessOnly (Only displays notification for success) or None (Does not show any popup).
@ -123,10 +138,10 @@ Specify the Notification level: Full (Default, displays all notification), Succe
Set WAU to run at user logon.
**-UpdatesInterval**
Specify the update frequency: Daily (Default), BiDaily, Weekly, BiWeekly, Monthly or Never. Can be set to 'Never' in combination with '-UpdatesAtLogon' for instance
Specify the update frequency: Daily (Default), BiDaily, Weekly, BiWeekly, Monthly or Never. Can be set to 'Never' in combination with '-UpdatesAtLogon' for instance.
**-UpdatesAtTime**
Specify the time of the update interval execution time. Default 6AM. (From version 1.15.0)
Specify the time of the update interval execution time. Default 6AM. (From version 1.15.0).
**-RunOnMetered**
Run WAU on metered connection. Default No.
@ -144,20 +159,33 @@ Just put the scripts in question with the **AppID** followed by the `-preinstall
> Runs during upgrade/install (before install check): `AppID-upgrade.ps1`/`AppID-install.ps1`
> Runs after upgrade/install has been confirmed: `AppID-installed.ps1`
The **-install** mod will be used for upgrades too if **-upgrade** doesn't exist
The **-install** mod will be used for upgrades too if **-upgrade** doesn't exist (**WAU** first tries `& $Winget upgrade --id` and if the app isn't detected after that `& $Winget install --id` is tried).
`AppID-install.ps1` is recommended because it's used in **both** scenarios.
> Example:
If you want to run a script that removes the shortcut from **%PUBLIC%\Desktop** (we don't want to fill the desktop with shortcuts our users can't delete) just after installing **Acrobat Reader DC** (32-bit), prepare a powershell script that removes the Public Desktop shortcut **Acrobat Reader DC.lnk** and name your script like this:
`Adobe.Acrobat.Reader.32-bit-installed.ps1` and put it in the **mods** folder.
You can find more information on [Winget-Install Repo](https://github.com/Romanitho/Winget-Install#custom-mods), as it's a related feature
You can find more information on [Winget-Install Repo](https://github.com/Romanitho/Winget-Install#custom-mods), as it's a related feature.
Read more in the `README.md` under the directory **mods**.
### Winget native parameters
Another finess is the **AppID** followed by the `-override` suffix as a **text file** (.txt) that you can place under the **mods** folder.
> Example:
> **Canneverbe.CDBurnerXP-override.txt** with the content `ADDLOCAL=All REMOVE=Desktop_Shortcut /qn`
This will use the content from the text file as a native **winget --override** parameter when upgrading (as proposed by [Nesovj](https://github.com/Nesovj) in [Mod for --override argument #244](https://github.com/Romanitho/Winget-AutoUpdate/discussions/244#discussion-4637666)).
This will use the **content** of the text file as a native **winget --override** parameter when upgrading (as proposed by [JonNesovic](https://github.com/JonNesovic) in [Mod for --override argument #244](https://github.com/Romanitho/Winget-AutoUpdate/discussions/244#discussion-4637666)).
## GPO Management
In an enterprise environment it's crucial that different groups can have different settings in applications etc. or to implement other mandatory settings, i.e for security/management reasons.
**WAU** doesn't have any setting that can be changed except for when installing (or editing the registry/the task `Winget-AutoUpdate` as **Admin**).
With the use of **ADML/ADMX** files you can manage every **WAU** setting from within **GPO**.
They will be detected/evaluated during the next run of **WAU** (taking effect before any actions).
The **GPO ADMX/ADML** validated with:
[Windows 10 - Validate ADMX for Ingestion](https://developer.vmware.com/samples/7115/windows-10---validate-admx-for-ingestion)
Read more in the `README.md` under the directory **Policies**.
![image](https://user-images.githubusercontent.com/102996177/212422844-9366c6aa-ee7a-490f-97f0-bffb5ab146ab.png)
## Help
In some cases, you need to "unblock" the `install.bat` file (Windows Defender SmartScreen). Right click, properties and unblock. Then, you'll be able to run it.
@ -166,4 +194,4 @@ In some cases, you need to "unblock" the `install.bat` file (Windows Defender Sm
* As reported by [soredake](https://github.com/soredake), Powershell from MsStore is not supported with WAU in system context. See https://github.com/Romanitho/Winget-AutoUpdate/issues/113
## Optimization
Feel free to give us any suggestions or optimizations in code and support us by adding a star :)
Feel free to give us any suggestions or optimizations in code and support us by adding a star :).

View File

@ -10,6 +10,12 @@ https://github.com/Romanitho/Winget-AutoUpdate
.PARAMETER Silent
Install Winget-AutoUpdate and prerequisites silently
.PARAMETER MaxLogFiles
Specify number of allowed log files (Default is 3 of 0-99: Setting MaxLogFiles to 0 don't delete any old archived log files, 1 keeps the original one and just let it grow)
.PARAMETER MaxLogSize
Specify the size of the log file in bytes before rotating. (Default is 1048576 = 1 MB)
.PARAMETER WingetUpdatePath
Specify Winget-AutoUpdate installation localtion. Default: C:\ProgramData\Winget-AutoUpdate\
@ -62,7 +68,7 @@ Install WAU with system and user context executions
Configure WAU to bypass the Black/White list when run in user context
.EXAMPLE
.\Winget-AutoUpdate-Install.ps1 -Silent -DoNotUpdate
.\Winget-AutoUpdate-Install.ps1 -Silent -DoNotUpdate -MaxLogFiles 4 -MaxLogSize 2097152
.EXAMPLE
.\Winget-AutoUpdate-Install.ps1 -Silent -UseWhiteList
@ -100,7 +106,9 @@ param(
[Parameter(Mandatory = $False)] [ValidateSet("Daily", "BiDaily", "Weekly", "BiWeekly", "Monthly", "Never")] [String] $UpdatesInterval = "Daily",
[Parameter(Mandatory = $False)] [DateTime] $UpdatesAtTime = ("06am"),
[Parameter(Mandatory = $False)] [Switch] $BypassListForUsers = $false,
[Parameter(Mandatory = $False)] [Switch] $InstallUserContext = $false
[Parameter(Mandatory = $False)] [Switch] $InstallUserContext = $false,
[Parameter(Mandatory = $False)] [ValidateRange(0,99)] [int32] $MaxLogFiles = 3,
[Parameter(Mandatory = $False)] [int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB
)
<# APP INFO #>
@ -177,7 +185,7 @@ function Install-WinGet {
#Check Package Install
$TestWinGet = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq "Microsoft.DesktopAppInstaller" }
If ([Version]$TestWinGet.Version -ge "2022.728.1939.0") {
If ([Version]$TestWinGet.Version -ge "2022.927.3.0") {
Write-Host "WinGet is Installed" -ForegroundColor Green
@ -186,7 +194,7 @@ function Install-WinGet {
#Download WinGet MSIXBundle
Write-Host "-> Not installed. Downloading WinGet..."
$WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.3.2091/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$WinGetURL = "https://github.com/microsoft/winget-cli/releases/download/v1.3.2691/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($WinGetURL, "$PSScriptRoot\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle")
@ -337,6 +345,8 @@ function Install-WingetAutoUpdate {
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $NotificationLevel -Force | Out-Null
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null
New-ItemProperty $regPath -Name WAU_PostUpdateActions -Value 0 -PropertyType DWord -Force | Out-Null
New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $MaxLogFiles -PropertyType DWord -Force | Out-Null
New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $MaxLogSize -PropertyType DWord -Force | Out-Null
if ($DisableWAUAutoUpdate) {
New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value 1 -Force | Out-Null
}

View File

@ -14,27 +14,76 @@ $Script:IsSystem = [System.Security.Principal.WindowsIdentity]::GetCurrent().IsS
#Run log initialisation function
Start-Init
#Log running context
if ($IsSystem) {
Write-Log "Running in System context"
}
else {
Write-Log "Running in User context"
}
#Get WAU Configurations
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
#Run post update actions if necessary
#Log running context and more...
if ($IsSystem) {
Write-Log "Running in System context"
#Get and set Domain/Local Policies (GPO)
$ActivateGPOManagement, $ChangedSettings = Get-Policies
if ($ActivateGPOManagement) {
Write-Log "Activated WAU GPO Management detected, comparing..."
if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) {
Write-Log "Changed settings detected and applied" "Yellow"
}
else {
Write-Log "No Changed settings detected" "Yellow"
}
}
# Maximum number of log files to keep. Default is 3. Setting MaxLogFiles to 0 will keep all log files.
$MaxLogFiles = $WAUConfig.WAU_MaxLogFiles
if ($null -eq $MaxLogFiles) {
[int32] $MaxLogFiles = 3
}
else {
[int32] $MaxLogFiles = $MaxLogFiles
}
# Maximum size of log file.
$MaxLogSize = $WAUConfig.WAU_MaxLogSize
if (!$MaxLogSize) {
[int64] $MaxLogSize = 1048576 # in bytes, default is 1048576 = 1 MB
}
else {
[int64] $MaxLogSize = $MaxLogSize
}
#LogRotation if System
$Exception, $Rotate = Invoke-LogRotation $LogFile $MaxLogFiles $MaxLogSize
if ($Exception -eq $True) {
Write-Log "An Exception occured during Log Rotation..."
}
if ($Rotate -eq $True) {
#Log Header
$Log = "##################################################`n# CHECK FOR APP UPDATES - $(Get-Date -Format (Get-culture).DateTimeFormat.ShortDatePattern)`n##################################################"
$Log | out-file -filepath $LogFile -Append
Write-Log "Running in System context"
if ($ActivateGPOManagement) {
Write-Log "Activated WAU GPO Management detected, comparing..."
if ($null -ne $ChangedSettings -and $ChangedSettings -ne 0) {
Write-Log "Changed settings detected and applied" "Yellow"
}
else {
Write-Log "No Changed settings detected" "Yellow"
}
}
Write-Log "Max Log Size reached: $MaxLogSize bytes - Rotated Logs"
}
#Run post update actions if necessary if run as System
if (!($WAUConfig.WAU_PostUpdateActions -eq 0)) {
Invoke-PostUpdateActions
}
#Run Scope Machine funtion if run as system
if ($IsSystem) {
#Run Scope Machine funtion if run as System
$SettingsPath = "$Env:windir\system32\config\systemprofile\AppData\Local\Microsoft\WinGet\Settings\defaultState\settings.json"
Add-ScopeMachine $SettingsPath
}
else {
Write-Log "Running in User context"
}
#Get Notif Locale function
$LocaleDisplayName = Get-NotifLocale
@ -50,9 +99,9 @@ if (Test-Network) {
$WAUCurrentVersion = $WAUConfig.DisplayVersion
Write-Log "WAU current version: $WAUCurrentVersion"
if ($IsSystem) {
#Check if WAU update feature is enabled or not
#Check if WAU update feature is enabled or not if run as System
$WAUDisableAutoUpdate = $WAUConfig.WAU_DisableAutoUpdate
#If yes then check WAU update if System
#If yes then check WAU update if run as System
if ($WAUDisableAutoUpdate -eq 1) {
Write-Log "WAU AutoUpdate is Disabled." "Grey"
}
@ -71,36 +120,47 @@ if (Test-Network) {
}
}
#Delete previous list_/winget_error (if they exist) if System
#Delete previous list_/winget_error (if they exist) if run as System
if (Test-Path "$WorkingDir\logs\error.txt") {
Remove-Item "$WorkingDir\logs\error.txt" -Force
}
#Get External ListPath if System
#Get External ListPath if run as System
if ($WAUConfig.WAU_ListPath) {
Write-Log "WAU uses External Lists from: $($WAUConfig.WAU_ListPath)"
$NewList = Test-ListPath $WAUConfig.WAU_ListPath $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation
Write-Log "WAU uses External Lists from: $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/"))"
$NewList = Test-ListPath $WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/") $WAUConfig.WAU_UseWhiteList $WAUConfig.InstallLocation.TrimEnd(" ", "\")
if ($ReachNoPath) {
Write-Log "Couldn't reach/find/compare/copy from $($WAUConfig.WAU_ListPath.TrimEnd(" ", "\", "/"))..." "Red"
$Script:ReachNoPath = $False
}
if ($NewList) {
Write-Log "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation)" "Yellow"
Write-Log "Newer List downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))" "Yellow"
}
else {
if ((Test-Path "$WorkingDir\included_apps.txt") -or (Test-Path "$WorkingDir\excluded_apps.txt")) {
Write-Log "List is up to date." "Green"
if ($WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\included_apps.txt")) {
Write-Log "List (white) is up to date." "Green"
}
elseif (!$WAUConfig.WAU_UseWhiteList -and (Test-Path "$WorkingDir\excluded_apps.txt")) {
Write-Log "List (black) is up to date." "Green"
}
else {
Write-Log "Critical: List doesn't exist, exiting..." "Red"
New-Item "$WorkingDir\logs\error.txt" -Value "List doesn't exist!" -Force
Write-Log "Critical: White/Black List doesn't exist, exiting..." "Red"
New-Item "$WorkingDir\logs\error.txt" -Value "White/Black List doesn't exist!" -Force
Exit 1
}
}
}
#Get External ModsPath if System
#Get External ModsPath if run as System
if ($WAUConfig.WAU_ModsPath) {
Write-Log "WAU uses External Mods from: $($WAUConfig.WAU_ModsPath)"
$NewMods, $DeletedMods = Test-ModsPath $WAUConfig.WAU_ModsPath $WAUConfig.InstallLocation
Write-Log "WAU uses External Mods from: $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/"))"
$NewMods, $DeletedMods = Test-ModsPath $WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/") $WAUConfig.InstallLocation.TrimEnd(" ", "\")
if ($ReachNoPath) {
Write-Log "Couldn't reach/find/compare/copy from $($WAUConfig.WAU_ModsPath.TrimEnd(" ", "\", "/"))..." "Red"
$Script:ReachNoPath = $False
}
if ($NewMods -gt 0) {
Write-Log "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation)\mods" "Yellow"
Write-Log "$NewMods newer Mods downloaded/copied to local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Yellow"
}
else {
if (Test-Path "$WorkingDir\mods\*.ps1") {
@ -111,7 +171,7 @@ if (Test-Network) {
}
}
if ($DeletedMods -gt 0) {
Write-Log "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation)\mods" "Red"
Write-Log "$DeletedMods Mods deleted (not externally managed) from local path: $($WAUConfig.InstallLocation.TrimEnd(" ", "\"))\mods" "Red"
}
}
}

View File

@ -0,0 +1,10 @@
#Function for creating shortcuts
function Add-Shortcut ($Target, $Shortcut, $Arguments, $Icon, $Description) {
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($Shortcut)
$Shortcut.TargetPath = $Target
$Shortcut.Arguments = $Arguments
$Shortcut.IconLocation = $Icon
$Shortcut.Description = $Description
$Shortcut.Save()
}

View File

@ -0,0 +1,354 @@
#Function to get Domain/Local Policies (GPO)
Function Get-Policies {
#Get WAU Policies and set the Configurations Registry Accordingly
$WAUPolicies = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Romanitho\Winget-AutoUpdate" -ErrorAction SilentlyContinue
if ($WAUPolicies) {
if ($($WAUPolicies.WAU_ActivateGPOManagement -eq 1)) {
$ChangedSettings = 0
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
if ($null -ne $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUPolicies.WAU_BypassListForUsers) -ne $($WAUConfig.WAU_BypassListForUsers))) {
New-ItemProperty $regPath -Name WAU_BypassListForUsers -Value $($WAUPolicies.WAU_BypassListForUsers) -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_BypassListForUsers) -and ($($WAUConfig.WAU_BypassListForUsers) -or $($WAUConfig.WAU_BypassListForUsers) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_BypassListForUsers -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUPolicies.WAU_DisableAutoUpdate) -ne $($WAUConfig.WAU_DisableAutoUpdate))) {
New-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Value $($WAUPolicies.WAU_DisableAutoUpdate) -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_DisableAutoUpdate) -and ($($WAUConfig.WAU_DisableAutoUpdate) -or $($WAUConfig.WAU_DisableAutoUpdate) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_DisableAutoUpdate -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_DoNotRunOnMetered) -and ($($WAUPolicies.WAU_DoNotRunOnMetered) -ne $($WAUConfig.WAU_DoNotRunOnMetered))) {
New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value $($WAUPolicies.WAU_DoNotRunOnMetered) -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_DoNotRunOnMetered) -and !$($WAUConfig.WAU_DoNotRunOnMetered)) {
New-ItemProperty $regPath -Name WAU_DoNotRunOnMetered -Value 1 -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UpdatePrerelease) -and ($($WAUPolicies.WAU_UpdatePrerelease) -ne $($WAUConfig.WAU_UpdatePrerelease))) {
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value $($WAUPolicies.WAU_UpdatePrerelease) -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UpdatePrerelease) -and $($WAUConfig.WAU_UpdatePrerelease)) {
New-ItemProperty $regPath -Name WAU_UpdatePrerelease -Value 0 -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUPolicies.WAU_UseWhiteList) -ne $($WAUConfig.WAU_UseWhiteList))) {
New-ItemProperty $regPath -Name WAU_UseWhiteList -Value $($WAUPolicies.WAU_UseWhiteList) -PropertyType DWord -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UseWhiteList) -and ($($WAUConfig.WAU_UseWhiteList) -or $($WAUConfig.WAU_UseWhiteList) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_UseWhiteList -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_ListPath) -and ($($WAUPolicies.WAU_ListPath) -ne $($WAUConfig.WAU_ListPath))) {
New-ItemProperty $regPath -Name WAU_ListPath -Value $($WAUPolicies.WAU_ListPath.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_ListPath) -and $($WAUConfig.WAU_ListPath)) {
Remove-ItemProperty $regPath -Name WAU_ListPath -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_ModsPath) -and ($($WAUPolicies.WAU_ModsPath) -ne $($WAUConfig.WAU_ModsPath))) {
New-ItemProperty $regPath -Name WAU_ModsPath -Value $($WAUPolicies.WAU_ModsPath.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_ModsPath) -and $($WAUConfig.WAU_ModsPath)) {
Remove-ItemProperty $regPath -Name WAU_ModsPath -Force -ErrorAction SilentlyContinue | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_NotificationLevel) -and ($($WAUPolicies.WAU_NotificationLevel) -ne $($WAUConfig.WAU_NotificationLevel))) {
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value $($WAUPolicies.WAU_NotificationLevel) -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_NotificationLevel) -and $($WAUConfig.WAU_NotificationLevel) -ne "Full") {
New-ItemProperty $regPath -Name WAU_NotificationLevel -Value "Full" -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UpdatesAtTime) -and ($($WAUPolicies.WAU_UpdatesAtTime) -ne $($WAUConfig.WAU_UpdatesAtTime))) {
New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $($WAUPolicies.WAU_UpdatesAtTime) -Force | Out-Null
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){
$PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0,11)
$PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19,6)
$Boundary = $PreStartBoundary + $($WAUPolicies.WAU_UpdatesAtTime) + $PostStartBoundary
$definition.Triggers.Item($triggerId).StartBoundary = $Boundary
break
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtTime) -and $($WAUConfig.WAU_UpdatesAtTime) -ne "06:00:00") {
New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value "06:00:00" -Force | Out-Null
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){
$PreStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(0,11)
$PostStartBoundary = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(19,6)
$Boundary = $PreStartBoundary + "06:00:00" + $PostStartBoundary
$definition.Triggers.Item($triggerId).StartBoundary = $Boundary
break
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UpdatesInterval) -and ($($WAUPolicies.WAU_UpdatesInterval) -ne $($WAUConfig.WAU_UpdatesInterval))) {
New-ItemProperty $regPath -Name WAU_UpdatesInterval -Value $($WAUPolicies.WAU_UpdatesInterval) -Force | Out-Null
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){
$UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11,8)
$definition.Triggers.Remove($triggerId)
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
if (!$($WAUConfig.WAU_UpdatesAtTime)) {
New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force | Out-Null
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
}
if ($($WAUPolicies.WAU_UpdatesInterval) -ne "Never") {
#Count Triggers (correctly)
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
$definition.Triggers.Count | Out-Null
switch ($($WAUPolicies.WAU_UpdatesInterval)) {
"Daily" {$tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime); break}
"BiDaily" {$tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime) -DaysInterval 2; break}
"Weekly" {$tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2; break}
"BiWeekly" {$tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 2; break}
"Monthly" {$tasktrigger = New-ScheduledTaskTrigger -Weekly -At $($WAUConfig.WAU_UpdatesAtTime) -DaysOfWeek 2 -WeeksInterval 4; break}
}
if ($definition.Triggers.Count -gt 0) {
$triggers = @()
$triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers
$triggers += $tasktrigger
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers
}
else {
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger
}
}
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UpdatesInterval) -and $($WAUConfig.WAU_UpdatesInterval) -ne "Daily") {
New-ItemProperty $regPath -Name WAU_UpdatesInterval -Value "Daily" -Force | Out-Null
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if(($definition.Triggers.Item($triggerId).Type -eq "2") -or ($definition.Triggers.Item($triggerId).Type -eq "3")){
$UpdatesAtTime = ($definition.Triggers.Item($triggerId).StartBoundary).Substring(11,8)
$definition.Triggers.Remove($triggerId)
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
if (!$($WAUConfig.WAU_UpdatesAtTime)) {
New-ItemProperty $regPath -Name WAU_UpdatesAtTime -Value $UpdatesAtTime -Force | Out-Null
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
}
$tasktrigger = New-ScheduledTaskTrigger -Daily -At $($WAUConfig.WAU_UpdatesAtTime)
#Count Triggers (correctly)
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
$definition.Triggers.Count | Out-Null
if ($definition.Triggers.Count -gt 0) {
$triggers = @()
$triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers
$triggers += $tasktrigger
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers
}
else {
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger
}
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUPolicies.WAU_UpdatesAtLogon) -ne $($WAUConfig.WAU_UpdatesAtLogon))) {
if ($WAUPolicies.WAU_UpdatesAtLogon -eq 1) {
New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null
$triggers = @()
$triggers += (Get-ScheduledTask "Winget-AutoUpdate").Triggers
#Count Triggers (correctly)
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
$definition.Triggers.Count | Out-Null
if ($definition.Triggers.Count -gt 0) {
$triggers += New-ScheduledTaskTrigger -AtLogon
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $triggers
}
else {
$tasktrigger = New-ScheduledTaskTrigger -AtLogon
Set-ScheduledTask -TaskName "Winget-AutoUpdate" -Trigger $tasktrigger
}
}
else {
New-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Value $($WAUPolicies.WAU_UpdatesAtLogon) -PropertyType DWord -Force | Out-Null
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
$definition.Triggers.Count | Out-Null
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if($definition.Triggers.Item($triggerId).Type -eq "9"){
$definition.Triggers.Remove($triggerId)
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
}
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UpdatesAtLogon) -and ($($WAUConfig.WAU_UpdatesAtLogon) -or $($WAUConfig.WAU_UpdatesAtLogon) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_UpdatesAtLogon -Force -ErrorAction SilentlyContinue | Out-Null
$service = New-Object -ComObject Schedule.Service
$service.Connect($env:COMPUTERNAME)
$folder = $service.GetFolder('\')
$task = $folder.GetTask("Winget-AutoUpdate")
$definition = $task.Definition
for($triggerId=1; $triggerId -le $definition.Triggers.Count; $triggerId++){
if($definition.Triggers.Item($triggerId).Type -eq "9"){
$definition.Triggers.Remove($triggerId)
$triggerId-=1
}
}
$folder.RegisterTaskDefinition($task.Name, $definition, 4, $null, $null, $null) | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_UserContext) -and ($($WAUPolicies.WAU_UserContext) -ne $($WAUConfig.WAU_UserContext))) {
New-ItemProperty $regPath -Name WAU_UserContext -Value $($WAUPolicies.WAU_UserContext) -PropertyType DWord -Force | Out-Null
if ($WAUPolicies.WAU_UserContext -eq 1) {
# Settings for the scheduled task in User context
$taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\winget-upgrade.ps1`"`""
$taskUserPrincipal = New-ScheduledTaskPrincipal -GroupId S-1-5-11
$taskSettings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 03:00:00
# Set up the task for user apps
$task = New-ScheduledTask -Action $taskAction -Principal $taskUserPrincipal -Settings $taskSettings
Register-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -InputObject $task -Force
}
else {
Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False
}
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_UserContext) -and ($($WAUConfig.WAU_UserContext) -or $($WAUConfig.WAU_UserContext) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_UserContext -Force -ErrorAction SilentlyContinue | Out-Null
Get-ScheduledTask -TaskName "Winget-AutoUpdate-UserContext" -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$False
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUPolicies.WAU_DesktopShortcut) -ne $($WAUConfig.WAU_DesktopShortcut))) {
New-ItemProperty $regPath -Name WAU_DesktopShortcut -Value $($WAUPolicies.WAU_DesktopShortcut) -PropertyType DWord -Force | Out-Null
if ($WAUPolicies.WAU_DesktopShortcut -eq 1) {
Add-Shortcut "wscript.exe" "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..."
}
else {
Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null
}
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_DesktopShortcut) -and ($($WAUConfig.WAU_DesktopShortcut) -or $($WAUConfig.WAU_DesktopShortcut) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_DesktopShortcut -Force -ErrorAction SilentlyContinue | Out-Null
Remove-Item -Path "${env:Public}\Desktop\WAU - Check for updated Apps.lnk" -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUPolicies.WAU_StartMenuShortcut) -ne $($WAUConfig.WAU_StartMenuShortcut))) {
New-ItemProperty $regPath -Name WAU_StartMenuShortcut -Value $($WAUPolicies.WAU_StartMenuShortcut) -PropertyType DWord -Force | Out-Null
if ($WAUPolicies.WAU_StartMenuShortcut -eq 1) {
if (!(Test-Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)")) {
New-Item -ItemType Directory -Force -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" | Out-Null
}
Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Check for updated Apps.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`"`"" "${env:SystemRoot}\System32\shell32.dll,-16739" "Manual start of Winget-AutoUpdate (WAU)..."
Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Open logs.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Logs`"" "${env:SystemRoot}\System32\shell32.dll,-16763" "Open existing WAU logs..."
Add-Shortcut "wscript.exe" "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)\WAU - Web Help.lnk" "`"$($WAUConfig.InstallLocation)\Invisible.vbs`" `"powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"`"`"$($WAUConfig.InstallLocation)\user-run.ps1`" -Help`"" "${env:SystemRoot}\System32\shell32.dll,-24" "Help for WAU..."
}
else {
Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null
}
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_StartMenuShortcut) -and ($($WAUConfig.WAU_StartMenuShortcut) -or $($WAUConfig.WAU_StartMenuShortcut) -eq 0)) {
Remove-ItemProperty $regPath -Name WAU_StartMenuShortcut -Force -ErrorAction SilentlyContinue | Out-Null
Remove-Item -Path "${env:ProgramData}\Microsoft\Windows\Start Menu\Programs\Winget-AutoUpdate (WAU)" -Recurse -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_MaxLogFiles) -and ($($WAUPolicies.WAU_MaxLogFiles) -ne $($WAUConfig.WAU_MaxLogFiles))) {
New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value $($WAUPolicies.WAU_MaxLogFiles.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_MaxLogFiles) -and $($WAUConfig.WAU_MaxLogFiles) -ne 3) {
New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value 3 -Force | Out-Null
$ChangedSettings++
}
if ($null -ne $($WAUPolicies.WAU_MaxLogSize) -and ($($WAUPolicies.WAU_MaxLogSize) -ne $($WAUConfig.WAU_MaxLogSize))) {
New-ItemProperty $regPath -Name WAU_MaxLogSize -Value $($WAUPolicies.WAU_MaxLogSize.TrimEnd(" ", "\", "/")) -Force | Out-Null
$ChangedSettings++
}
elseif ($null -eq $($WAUPolicies.WAU_MaxLogSize) -and $($WAUConfig.WAU_MaxLogSize) -ne 1048576) {
New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -Force | Out-Null
$ChangedSettings++
}
#Get WAU Configurations after Policies change
$Script:WAUConfig = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
}
}
Return $($WAUPolicies.WAU_ActivateGPOManagement), $ChangedSettings
}

View File

@ -9,7 +9,10 @@ function Get-WingetSystemApps {
#Convert json file to txt file with app ids
$InstalledApps = get-content $jsonFile | ConvertFrom-Json
#Return app list
#Save app list
Set-Content $InstalledApps.Sources.Packages.PackageIdentifier -Path $jsonFile
#Sort app list
Get-Content $jsonFile | Sort-Object | Set-Content $jsonFile
}

View File

@ -0,0 +1,79 @@
#Function rotate the logs
function Invoke-LogRotation ($LogFile, $MaxLogFiles, $MaxLogSize) {
<#
.SYNOPSIS
Handle log rotation.
.DESCRIPTION
Invoke-LogRotation handles log rotation
.NOTES
Author: Øyvind Kallstad (Minimized and changed for WAU 12.01.2023 by Göran Axel Johannesson)
URL: https://www.powershellgallery.com/packages/Communary.Logger/1.1
Date: 21.11.2014
Version: 1.0
#>
try {
# get current size of log file
$currentSize = (Get-Item $LogFile).Length
# get log name
$logFileName = Split-Path $LogFile -Leaf
$logFilePath = Split-Path $LogFile
$logFileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($logFileName)
$logFileNameExtension = [System.IO.Path]::GetExtension($logFileName)
# if MaxLogFiles is 1 just keep the original one and let it grow
if (-not($MaxLogFiles -eq 1)) {
if ($currentSize -ge $MaxLogSize) {
# construct name of archived log file
$newLogFileName = $logFileNameWithoutExtension + (Get-Date -Format 'yyyyMMddHHmmss').ToString() + $logFileNameExtension
# copy old log file to new using the archived name constructed above
Copy-Item -Path $LogFile -Destination (Join-Path (Split-Path $LogFile) $newLogFileName)
# Create a new log file
try {
Remove-Item -Path $LogFile -Force
New-Item -ItemType File -Path $LogFile -Force
#Set ACL for users on logfile
$NewAcl = Get-Acl -Path $LogFile
$identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11
$fileSystemRights = "Modify"
$type = "Allow"
$fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, $type
$fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList
$NewAcl.SetAccessRule($fileSystemAccessRule)
Set-Acl -Path $LogFile -AclObject $NewAcl
}
catch {
Return $True, $False
}
# if MaxLogFiles is 0 don't delete any old archived log files
if (-not($MaxLogFiles -eq 0)) {
# set filter to search for archived log files
$archivedLogFileFilter = $logFileNameWithoutExtension + '??????????????' + $logFileNameExtension
# get archived log files
$oldLogFiles = Get-Item -Path "$(Join-Path -Path $logFilePath -ChildPath $archivedLogFileFilter)"
if ([bool]$oldLogFiles) {
# compare found log files to MaxLogFiles parameter of the log object, and delete oldest until we are
# back to the correct number
if (($oldLogFiles.Count + 1) -gt $MaxLogFiles) {
[int]$numTooMany = (($oldLogFiles.Count) + 1) - $MaxLogFiles
$oldLogFiles | Sort-Object 'LastWriteTime' | Select-Object -First $numTooMany | Remove-Item
}
}
}
Return $False, $True
}
}
}
catch {
Return $True, $False
}
}

View File

@ -43,6 +43,16 @@ function Invoke-PostUpdateActions {
Write-Log "-> Notification level setting was missing. Fixed with 'Full' option."
}
#Set WAU_MaxLogFiles/WAU_MaxLogSize if not set
$MaxLogFiles = Get-ItemProperty $regPath -Name WAU_MaxLogFiles -ErrorAction SilentlyContinue
if (!$MaxLogFiles) {
New-ItemProperty $regPath -Name WAU_MaxLogFiles -Value 3 -PropertyType DWord -Force | Out-Null
New-ItemProperty $regPath -Name WAU_MaxLogSize -Value 1048576 -PropertyType DWord -Force | Out-Null
#log
Write-Log "-> 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
$WAUAboutPath = "$WorkingDir\config\about.xml"
if (test-path $WAUAboutPath) {

View File

@ -30,29 +30,41 @@ function Test-ListPath ($ListPath, $UseWhiteList, $WingetUpdatePath) {
$wc.DownloadFile($ExternalList, $LocalList)
}
catch {
$Script:ReachNoPath = $True
return $False
}
return $true
}
}
catch {
$Script:ReachNoPath = $True
return $False
}
}
# If path is UNC or local
else {
if (Test-Path -Path $ExternalList -PathType leaf) {
if (Test-Path -Path $ExternalList) {
try {
$dateExternal = (Get-Item "$ExternalList").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
}
catch {
$Script:ReachNoPath = $True
return $False
}
if ($dateExternal -gt $dateLocal) {
try {
Copy-Item $ExternalList -Destination $LocalList -Force
}
catch {
$Script:ReachNoPath = $True
return $False
}
return $true
return $True
}
}
else {
$Script:ReachNoPath = $True
}
return $False
}
return $false
}

View File

@ -8,11 +8,10 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
#Get File Names Locally
$InternalModsNames = Get-ChildItem -Path $LocalMods -Name -Recurse -Include *.ps1, *.txt
$InternalBinsNames = Get-ChildItem -Path $LocalMods"\bins" -Name -Recurse -Include *.exe
# If path is URL
if ($ExternalMods -like "http*") {
$wc = New-Object System.Net.WebClient
# enable TLS 1.2 and TLS 1.1 protocols
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Tls11
#Get Index of $ExternalMods (or index page with href listing of all the Mods)
@ -20,21 +19,89 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
$WebResponse = Invoke-WebRequest -Uri $ExternalMods -UseBasicParsing
}
catch {
$Script:ReachNoPath = $True
return $False
}
#Check for bins, download if newer. Delete if not external
$ExternalBins = "$ModsPath/bins"
if ($WebResponse -match "bins/") {
$BinResponse = Invoke-WebRequest -Uri $ExternalBins -UseBasicParsing
# Collect the external list of href links
$ModLinks = $WebResponse.Links | Select-Object -ExpandProperty href
#Delete Local Mods that don't exist Externally
foreach ($Mod in $InternalModsNames) {
If ($Mod -notin $ModLinks) {
Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null
$DeletedMods++
$BinLinks = $BinResponse.Links | Select-Object -ExpandProperty HREF
#If there's a directory path in the HREF:s, delete it (IIS)
$CleanBinLinks = $BinLinks -replace "/.*/",""
#Modify strings to HREF:s
$index = 0
foreach ($Bin in $CleanBinLinks) {
if ($Bin) {
$CleanBinLinks[$index] = '<a href="' + $Bin + '"> ' + $Bin + '</a>'
}
$index++
}
#Delete Local Bins that don't exist Externally
$index = 0
$CleanLinks = $BinLinks -replace "/.*/",""
foreach ($Bin in $InternalBinsNames) {
If ($CleanLinks -notcontains "$Bin") {
Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null
}
$index++
}
$CleanBinLinks = $BinLinks -replace "/.*/",""
$Bin = ""
#Loop through all links
$wc = New-Object System.Net.WebClient
$CleanBinLinks | ForEach-Object {
#Check for .exe in listing/HREF:s in an index page pointing to .exe
if ($_ -like "*.exe") {
$dateExternalBin = ""
$dateLocalBin =""
$wc.OpenRead("$ExternalBins/$_").Close() | Out-Null
$dateExternalBin = ([DateTime]$wc.ResponseHeaders['Last-Modified']).ToString("yyyy-MM-dd HH:mm:ss")
if (Test-Path -Path $LocalMods"\bins\"$_) {
$dateLocalBin = (Get-Item "$LocalMods\bins\$_").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
}
if ($dateExternalBin -gt $dateLocalBin) {
$SaveBin = Join-Path -Path "$LocalMods\bins" -ChildPath $_
Invoke-WebRequest -Uri "$ExternalBins/$_" -OutFile $SaveBin.Replace("%20"," ") -UseBasicParsing
}
}
}
}
# Collect the external list of href links
$ModLinks = $WebResponse.Links | Select-Object -ExpandProperty HREF
#If there's a directory path in the HREF:s, delete it (IIS)
$CleanLinks = $ModLinks -replace "/.*/",""
#Modify strings to HREF:s
$index = 0
foreach ($Mod in $CleanLinks) {
if ($Mod) {
$CleanLinks[$index] = '<a href="' + $Mod + '"> ' + $Mod + '</a>'
}
$index++
}
#Delete Local Mods that don't exist Externally
$DeletedMods = 0
$index = 0
$CleanLinks = $ModLinks -replace "/.*/",""
foreach ($Mod in $InternalModsNames) {
If ($CleanLinks -notcontains "$Mod") {
Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null
$DeletedMods++
}
$index++
}
$CleanLinks = $ModLinks -replace "/.*/",""
#Loop through all links
$WebResponse.Links | Select-Object -ExpandProperty href | ForEach-Object {
$wc = New-Object System.Net.WebClient
$CleanLinks | ForEach-Object {
#Check for .ps1/.txt in listing/HREF:s in an index page pointing to .ps1/.txt
if (($_ -like "*.ps1") -or ($_ -like "*.txt")) {
try {
@ -54,12 +121,14 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
$ModsUpdated++
}
catch {
return $False
$Script:ReachNoPath = $True
}
}
}
catch {
return $False
if (($_ -like "*.ps1") -or ($_ -like "*.txt")) {
$Script:ReachNoPath = $True
}
}
}
}
@ -67,17 +136,43 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
}
# If path is UNC or local
else {
$ExternalBins = "$ModsPath\bins"
if (Test-Path -Path $ExternalBins"\*.exe") {
$ExternalBinsNames = Get-ChildItem -Path $ExternalBins -Name -Recurse -Include *.exe
#Delete Local Bins that don't exist Externally
foreach ($Bin in $InternalBinsNames){
If ($Bin -notin $ExternalBinsNames ){
Remove-Item $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null
}
}
#Copy newer external bins
foreach ($Bin in $ExternalBinsNames){
$dateExternalBin = ""
$dateLocalBin =""
if (Test-Path -Path $LocalMods"\bins\"$Bin) {
$dateLocalBin = (Get-Item "$LocalMods\bins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
}
$dateExternalBin = (Get-Item "$ExternalBins\$Bin").LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
if ($dateExternalBin -gt $dateLocalBin) {
Copy-Item $ExternalBins\$Bin -Destination $LocalMods\bins\$Bin -Force -ErrorAction SilentlyContinue | Out-Null
}
}
}
if ((Test-Path -Path $ExternalMods"\*.ps1") -or (Test-Path -Path $ExternalMods"\*.txt")) {
#Get File Names Externally
$ExternalModsNames = Get-ChildItem -Path $ExternalMods -Name -Recurse -Include *.ps1, *.txt
#Delete Local Mods that don't exist Externally
$DeletedMods = 0
foreach ($Mod in $InternalModsNames){
If ($Mod -notin $ExternalModsNames ){
Remove-Item $LocalMods\$Mod -Force -ErrorAction SilentlyContinue | Out-Null
$DeletedMods++
}
}
try {
#Copy newer external mods
foreach ($Mod in $ExternalModsNames){
$dateExternalMod = ""
$dateLocalMod =""
@ -90,13 +185,10 @@ function Test-ModsPath ($ModsPath, $WingetUpdatePath) {
$ModsUpdated++
}
}
}
catch {
return $False
else {
$Script:ReachNoPath = $True
}
return $ModsUpdated, $DeletedMods
}
return $False
}
}

View File

@ -1,7 +1,10 @@
Pre/During/Post install/uninstall custom scripts should be placed here.
A script Template and Mods Functions are included as example to get you started...
A script **Template** and **Mods Functions** are included as **example** to get you started...
Scripts that are considered:
**AppID**`-preinstall.ps1`, `-upgrade.ps1`, `-install.ps1`, `-installed.ps1`, `-preuninstall.ps1`, `-uninstall.ps1` or `-uninstalled.ps1`
The **-install** mod will be used for upgrades too if **-upgrade** doesn't exist (**WAU** first tries `& $Winget upgrade --id` and if the app isn't detected after that `& $Winget install --id` is tried).
`AppID-install.ps1` is recommended because it's used in **both** scenarios.
**AppID**`-override.txt` (the content) will be used as a native **winget --override** parameter when upgrading

View File

@ -1,4 +1,9 @@
<# ARRAYS/VARIABLES #>
#App to Run ($RunWait = $False if it shouldn't be waited for)
$Run = ""
$RunSwitch = ""
$RunWait = $True
#Beginning of Process Name to Stop - optional wildcard (*) after, without .exe, multiple: "proc1","proc2"
$Proc = @("")
@ -6,16 +11,49 @@ $Proc = @("")
$Wait = @("")
#Beginning of App Name string to Silently Uninstall (MSI/NSIS/INNO/EXE with defined silent uninstall in registry)
#Required wildcard (*) after, search is done with "-like"!
$App = ""
#Multiple: "app1*","app2*", required wildcard (*) after; search is done with "-like"!
$App = @("")
#Beginning of Desktop Link Name to Remove - optional wildcard (*) after, without .lnk, multiple: "lnk1","lnk2"
$Lnk = @("")
#Registry _value_ (DWord/String) to add in existing registry Key (Key created if not existing). Example:
#$AddKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
#$AddValue = "WAU_BypassListForUsers"
#$AddTypeData = "1"
#$AddType = "DWord"
$AddKey = ""
$AddValue = ""
$AddTypeData = ""
$AddType = ""
#Registry _value_ to delete in existing registry Key.
#Value can be omitted for deleting entire Key!. Example:
#$DelKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Winget-AutoUpdate"
#$DelValue = "WAU_BypassListForUsers"
$DelKey = ""
$DelValue = ""
#Remove file/directory, multiple: "file1","file2"
$DelFile = @("")
#Copy file/directory
#Example:
#$CopyFile = "C:\Logfiles"
#$CopyTo = "C:\Drawings\Logs"
$CopyFile = ""
$CopyTo = ""
#Grant "Modify" for directory/file to "Authenticated Users" - multiple: "dir1","dir2"
$GrantPath = @("")
<# FUNCTIONS #>
. $PSScriptRoot\_Mods-Functions.ps1
<# MAIN #>
if ($Run) {
Invoke-ModsApp $Run $RunSwitch $RunWait
}
if ($Proc) {
Stop-ModsProc $Proc
}
@ -28,5 +66,20 @@ if ($App) {
if ($Lnk) {
Remove-ModsLnk $Lnk
}
if ($AddKey -and $AddValue -and $AddTypeData -and $AddType) {
Add-ModsReg $AddKey $AddValue $AddTypeData $AddType
}
if ($DelKey) {
Remove-ModsReg $DelKey $DelValue
}
if ($DelFile) {
Remove-ModsFile $DelFile
}
if ($CopyFile -and $CopyTo) {
Copy-ModsFile $CopyFile $CopyTo
}
if ($GrantPath) {
Grant-ModsPath $GrantPath
}
<# EXTRAS #>

View File

@ -1,5 +1,18 @@
#Common shared functions for mods handling
function Invoke-ModsApp ($Run, $RunSwitch, $RunWait) {
if (Test-Path "$Run") {
if (!$RunWait) {
Start-Process $Run -ArgumentList $RunSwitch
}
else {
Start-Process $Run -ArgumentList $RunSwitch -Wait
}
}
Return
}
function Stop-ModsProc ($Proc) {
foreach ($process in $Proc)
{
@ -7,6 +20,7 @@ function Stop-ModsProc ($Proc) {
}
Return
}
function Wait-ModsProc ($Wait) {
foreach ($process in $Wait)
{
@ -14,11 +28,15 @@ function Wait-ModsProc ($Wait) {
}
Return
}
function Uninstall-ModsApp ($App) {
foreach ($app in $App)
{
$InstalledSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
foreach ($obj in $InstalledSoftware){
if ($obj.GetValue('DisplayName') -like $App) {
$UninstallString = $obj.GetValue('UninstallString')
$CleanedUninstallString = $UninstallString.Trim([char]0x0022)
if ($UninstallString -like "MsiExec.exe*") {
$ProductCode = Select-String "{.*}" -inputobject $UninstallString
$ProductCode = $ProductCode.matches.groups[0].value
@ -39,19 +57,28 @@ function Uninstall-ModsApp ($App) {
Start-Process $Command -ArgumentList $Parameter -Wait
}
else {
$NullSoft = Select-String -Path $UninstallString.Trim([char]0x0022) -Pattern "Nullsoft"
if ((Test-Path $CleanedUninstallString)) {
$NullSoft = Select-String -Path $CleanedUninstallString -Pattern "Nullsoft"
}
if ($NullSoft) {
#NSIS x64 Installer
Start-Process $UninstallString -ArgumentList "/S" -Wait
}
else {
$Inno = Select-String -Path $UninstallString.Trim([char]0x0022) -Pattern "Inno Setup"
if ((Test-Path $CleanedUninstallString)) {
$Inno = Select-String -Path $CleanedUninstallString -Pattern "Inno Setup"
}
if ($Inno) {
#Inno x64 Installer
Start-Process $UninstallString -ArgumentList "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" -Wait
}
else {
Write-Host "x64 Uninstaller unknown..."
Write-Host "x64 Uninstaller unknown, trying the UninstallString from registry..."
$NativeUninstallString = Select-String "(\x22.*\x22) +(.*)" -inputobject $UninstallString
$Command = $NativeUninstallString.matches.groups[1].value
$Parameter = $NativeUninstallString.matches.groups[2].value
#All EXE x64 Installers (native defined uninstall)
Start-Process $Command -ArgumentList $Parameter -Wait
}
}
}
@ -65,6 +92,7 @@ function Uninstall-ModsApp ($App) {
foreach ($obj in $InstalledSoftware){
if ($obj.GetValue('DisplayName') -like $App) {
$UninstallString = $obj.GetValue('UninstallString')
$CleanedUninstallString = $UninstallString.Trim([char]0x0022)
if ($UninstallString -like "MsiExec.exe*") {
$ProductCode = Select-String "{.*}" -inputobject $UninstallString
$ProductCode = $ProductCode.matches.groups[0].value
@ -85,19 +113,28 @@ function Uninstall-ModsApp ($App) {
Start-Process $Command -ArgumentList $Parameter -Wait
}
else {
$NullSoft = Select-String -Path $UninstallString.Trim([char]0x0022) -Pattern "Nullsoft"
if ((Test-Path $CleanedUninstallString)) {
$NullSoft = Select-String -Path $CleanedUninstallString -Pattern "Nullsoft"
}
if ($NullSoft) {
#NSIS x86 Installer
Start-Process $UninstallString -ArgumentList "/S" -Wait
}
else {
$Inno = Select-String -Path $UninstallString.Trim([char]0x0022) -Pattern "Inno Setup"
if ((Test-Path $CleanedUninstallString)) {
$Inno = Select-String -Path $CleanedUninstallString -Pattern "Inno Setup"
}
if ($Inno) {
#Inno x86 Installer
Start-Process $UninstallString -ArgumentList "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" -Wait
}
else {
Write-Host "x86 Uninstaller unknown..."
Write-Host "x86 Uninstaller unknown, trying the UninstallString from registry..."
$NativeUninstallString = Select-String "(\x22.*\x22) +(.*)" -inputobject $UninstallString
$Command = $NativeUninstallString.matches.groups[1].value
$Parameter = $NativeUninstallString.matches.groups[2].value
#All EXE x86 Installers (native defined uninstall)
Start-Process $Command -ArgumentList $Parameter -Wait
}
}
}
@ -106,8 +143,10 @@ function Uninstall-ModsApp ($App) {
}
}
}
}
Return
}
function Remove-ModsLnk ($Lnk) {
foreach ($link in $Lnk)
{
@ -115,3 +154,60 @@ function Remove-ModsLnk ($Lnk) {
}
Return
}
function Add-ModsReg ($AddKey, $AddValue, $AddTypeData, $AddType) {
if (!Test-Path "$AddKey") {
New-Item $AddKey -Force -ErrorAction SilentlyContinue | Out-Null
}
New-ItemProperty $AddKey -Name $AddValue -Value $AddTypeData -PropertyType $AddType -Force | Out-Null
Return
}
function Remove-ModsReg ($DelKey, $DelValue) {
if (Test-Path "$DelKey") {
if (!$DelValue) {
Remove-Item $DelKey -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
}
else {
Remove-ItemProperty $DelKey -Name $DelValue -Force -ErrorAction SilentlyContinue | Out-Null
}
}
Return
}
function Remove-ModsFile ($DelFile) {
foreach ($file in $DelFile)
{
if (Test-Path "$file") {
Remove-Item -Path $file -Force -Recurse -ErrorAction SilentlyContinue | Out-Null
}
}
Return
}
function Copy-ModsFile ($CopyFile, $CopyTo) {
if (Test-Path "$CopyFile") {
Copy-Item -Path $CopyFile -Destination $CopyTo -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
}
Return
}
function Grant-ModsPath ($GrantPath) {
foreach ($path in $GrantPath)
{
if (Test-Path "$path") {
$NewAcl = Get-Acl -Path $path
$identity = New-Object System.Security.Principal.SecurityIdentifier S-1-5-11
if ((Get-Item $path) -is [System.IO.DirectoryInfo]) {
$fileSystemAccessRuleArgumentList = $identity, 'Modify', 'ContainerInherit, ObjectInherit', 'InheritOnly', 'Allow'
}
else {
$fileSystemAccessRuleArgumentList = $identity, 'Modify', 'Allow'
}
$fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList
$NewAcl.SetAccessRule($fileSystemAccessRule)
Set-Acl -Path $path -AclObject $NewAcl
}
}
Return
}

View File

@ -0,0 +1,6 @@
A Directory for placing useful **bins** (**MsiZap.exe** as a really good example) for running via the **Template Function**:
#App to Run ($RunWait = $False if it shouldn't be waited for)
$Run = ""
$RunSwitch = ""
$RunWait = $True