@@ -76,156 +76,6 @@ param(
7676 [switch ]$DryRun
7777)
7878
79- function Remove-WingetApps {
80- param ([string []]$AppPatterns )
81-
82- Write-Log " Starting winget app removal..." - Component ' REMOVAL'
83-
84- foreach ($pattern in $AppPatterns ) {
85- Write-Log " Searching for apps matching: $pattern " - Component ' REMOVAL'
86-
87- try {
88- if ($DryRun ) {
89- Write-Log " DryRun: Would search and remove apps matching '$pattern '" - Level ' INFO' - Component ' REMOVAL'
90- $Script :ActionsSummary.AppsRemoved += " DryRun-$pattern "
91- continue
92- }
93-
94- # Use enhanced app search
95- $foundApps = Get-WingetAppByPattern - Pattern $pattern
96-
97- if ($foundApps -and $foundApps.Count -gt 0 ) {
98- Write-Log " Found $ ( $foundApps.Count ) app(s) matching '$pattern '" - Component ' REMOVAL'
99-
100- foreach ($app in $foundApps ) {
101- if ($app -is [string ]) {
102- $appName = $app
103- $uninstallCmd = " winget uninstall --name `" $pattern `" --silent --force --accept-source-agreements"
104- } else {
105- $appName = $app.Name
106- $uninstallCmd = " winget uninstall --id `" $ ( $app.Id ) `" --silent --force --accept-source-agreements"
107- }
108-
109- Write-Log " Attempting to uninstall: $appName " - Component ' REMOVAL'
110- $result = Invoke-WingetCommand - Command $uninstallCmd - AppName $appName
111-
112- if ($result ) {
113- Write-Log " Successfully removed: $appName " - Component ' REMOVAL'
114- $Script :ActionsSummary.AppsRemoved += $appName
115- } else {
116- Write-Log " Failed to remove: $appName " - Level ' WARN' - Component ' REMOVAL' - ErrorCode 3001
117- }
118- }
119- } else {
120- Write-Log " No apps found matching: $pattern " - Component ' REMOVAL'
121- }
122- }
123- catch {
124- Write-Log " Error processing $pattern `: $ ( $_.Exception.Message ) " - Level ' ERROR' - Component ' REMOVAL' - ErrorCode 3000
125- }
126- }
127- }
128-
129- function Remove-AppxPackagesAllUsers {
130- Write-Log " Removing UWP/Appx packages for all users..." - Component ' APPX'
131-
132- $packagesToRemove = @ (
133- ' *Microsoft.OutlookForWindows*' ,
134- ' *Clipchamp*' ,
135- ' *MicrosoftFamily*' ,
136- ' *OneDrive*' ,
137- ' *LinkedIn*' ,
138- ' *Xbox*' ,
139- ' *Skype*' ,
140- ' *MixedReality*' ,
141- ' *RemoteDesktop*' ,
142- ' *QuickAssist*' ,
143- ' *MicrosoftTeams*' ,
144- ' *Disney*' ,
145- ' *Netflix*' ,
146- ' *Spotify*' ,
147- ' *TikTok*' ,
148- ' *Instagram*' ,
149- ' *Facebook*' ,
150- ' *Candy*' ,
151- ' *Twitter*' ,
152- ' *Minecraft*'
153- )
154-
155- foreach ($packagePattern in $packagesToRemove ) {
156- Write-Log " Processing Appx package: $packagePattern " - Component ' APPX'
157-
158- if ($DryRun ) {
159- Write-Log " DryRun: Would remove Appx package pattern '$packagePattern '" - Level ' INFO' - Component ' APPX'
160- $Script :ActionsSummary.PackagesRemoved += " DryRun-$packagePattern "
161- continue
162- }
163-
164- try {
165- # Remove for all users (current and future)
166- $packages = Get-AppxPackage - AllUsers - Name $packagePattern - ErrorAction SilentlyContinue
167- foreach ($package in $packages ) {
168- Write-Log " Removing package for all users: $ ( $package.Name ) " - Component ' APPX'
169- Remove-AppxPackage - Package $package.PackageFullName - AllUsers - ErrorAction SilentlyContinue
170- $Script :ActionsSummary.PackagesRemoved += $package.Name
171- }
172-
173- # Remove provisioned packages (affects new user accounts)
174- $provisionedPackages = Get-AppxProvisionedPackage - Online - ErrorAction SilentlyContinue |
175- Where-Object { $_.DisplayName -like $packagePattern }
176-
177- foreach ($package in $provisionedPackages ) {
178- Write-Log " Removing provisioned package: $ ( $package.DisplayName ) " - Component ' APPX'
179- Remove-AppxProvisionedPackage - Online - PackageName $package.PackageName - ErrorAction SilentlyContinue
180- $Script :ActionsSummary.PackagesRemoved += $package.DisplayName
181- }
182- }
183- catch {
184- Write-Log " Error removing $packagePattern `: $ ( $_.Exception.Message ) " - Level ' WARN' - Component ' APPX' - ErrorCode 3002
185- }
186- }
187- }
188-
189- # ================================
190- # Enhanced Application Installation with Parallel Processing
191- # ================================
192-
193- function Install-StandardApps {
194- Write-Log " Installing standard applications..." - Component ' INSTALL'
195-
196- $appsToInstall = @ (
197- @ { Id = ' Malwarebytes.Malwarebytes' ; Name = ' Malwarebytes' },
198- @ { Id = ' BleachBit.BleachBit' ; Name = ' BleachBit' },
199- @ { Id = ' Google.Chrome' ; Name = ' Google Chrome' },
200- @ { Id = ' Microsoft.DotNet.DesktopRuntime.7' ; Name = ' .NET 7 Desktop Runtime' },
201- @ { Id = ' Adobe.Acrobat.Reader.64-bit' ; Name = ' Adobe Reader' },
202- @ { Id = ' Zoom.Zoom' ; Name = ' Zoom' },
203- @ { Id = ' 7zip.7zip' ; Name = ' 7-Zip' },
204- @ { Id = ' VideoLAN.VLC' ; Name = ' VLC Media Player' }
205- )
206-
207- # Add Java runtimes if not skipped
208- if (-not $SkipJavaRuntimes ) {
209- $appsToInstall += @ { Id = ' Oracle.JavaRuntimeEnvironment' ; Name = ' Java Runtime Environment' }
210- } else {
211- Write-Log " Skipping Java runtime installation (SkipJavaRuntimes flag set)" - Component ' INSTALL'
212- }
213-
214- if ($DryRun ) {
215- Write-Log " DryRun: Would install $ ( $appsToInstall.Count ) applications" - Level ' INFO' - Component ' INSTALL'
216- foreach ($app in $appsToInstall ) {
217- $Script :ActionsSummary.AppsInstalled += " DryRun-$ ( $app.Name ) "
218- }
219- return $appsToInstall.Count
220- }
221-
222- # Use parallel installation for better performance
223- $successCount = Invoke-ParallelWingetInstall - AppList $appsToInstall - MaxConcurrentJobs 3
224-
225- Write-Log " App installation complete: $successCount /$ ( $appsToInstall.Count ) successful" - Component ' INSTALL'
226- return $successCount
227- }
228-
22979# ================================
23080# Telemetry and Summary Functions
23181# ================================
@@ -1103,12 +953,12 @@ function Remove-WingetApps {
1103953 Write-Log " Error processing $pattern `: $ ( $_.Exception.Message ) " - Level ' ERROR' - Component ' REMOVAL' - ErrorCode 3000
1104954 }
1105955 }
1106-
956+
1107957 Write-Log " Winget app removal completed" - Component ' REMOVAL'
1108958}
1109959
1110960function Remove-AppxPackagesAllUsers {
1111- Write-Log " Removing UWP/Appx packages for all users..."
961+ Write-Log " Removing UWP/Appx packages for all users..." - Component ' APPX '
1112962
1113963 $packagesToRemove = @ (
1114964 ' *Microsoft.OutlookForWindows*' ,
@@ -1134,32 +984,35 @@ function Remove-AppxPackagesAllUsers {
1134984 )
1135985
1136986 foreach ($packagePattern in $packagesToRemove ) {
1137- Write-Log " Processing Appx package: $packagePattern "
987+ Write-Log " Processing Appx package: $packagePattern " - Component ' APPX '
1138988
1139989 if ($DryRun ) {
1140- Write-Log " DryRun: Would remove Appx package pattern '$packagePattern '" - Level ' INFO'
990+ Write-Log " DryRun: Would remove Appx package pattern '$packagePattern '" - Level ' INFO' - Component ' APPX'
991+ $Script :ActionsSummary.PackagesRemoved += " DryRun-$packagePattern "
1141992 continue
1142993 }
1143994
1144995 try {
1145996 # Remove for all users (current and future)
1146997 $packages = Get-AppxPackage - AllUsers - Name $packagePattern - ErrorAction SilentlyContinue
1147998 foreach ($package in $packages ) {
1148- Write-Log " Removing package for all users: $ ( $package.Name ) "
999+ Write-Log " Removing package for all users: $ ( $package.Name ) " - Component ' APPX '
11491000 Remove-AppxPackage - Package $package.PackageFullName - AllUsers - ErrorAction SilentlyContinue
1001+ $Script :ActionsSummary.PackagesRemoved += $package.Name
11501002 }
11511003
11521004 # Remove provisioned packages (affects new user accounts)
11531005 $provisionedPackages = Get-AppxProvisionedPackage - Online - ErrorAction SilentlyContinue |
11541006 Where-Object { $_.DisplayName -like $packagePattern }
11551007
11561008 foreach ($package in $provisionedPackages ) {
1157- Write-Log " Removing provisioned package: $ ( $package.DisplayName ) "
1009+ Write-Log " Removing provisioned package: $ ( $package.DisplayName ) " - Component ' APPX '
11581010 Remove-AppxProvisionedPackage - Online - PackageName $package.PackageName - ErrorAction SilentlyContinue
1011+ $Script :ActionsSummary.PackagesRemoved += $package.DisplayName
11591012 }
11601013 }
11611014 catch {
1162- Write-Log " Error removing $packagePattern `: $ ( $_.Exception.Message ) " - Level ' WARN'
1015+ Write-Log " Error removing $packagePattern `: $ ( $_.Exception.Message ) " - Level ' WARN' - Component ' APPX ' - ErrorCode 3002
11631016 }
11641017 }
11651018}
@@ -1284,53 +1137,100 @@ function Remove-McAfeeProducts {
12841137}
12851138
12861139# ================================
1287- # Enhanced Application Installation
1140+ # Enhanced Application Installation with Parallel Processing
12881141# ================================
12891142
12901143function Install-StandardApps {
1291- Write-Log " Installing standard applications..."
1144+ param (
1145+ [int ]$MaxConcurrentJobs = 3
1146+ )
12921147
1293- $appsToInstall = @ (
1148+ Write-Log " Installing standard applications and runtime libraries..."
1149+
1150+ # Core applications
1151+ $coreApps = @ (
12941152 @ { Id = ' Malwarebytes.Malwarebytes' ; Name = ' Malwarebytes' },
12951153 @ { Id = ' BleachBit.BleachBit' ; Name = ' BleachBit' },
12961154 @ { Id = ' Google.Chrome' ; Name = ' Google Chrome' },
1297- @ { Id = ' Microsoft.DotNet.DesktopRuntime.7' ; Name = ' .NET 7 Desktop Runtime' },
12981155 @ { Id = ' Adobe.Acrobat.Reader.64-bit' ; Name = ' Adobe Reader' },
12991156 @ { Id = ' Zoom.Zoom' ; Name = ' Zoom' },
13001157 @ { Id = ' 7zip.7zip' ; Name = ' 7-Zip' },
13011158 @ { Id = ' VideoLAN.VLC' ; Name = ' VLC Media Player' }
13021159 )
13031160
1304- # Add Java runtimes if not skipped
1305- if (-not $SkipJavaRuntimes ) {
1306- $appsToInstall += @ { Id = ' Oracle.JavaRuntimeEnvironment' ; Name = ' Java Runtime Environment' }
1307- } else {
1308- Write-Log " Skipping Java runtime installation (SkipJavaRuntimes flag set)"
1309- }
1310-
1311- $successCount = 0
1312- $totalCount = $appsToInstall.Count
1161+ # .NET Framework and Desktop Runtimes
1162+ $dotnetApps = @ (
1163+ @ { Id = ' Microsoft.DotNet.Framework.4.8.1' ; Name = ' .NET Framework 4.8.1' },
1164+ @ { Id = ' Microsoft.DotNet.DesktopRuntime.8' ; Name = ' .NET Desktop Runtime 8' },
1165+ @ { Id = ' Microsoft.DotNet.DesktopRuntime.8' ; Name = ' .NET Desktop Runtime x64 8' }, # Same package for x64
1166+ @ { Id = ' Microsoft.DotNet.DesktopRuntime.9' ; Name = ' .NET Desktop Runtime 9' },
1167+ @ { Id = ' Microsoft.DotNet.DesktopRuntime.9' ; Name = ' .NET Desktop Runtime x64 9' } # Same package for x64
1168+ )
13131169
1314- foreach ($app in $appsToInstall ) {
1315- Write-Log " Installing: $ ( $app.Name ) ($ ( $app.Id ) )"
1170+ # Visual C++ Redistributables (All requested versions - x64 and x86 only)
1171+ $vcredistApps = @ (
1172+ # 2015+ (Latest - recommended)
1173+ @ { Id = ' Microsoft.VCRedist.2015+.x64' ; Name = ' VC Redist x64 2015+' },
1174+ @ { Id = ' Microsoft.VCRedist.2015+.x86' ; Name = ' VC Redist x86 2015+' },
13161175
1317- if ($DryRun ) {
1318- Write-Log " DryRun: Would install $ ( $app.Name ) " - Level ' INFO'
1319- $successCount ++
1320- continue
1321- }
1176+ # 2013
1177+ @ { Id = ' Microsoft.VCRedist.2013.x64' ; Name = ' VC Redist x64 2013' },
1178+ @ { Id = ' Microsoft.VCRedist.2013.x86' ; Name = ' VC Redist x86 2013' },
13221179
1323- $result = Invoke-WingetCommand - Command " winget install --id $ ( $app.Id ) --source winget --accept-package-agreements --accept-source-agreements --silent"
1180+ # 2012
1181+ @ { Id = ' Microsoft.VCRedist.2012.x64' ; Name = ' VC Redist x64 2012' },
1182+ @ { Id = ' Microsoft.VCRedist.2012.x86' ; Name = ' VC Redist x86 2012' },
13241183
1325- if ($result ) {
1326- Write-Log " Successfully installed: $ ( $app.Name ) "
1327- $successCount ++
1328- } else {
1329- Write-Log " Failed to install: $ ( $app.Name ) " - Level ' WARN'
1330- }
1331- }
1184+ # 2010
1185+ @ { Id = ' Microsoft.VCRedist.2010.x64' ; Name = ' VC Redist x64 2010' },
1186+ @ { Id = ' Microsoft.VCRedist.2010.x86' ; Name = ' VC Redist x86 2010' },
1187+
1188+ # 2008
1189+ @ { Id = ' Microsoft.VCRedist.2008.x64' ; Name = ' VC Redist x64 2008' },
1190+ @ { Id = ' Microsoft.VCRedist.2008.x86' ; Name = ' VC Redist x86 2008' },
1191+
1192+ # 2005
1193+ @ { Id = ' Microsoft.VCRedist.2005.x64' ; Name = ' VC Redist x64 2005' },
1194+ @ { Id = ' Microsoft.VCRedist.2005.x86' ; Name = ' VC Redist x86 2005' }
1195+ )
1196+
1197+ # Combine app lists based on parameters
1198+ $appsToInstall = $coreApps + $dotnetApps + $vcredistApps
1199+
1200+ # Add Java runtimes if not skipped
1201+ $javaApps = @ ()
1202+ if (-not $SkipJavaRuntimes ) {
1203+ $javaApps = @ (@ { Id = ' Oracle.JavaRuntimeEnvironment' ; Name = ' Java Runtime Environment' })
1204+ $appsToInstall += $javaApps
1205+ }
1206+
1207+ if ($DryRun ) {
1208+ Write-Log " DryRun: Would install $ ( $appsToInstall.Count ) applications" - Level ' INFO' - Component ' INSTALL'
1209+ foreach ($app in $appsToInstall ) {
1210+ $Script :ActionsSummary.AppsInstalled += " DryRun-$ ( $app.Name ) "
1211+ }
1212+ return $appsToInstall.Count
1213+ }
1214+
1215+ $totalCount = $appsToInstall.Count
1216+
1217+ Write-Log " Installing $totalCount applications and runtime libraries..."
1218+ Write-Log " Categories: Core Apps ($ ( $coreApps.Count ) ), .NET ($ ( $dotnetApps.Count ) ), VC++ Redist ($ ( $vcredistApps.Count ) ), Java Runtime ($ ( if (-not $SkipJavaRuntimes ) { 1 } else { 0 }) )"
1219+
1220+ $successCount = Invoke-ParallelWingetInstall - AppList $appsToInstall - MaxConcurrentJobs 3
13321221
13331222 Write-Log " App installation complete: $successCount /$totalCount successful"
1223+
1224+ # Log summary by category
1225+ Write-Log " Installation Summary:"
1226+ Write-Log " - Core Applications: $ ( $coreApps.Count ) packages"
1227+ Write-Log " - .NET Frameworks/Runtimes: $ ( $dotnetApps.Count ) packages"
1228+ Write-Log " - Visual C++ Redistributables: $ ( $vcredistApps.Count ) packages"
1229+ if (-not $SkipJavaRuntimes ) {
1230+ Write-Log " - Java Runtime: $ ( $javaApps.Count ) package(s)"
1231+ }
1232+
1233+ return ($successCount -ge ($totalCount * 0.8 )) # Consider successful if 80% or more installed
13341234}
13351235
13361236# ================================
0 commit comments