Skip to content

Commit 27e25c5

Browse files
committed
Enhance deployment instructions and mod functionality in README and scripts
- Updated README.md to include deployment examples for SCCM and Intune. - Improved Winget-Install.ps1 to handle mod overrides and custom parameters. - Enhanced Update-App.ps1 to support pre-install checks and improved logging. - Added functionality to skip apps based on running processes in mod templates. - Introduced new functions for process management in _Mods-Functions.ps1. - Implemented winget-detect.ps1 for detecting installed applications.
1 parent de34b54 commit 27e25c5

File tree

7 files changed

+262
-132
lines changed

7 files changed

+262
-132
lines changed

README.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,25 @@ Default is 1048576 = 1 MB (ca. 7500 lines)
175175
Specify Winget-AutoUpdate installation location. Default: `C:\Program Files\Winget-AutoUpdate` (Recommended to leave default).
176176

177177
### Deploy with Intune
178-
You can use [Winget-Install](https://github.com/Romanitho/Winget-AutoUpdate/blob/main/Sources/Winget-AutoUpdate/Winget-Install.ps1) to deploy the package for example in Intune:
178+
You can use [Winget-Install](https://github.com/Romanitho/Winget-AutoUpdate/blob/main/Sources/Winget-AutoUpdate/Winget-Install.ps1) to deploy the package (this example with an override of parameters):
179179
```batch
180-
"%systemroot%\sysnative\WindowsPowerShell\v1.0\powershell.exe" -noprofile -executionpolicy bypass -file "C:\Program Files\Winget-AutoUpdate\Winget-Install.ps1" -AppIDs "Romanitho.Winget-AutoUpdate --scope machine --override \"/qn RUN_WAU=YES USERCONTEXT=1 STARTMENUSHORTCUT=1 NOTIFICATIONLEVEL=SuccessOnly UPDATESINTERVAL=Daily""
180+
"%systemroot%\sysnative\WindowsPowerShell\v1.0\powershell.exe" -noprofile -executionpolicy bypass -file "C:\Program Files\Winget-AutoUpdate\Winget-Install.ps1" -AppIDs "Adobe.Acrobat.Reader.64-bit --scope machine --override \"-sfx_nu /sAll /rs /msi EULA_ACCEPT=YES DISABLEDESKTOPSHORTCUT=1""
181181
```
182+
### Deploy with SCCM
183+
You can also use [Winget-Install](https://github.com/Romanitho/Winget-AutoUpdate/blob/main/Sources/Winget-AutoUpdate/Winget-Install.ps1) to deploy the same package in **SCCM**:
184+
```batch
185+
powershell.exe -noprofile -executionpolicy bypass -file "C:\Program Files\Winget-AutoUpdate\Winget-Install.ps1" -AppIDs "Adobe.Acrobat.Reader.64-bit --scope machine --override \"-sfx_nu /sAll /rs /msi EULA_ACCEPT=YES DISABLEDESKTOPSHORTCUT=1""
186+
```
187+
Instead of including the override parameters in the install string you can use a **Mod** (**mods\Adobe.Acrobat.Reader.64-bit-override.txt**) with the content:
188+
```batch
189+
"-sfx_nu /sAll /rs /msi EULA_ACCEPT=YES DISABLEDESKTOPSHORTCUT=1"
190+
```
191+
* A standard single installation: **-AppIDs Notepad++.Notepad++**
192+
* Multiple installations: **-AppIDs "7zip.7zip, Notepad++.Notepad++"**
193+
194+
As a detection script use **config\winget-detect.ps1** (change app to detect [**Application ID**]) in **Intune**/**SCCM** ([winget-detect.ps1](Sources/Winget-AutoUpdate/config/winget-detect.ps1))
195+
196+
A nice feature is if you're already using the deprecated standalone script **winget-install.ps1** from the [old repo](https://github.com/Romanitho/Winget-Install) and have placed it somwhere locally on all clients you can make a **SymLink** in its place and keep using the old path (avoiding a lot of work) in your deployed applications (**Winget-Install.ps1** takes care of the SymLink logic).
182197

183198
## GPO / Intune Management
184199
Read more in the [Policies section](https://github.com/Romanitho/Winget-AutoUpdate/tree/main/Sources/Policies).
@@ -191,6 +206,8 @@ If **ExitCode** is **1** from `_WAU-mods.ps1` then **Re-run WAU**.
191206

192207
Likewise `_WAU-mods-postsys.ps1` can be used to do things at the end of the **SYSTEM context WAU** process before the user run.
193208

209+
You can find more information in [README Mods for WAU](Sources/Winget-AutoUpdate/mods/README.md)
210+
194211
## Custom scripts (Mods feature for Apps)
195212
The Mods feature allows you to run additional scripts when upgrading or installing an app.
196213
Just put the scripts in question with the **AppID** followed by the `-preinstall`, `-upgrade`, `-install`, `-installed` or `-notinstalled` suffix in the **mods** folder.
@@ -207,18 +224,24 @@ The **-install** mod will be used for upgrades too if **-upgrade** doesn't exist
207224
> Example:<br>
208225
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.
209226

210-
You can find more information on [Winget-Install Repo](https://github.com/Romanitho/Winget-AutoUpdate?tab=readme-ov-file#custom-script-mods-for-wau), as it's a related feature.<br>
211-
Read more in the `README.md` under the directory **mods**.
227+
You can find more information in [README Mods for WAU](Sources/Winget-AutoUpdate/mods/README.md), as it's a related feature.
212228

213229
Share your mods with the community:<br>
214230
<https://github.com/Romanitho/Winget-AutoUpdate/discussions/categories/mods>
215231

216232
### Winget native parameters
217233
Another finess is the **AppID** followed by the `-override` suffix as a **text file** (.**txt**) that you can place under the **mods** folder.
218234
> Example:<br>
219-
**Canneverbe.CDBurnerXP-override.txt** with the content `ADDLOCAL=All REMOVE=Desktop_Shortcut /qn`
235+
**Adobe.Acrobat.Reader.64-bit-override.txt** with the content `"-sfx_nu /sAll /rs /msi EULA_ACCEPT=YES DISABLEDESKTOPSHORTCUT=1"`
236+
237+
This will use the **content** of the text file as a native **winget --override** parameter when upgrading.
238+
239+
Likewise you can use the **AppID** followed by the `-custom` suffix as a **text file** (.**txt**) that you can place under the **mods** folder (*Arguments to be passed on to the installer in addition to the defaults*).
240+
> Example:<br>
241+
**Adobe.Acrobat.Reader.64-bit-custom.txt** with the content `"DISABLEDESKTOPSHORTCUT=1"`
242+
243+
This will use the **content** of the text file as a native **winget --custom** parameter when upgrading.
220244

221-
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)).
222245

223246
## Known issues
224247
* 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>

Sources/Winget-AutoUpdate/Winget-Install.ps1

Lines changed: 66 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<#
22
.SYNOPSIS
33
Install apps with Winget through Intune or SCCM.
4-
Can be used standalone.
4+
(Can be used standalone.) - Deprecated in favor of Winget-AutoUpdate.
55
66
.DESCRIPTION
77
Allow to run Winget in System Context to install your apps.
8-
https://github.com/Romanitho/Winget-Install
8+
(https://github.com/Romanitho/Winget-Install) - Deprecated in favor of Winget-AutoUpdate.
99
1010
.PARAMETER AppIDs
1111
Forward Winget App ID to install. For multiple apps, separate with ",". Case sensitive.
@@ -90,59 +90,39 @@ function Confirm-Exist ($AppID) {
9090

9191
#Check if install modifications exist in "mods" directory
9292
function Test-ModsInstall ($AppID) {
93-
#Check current location
94-
if (Test-Path ".\mods\$AppID-preinstall.ps1") {
95-
$ModsPreInstall = ".\mods\$AppID-preinstall.ps1"
96-
}
97-
#Else, check in WAU mods
98-
elseif (Test-Path "$WAUModsLocation\$AppID-preinstall.ps1") {
99-
$ModsPreInstall = "$WAUModsLocation\$AppID-preinstall.ps1"
100-
}
101-
102-
if (Test-Path ".\mods\$AppID-install.ps1") {
103-
$ModsInstall = ".\mods\$AppID-install.ps1"
104-
}
105-
elseif (Test-Path "$WAUModsLocation\$AppID-install.ps1") {
106-
$ModsInstall = "$WAUModsLocation\$AppID-install.ps1"
107-
}
108-
109-
if (Test-Path ".\mods\$AppID-installed-once.ps1") {
110-
$ModsInstalledOnce = ".\mods\$AppID-installed-once.ps1"
111-
}
112-
113-
if (Test-Path ".\mods\$AppID-installed.ps1") {
114-
$ModsInstalled = ".\mods\$AppID-installed.ps1"
115-
}
116-
elseif (Test-Path "$WAUModsLocation\$AppID-installed.ps1") {
117-
$ModsInstalled = "$WAUModsLocation\$AppID-installed.ps1"
93+
if (Test-Path "$Mods\$AppID-*") {
94+
if (Test-Path "$Mods\$AppID-preinstall.ps1") {
95+
$ModsPreInstall = "$Mods\$AppID-preinstall.ps1"
96+
}
97+
if (Test-Path "$Mods\$AppID-override.txt") {
98+
$ModsOverride = (Get-Content "$Mods\$AppID-override.txt" -Raw).Trim()
99+
}
100+
if (Test-Path "$Mods\$AppID-custom.txt") {
101+
$ModsCustom = (Get-Content "$Mods\$AppID-custom.txt" -Raw).Trim()
102+
}
103+
if (Test-Path "$Mods\$AppID-install.ps1") {
104+
$ModsInstall = "$Mods\$AppID-install.ps1"
105+
}
106+
if (Test-Path "$Mods\$AppID-installed.ps1") {
107+
$ModsInstalled = "$Mods\$AppID-installed.ps1"
108+
}
118109
}
119110

120-
return $ModsPreInstall, $ModsInstall, $ModsInstalledOnce, $ModsInstalled
111+
return $ModsPreInstall, $ModsOverride, $ModsCustom, $ModsInstall, $ModsInstalled
121112
}
122113

123114
#Check if uninstall modifications exist in "mods" directory
124115
function Test-ModsUninstall ($AppID) {
125-
#Check current location
126-
if (Test-Path ".\mods\$AppID-preuninstall.ps1") {
127-
$ModsPreUninstall = ".\mods\$AppID-preuninstall.ps1"
128-
}
129-
#Else, check in WAU mods
130-
elseif (Test-Path "$WAUModsLocation\$AppID-preuninstall.ps1") {
131-
$ModsPreUninstall = "$WAUModsLocation\$AppID-preuninstall.ps1"
132-
}
133-
134-
if (Test-Path ".\mods\$AppID-uninstall.ps1") {
135-
$ModsUninstall = ".\mods\$AppID-uninstall.ps1"
136-
}
137-
elseif (Test-Path "$WAUModsLocation\$AppID-uninstall.ps1") {
138-
$ModsUninstall = "$WAUModsLocation\$AppID-uninstall.ps1"
139-
}
140-
141-
if (Test-Path ".\mods\$AppID-uninstalled.ps1") {
142-
$ModsUninstalled = ".\mods\$AppID-uninstalled.ps1"
143-
}
144-
elseif (Test-Path "$WAUModsLocation\$AppID-uninstalled.ps1") {
145-
$ModsUninstalled = "$WAUModsLocation\$AppID-uninstalled.ps1"
116+
if (Test-Path "$Mods\$AppID-*") {
117+
if (Test-Path "$Mods\$AppID-preuninstall.ps1") {
118+
$ModsPreUninstall = "$Mods\$AppID-preuninstall.ps1"
119+
}
120+
if (Test-Path "$Mods\$AppID-uninstall.ps1") {
121+
$ModsUninstall = "$Mods\$AppID-uninstall.ps1"
122+
}
123+
if (Test-Path "$Mods\$AppID-uninstalled.ps1") {
124+
$ModsUninstalled = "$Mods\$AppID-uninstalled.ps1"
125+
}
146126
}
147127

148128
return $ModsPreUninstall, $ModsUninstall, $ModsUninstalled
@@ -152,23 +132,38 @@ function Test-ModsUninstall ($AppID) {
152132
function Install-App ($AppID, $AppArgs) {
153133
$IsInstalled = Confirm-Installation $AppID
154134
if (!($IsInstalled) -or $AllowUpgrade ) {
155-
#Check if mods exist (or already exist) for preinstall/install/installedonce/installed
156-
$ModsPreInstall, $ModsInstall, $ModsInstalledOnce, $ModsInstalled = Test-ModsInstall $($AppID)
135+
#Check if mods exist (or already exist) for preinstall/override/custom/install/installed
136+
$ModsPreInstall, $ModsOverride, $ModsCustom, $ModsInstall, $ModsInstalled = Test-ModsInstall $($AppID)
157137

158138
#If PreInstall script exist
159139
if ($ModsPreInstall) {
160-
Write-ToLog "-> Modifications for $AppID before install are being applied..." "Yellow"
161-
& "$ModsPreInstall"
140+
Write-ToLog "Modifications for $AppID before install are being applied..." "DarkYellow"
141+
$preInstallResult = & "$ModsPreInstall"
142+
if ($preInstallResult -eq $false) {
143+
Write-ToLog "PreInstall script for $AppID requested to skip this installation" "Yellow"
144+
return # Exit the function early
145+
}
162146
}
163147

164148
#Install App
165-
Write-ToLog "-> Installing $AppID..." "Yellow"
166-
$WingetArgs = "install --id $AppID -e --accept-package-agreements --accept-source-agreements -s winget -h $AppArgs" -split " "
149+
Write-ToLog "-> Installing $AppID..." "DarkYellow"
150+
if ($ModsOverride) {
151+
Write-ToLog "-> Arguments (overriding default): $ModsOverride" # Without -h (user overrides default)
152+
$WingetArgs = "install --id $AppID -e --accept-package-agreements --accept-source-agreements -s winget --override $ModsOverride" -split " "
153+
}
154+
elseif ($ModsCustom) {
155+
Write-ToLog "-> Arguments (customizing default): $ModsCustom" # With -h (user customizes default)
156+
$WingetArgs = "install --id $AppID -e --accept-package-agreements --accept-source-agreements -s winget -h --custom $ModsCustom" -split " "
157+
}
158+
else {
159+
$WingetArgs = "install --id $AppID -e --accept-package-agreements --accept-source-agreements -s winget -h $AppArgs" -split " "
160+
}
161+
167162
Write-ToLog "-> Running: `"$Winget`" $WingetArgs"
168-
& "$Winget" $WingetArgs | Where-Object { $_ -notlike " *" } | Tee-Object -file $LogFile -Append
163+
& "$Winget" $WingetArgs | Where-Object { $_ -notlike " *" } | Tee-Object -file $LogFile -Append
169164

170165
if ($ModsInstall) {
171-
Write-ToLog "-> Modifications for $AppID during install are being applied..." "Yellow"
166+
Write-ToLog "-> Modifications for $AppID during install are being applied..." "DarkYellow"
172167
& "$ModsInstall"
173168
}
174169

@@ -177,26 +172,11 @@ function Install-App ($AppID, $AppArgs) {
177172
if ($IsInstalled) {
178173
Write-ToLog "-> $AppID successfully installed." "Green"
179174

180-
if ($ModsInstalledOnce) {
181-
Write-ToLog "-> Modifications for $AppID after install (one time) are being applied..." "Yellow"
182-
& "$ModsInstalledOnce"
183-
}
184-
elseif ($ModsInstalled) {
185-
Write-ToLog "-> Modifications for $AppID after install are being applied..." "Yellow"
175+
if ($ModsInstalled) {
176+
Write-ToLog "-> Modifications for $AppID after install are being applied..." "DarkYellow"
186177
& "$ModsInstalled"
187178
}
188179

189-
#Add mods if deployed from Winget-Install
190-
if (Test-Path ".\mods\$AppID-*") {
191-
#Check if WAU default install path exists
192-
$Mods = "$WAUModsLocation"
193-
if (Test-Path $Mods) {
194-
#Add mods
195-
Write-ToLog "-> Add modifications for $AppID to WAU 'mods'"
196-
Copy-Item ".\mods\$AppID-*" -Destination "$Mods" -Exclude "*installed-once*", "*uninstall*" -Force
197-
}
198-
}
199-
200180
#Add to WAU White List if set
201181
if ($WAUWhiteList) {
202182
Add-WAUWhiteList $AppID
@@ -220,18 +200,22 @@ function Uninstall-App ($AppID, $AppArgs) {
220200

221201
#If PreUninstall script exist
222202
if ($ModsPreUninstall) {
223-
Write-ToLog "-> Modifications for $AppID before uninstall are being applied..." "Yellow"
224-
& "$ModsPreUninstall"
203+
Write-ToLog "Modifications for $AppID before uninstall are being applied..." "DarkYellow"
204+
$preUnInstallResult = & "$ModsPreUnInstall"
205+
if ($preUnInstallResult -eq $false) {
206+
Write-ToLog "PreUnInstall script for $AppID requested to skip this uninstallation" "Yellow"
207+
return # Exit the function early
208+
}
225209
}
226210

227211
#Uninstall App
228-
Write-ToLog "-> Uninstalling $AppID..." "Yellow"
212+
Write-ToLog "-> Uninstalling $AppID..." "DarkYellow"
229213
$WingetArgs = "uninstall --id $AppID -e --accept-source-agreements -h $AppArgs" -split " "
230214
Write-ToLog "-> Running: `"$Winget`" $WingetArgs"
231-
& "$Winget" $WingetArgs | Where-Object { $_ -notlike " *" } | Tee-Object -file $LogFile -Append
215+
& "$Winget" $WingetArgs | Where-Object { $_ -notlike " *" } | Tee-Object -file $LogFile -Append
232216

233217
if ($ModsUninstall) {
234-
Write-ToLog "-> Modifications for $AppID during uninstall are being applied..." "Yellow"
218+
Write-ToLog "-> Modifications for $AppID during uninstall are being applied..." "DarkYellow"
235219
& "$ModsUninstall"
236220
}
237221

@@ -240,21 +224,10 @@ function Uninstall-App ($AppID, $AppArgs) {
240224
if (!($IsInstalled)) {
241225
Write-ToLog "-> $AppID successfully uninstalled." "Green"
242226
if ($ModsUninstalled) {
243-
Write-ToLog "-> Modifications for $AppID after uninstall are being applied..." "Yellow"
227+
Write-ToLog "-> Modifications for $AppID after uninstall are being applied..." "DarkYellow"
244228
& "$ModsUninstalled"
245229
}
246230

247-
#Remove mods if deployed from Winget-Install
248-
if (Test-Path ".\mods\$AppID-*") {
249-
#Check if WAU default install path exists
250-
$Mods = "$WAUModsLocation"
251-
if (Test-Path "$Mods\$AppID*") {
252-
Write-ToLog "-> Remove $AppID modifications from WAU 'mods'"
253-
#Remove mods
254-
Remove-Item -Path "$Mods\$AppID-*" -Exclude "*uninstall*" -Force
255-
}
256-
}
257-
258231
#Remove from WAU White List if set
259232
if ($WAUWhiteList) {
260233
Remove-WAUWhiteList $AppID
@@ -321,7 +294,8 @@ $Script:IsElevated = $CurrentPrincipal.IsInRole([Security.Principal.WindowsBuilt
321294
#Get WAU Installed location
322295
$WAURegKey = "HKLM:\SOFTWARE\Romanitho\Winget-AutoUpdate\"
323296
$Script:WAUInstallLocation = Get-ItemProperty $WAURegKey -ErrorAction SilentlyContinue | Select-Object -ExpandProperty InstallLocation
324-
$Script:WAUModsLocation = Join-Path -Path $WAUInstallLocation -ChildPath "mods"
297+
# Use the Working Dir (even if it is from a symlink)
298+
$Mods = "$realPath\mods"
325299

326300
#Log file & LogPath initialization
327301
if ($IsElevated) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#Change app to detect [Application ID]
2+
$AppToDetect = "Notepad++.Notepad++"
3+
4+
5+
<# FUNCTIONS #>
6+
7+
Function Get-WingetCmd {
8+
9+
$WingetCmd = $null
10+
11+
#Get WinGet Path
12+
try {
13+
#Get Admin Context Winget Location
14+
$WingetInfo = (Get-Item "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_8wekyb3d8bbwe\winget.exe").VersionInfo | Sort-Object -Property FileVersionRaw
15+
#If multiple versions, pick most recent one
16+
$WingetCmd = $WingetInfo[-1].FileName
17+
}
18+
catch {
19+
#Get User context Winget Location
20+
if (Test-Path "$env:LocalAppData\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe") {
21+
$WingetCmd = "$env:LocalAppData\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
22+
}
23+
}
24+
25+
return $WingetCmd
26+
}
27+
28+
<# MAIN #>
29+
30+
#Get WinGet Location Function
31+
$winget = Get-WingetCmd
32+
33+
#Set json export file
34+
$JsonFile = "$env:TEMP\InstalledApps.json"
35+
36+
#Get installed apps and version in json file
37+
& $Winget export -o $JsonFile --accept-source-agreements | Out-Null
38+
39+
#Get json content
40+
$Json = Get-Content $JsonFile -Raw | ConvertFrom-Json
41+
42+
#Get apps and version in hashtable
43+
$Packages = $Json.Sources.Packages
44+
45+
#Remove json file
46+
Remove-Item $JsonFile -Force
47+
48+
# Search for specific app and version
49+
$Apps = $Packages | Where-Object { $_.PackageIdentifier -eq $AppToDetect }
50+
51+
if ($Apps) {
52+
return "Installed!"
53+
}

0 commit comments

Comments
 (0)