Skip to content

Commit 1e08114

Browse files
authored
Update DeployWorkstation-AllUsers.ps1
fixed duplicate sections, fixed package installation issues for Visual C++ and .Net applications, also fixed java installation and logging issues. Fully debugged and code verified by CoPilot 365
1 parent a969068 commit 1e08114

1 file changed

Lines changed: 85 additions & 185 deletions

File tree

DeployWorkstation-AllUsers.ps1

Lines changed: 85 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1110960
function 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

12901143
function 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

Comments
 (0)