Skip to content

Commit 5893be7

Browse files
authored
V0.5.4
## [0.5.4] - 2025-11-19 ### Added - Additional security hardening based on CISO recommendations. - Additional Winget exit codes to better understand installation results. ### Changed - Merged Autorun disable options into Harden-Windows.ps1 for better maintainability and understandability. ### Fixed - Improved handling of situations where the script was not run as admin and PowerShell 7 was not present on the system. - Implemented PSScriptAnalyzer suggestions to enhance code quality and best practices. - Improved GitHub API usage: Scripts now perform more attempts to obtain a good release. - Fixed an issue where the deployment tried to use the wrong command to silently update a Dell device driver. - Fixed an issue where the logs did not properly capture the output of Driver installs.
1 parent 9a7f1b9 commit 5893be7

File tree

15 files changed

+867
-228
lines changed

15 files changed

+867
-228
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
---
99

10+
## [0.5.4] - 2025-11-19
11+
12+
### Added
13+
- Additional security hardening based on CISO recommendations.
14+
- Additional Winget exit codes to better understand installation results.
15+
16+
### Changed
17+
- Merged Autorun disable options into Harden-Windows.ps1 for better maintainability and understandability.
18+
19+
### Fixed
20+
- Improved handling of situations where the script was not run as admin and PowerShell 7 was not present on the system.
21+
- Implemented PSScriptAnalyzer suggestions to enhance code quality and best practices.
22+
- Improved GitHub API usage: Scripts now perform more attempts to obtain a good release.
23+
- Fixed an issue where the deployment tried to use the wrong command to silently update a Dell device driver.
24+
- Fixed an issue where the logs did not properly capture the output of Driver installs.
25+
26+
---
27+
1028
## [0.5.3] - 2025-11-18
1129

1230
### Fixed
@@ -84,6 +102,7 @@ First open-source release of WinDeploy - Windows Deployment Automation Toolkit.
84102

85103
---
86104

105+
[0.5.4]: https://github.com/Stensel8/WinDeploy/releases/tag/v0.5.4
87106
[0.5.3]: https://github.com/Stensel8/WinDeploy/releases/tag/v0.5.3
88107
[0.5.2]: https://github.com/Stensel8/WinDeploy/releases/tag/v0.5.2
89108
[0.5.0]: https://github.com/Stensel8/WinDeploy/releases/tag/v0.5.0

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ graph TD
5959
G --> H[Launch Deploy.ps1]
6060
H --> I[Update Drivers]
6161
I --> J[Install RMM Agent]
62-
J --> K[Disable AutoRun]
62+
J --> K[Windows Hardening]
6363
K --> L[Install Applications]
6464
L --> M[Remove Bloatware]
6565
M --> N[Apply Theme]

Scripts/Archived/Fix-Spotlight.ps1

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Complete script to activate Windows Spotlight for Lock Screen and Desktop
2+
# Based on registry adjustments, package re-registration and policy resets
3+
# Run as Administrator; restart after execution for full effect
4+
5+
# Step 1: Remove blocking policies (CloudContent)
6+
Write-Host "Step 1: Removing blocking policies..." -ForegroundColor Green
7+
$policyPath = "HKCU:\Software\Policies\Microsoft\Windows\CloudContent"
8+
if (Test-Path $policyPath) {
9+
Remove-ItemProperty -Path $policyPath -Name "DisableSpotlightCollectionOnDesktop" -ErrorAction SilentlyContinue
10+
Remove-ItemProperty -Path $policyPath -Name "DisableWindowsSpotlightFeatures" -ErrorAction SilentlyContinue
11+
Remove-ItemProperty -Path $policyPath -Name "TurnOffAllWindowsSpotlightFeatures" -ErrorAction SilentlyContinue
12+
Remove-ItemProperty -Path $policyPath -Name "ConfigureWindowsSpotlightOnLockScreen" -ErrorAction SilentlyContinue
13+
Write-Host "Policies removed or reset." -ForegroundColor Yellow
14+
} else {
15+
Write-Host "No blocking policies found." -ForegroundColor Cyan
16+
}
17+
18+
# Step 2: Create DesktopSpotlight registry keys if they are missing
19+
Write-Host "Step 2: Creating DesktopSpotlight keys..." -ForegroundColor Green
20+
$desktopSpotlightPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\DesktopSpotlight"
21+
if (-not (Test-Path $desktopSpotlightPath)) {
22+
New-Item -Path $desktopSpotlightPath -Force | Out-Null
23+
Write-Host "DesktopSpotlight folder created." -ForegroundColor Yellow
24+
}
25+
$values = @("RegistrationStatusCheck", "Rotation", "State", "UpdateTask", "UpdateTimer", "WallpaperRefresh")
26+
foreach ($val in $values) {
27+
if (-not (Get-ItemProperty -Path $desktopSpotlightPath -Name $val -ErrorAction SilentlyContinue)) {
28+
New-ItemProperty -Path $desktopSpotlightPath -Name $val -PropertyType String -Value "" -Force | Out-Null
29+
Write-Host "Key '$val' created." -ForegroundColor Yellow
30+
}
31+
}
32+
33+
# Step 3: Reset and activate ContentDeliveryManager keys
34+
Write-Host "Step 3: Resetting ContentDeliveryManager..." -ForegroundColor Green
35+
$contentPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"
36+
Remove-ItemProperty -Path $contentPath -Name "NoSpotlight" -ErrorAction SilentlyContinue
37+
Remove-ItemProperty -Path $contentPath -Name "NoRotatingLockScreen" -ErrorAction SilentlyContinue
38+
Remove-ItemProperty -Path $contentPath -Name "RotatingLockScreenOverlayEnabled" -ErrorAction SilentlyContinue
39+
Remove-ItemProperty -Path $contentPath -Name "RotatingLockScreenOverlayContentEnabled" -ErrorAction SilentlyContinue
40+
# Activate
41+
Set-ItemProperty -Path $contentPath -Name "ContentDeliveryAllowed" -Value 1 -Type DWord -Force
42+
Set-ItemProperty -Path $contentPath -Name "RotatingLockScreenEnabled" -Value 1 -Type DWord -Force
43+
Set-ItemProperty -Path $contentPath -Name "RotatingLockScreenOverlayEnabled" -Value 1 -Type DWord -Force
44+
Set-ItemProperty -Path $contentPath -Name "RotatingLockScreenOverlayContentEnabled" -Value 1 -Type DWord -Force
45+
Set-ItemProperty -Path $contentPath -Name "SubscribedContent-338389Enabled" -Value 1 -Type DWord -Force # For desktop Spotlight
46+
Write-Host "ContentDeliveryManager activated." -ForegroundColor Yellow
47+
48+
# Step 4: Re-register Spotlight package (for lockscreen and desktop)
49+
Write-Host "Step 4: Re-registering Spotlight package..." -ForegroundColor Green
50+
Get-AppxPackage -allusers Microsoft.Windows.ContentDeliveryManager | ForEach-Object {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}
51+
Write-Host "Package registered." -ForegroundColor Yellow
52+
53+
# Step 5: Optional policy-check and reset (if DisableSpotlightFeatures exists, set to 0)
54+
Write-Host "Step 5: Extra policy-check..." -ForegroundColor Green
55+
if ((Get-ItemProperty -Path $policyPath -Name "DisableSpotlightFeatures" -ErrorAction SilentlyContinue)) {
56+
Set-ItemProperty -Path $policyPath -Name "DisableSpotlightFeatures" -Value 0 -Type DWord -Force
57+
Write-Host "DisableSpotlightFeatures disabled." -ForegroundColor Yellow
58+
}
59+
60+
# Step 6: Restart Explorer to apply changes
61+
Write-Host "Step 6: Restarting Explorer..." -ForegroundColor Green
62+
Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue
63+
Start-Sleep -Seconds 2
64+
Write-Host "Script completed! Log out/in or restart for full effect. Check Settings > Personalization > Background." -ForegroundColor Green

Scripts/Archived/Get-IntuneHash.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,4 @@ try {
9494
} catch {
9595
Write-Error "Failed to collect hardware hash: $($_.Exception.Message)"
9696
exit 1
97-
}
97+
}

Scripts/Deploy.ps1

Lines changed: 123 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,58 @@
11
Set-StrictMode -Version Latest
22
$ErrorActionPreference = 'Continue'
33

4-
# Fetch the latest release tag for downloading scripts
5-
$releaseTag = "main"
6-
try {
7-
$latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/Stensel8/WinDeploy/releases/latest" -ErrorAction SilentlyContinue
8-
if ($latestRelease.tag_name) {
9-
$releaseTag = $latestRelease.tag_name
4+
# Fetch latest release with retry logic
5+
function Get-LatestRelease {
6+
param(
7+
[int]$MaxRetries = 3,
8+
[int]$RetryDelay = 5
9+
)
10+
11+
for ($attempt = 1; $attempt -le $MaxRetries; $attempt++) {
12+
try {
13+
$latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/Stensel8/WinDeploy/releases/latest" -ErrorAction Stop
14+
if ($latestRelease.tag_name) {
15+
return $latestRelease.tag_name
16+
}
17+
} catch {
18+
$errorMsg = $_.Exception.Message
19+
Write-Warning "Failed to fetch latest release (attempt $attempt/$MaxRetries): $errorMsg"
20+
21+
if ($attempt -lt $MaxRetries) {
22+
if ($errorMsg -match "403|401") {
23+
Write-Host "Possible issue: GitHub API rate limit or authentication required" -ForegroundColor Yellow
24+
} elseif ($errorMsg -match "404") {
25+
Write-Host "Possible issue: No releases found in repository" -ForegroundColor Yellow
26+
}
27+
Write-Host "Waiting $RetryDelay seconds before retry..." -ForegroundColor Cyan
28+
Start-Sleep -Seconds $RetryDelay
29+
}
30+
}
1031
}
11-
} catch {
12-
Write-Warning "Failed to fetch latest release, using main branch."
32+
return $null
33+
}
34+
35+
# Fetch the latest release tag - REQUIRED for deployment
36+
$releaseTag = Get-LatestRelease
37+
if (!$releaseTag) {
38+
Write-Output "ERROR: Failed to fetch latest release from GitHub."
39+
Write-Output "Releases are required for deployment. Development branches are not used."
40+
Write-Output "Please check:"
41+
Write-Output " 1. Your internet connection"
42+
Write-Output " 2. GitHub API accessibility"
43+
Write-Output " 3. Repository has published releases: github.com/Stensel8/WinDeploy/releases"
44+
Read-Host "Press Enter to exit"
45+
exit 1
1346
}
1447

1548
# Read version
1649
$version = $null
1750
try {
1851
$version = Invoke-RestMethod -Uri "https://raw.githubusercontent.com/Stensel8/WinDeploy/$releaseTag/VERSION" -ErrorAction SilentlyContinue
1952
$version = $version.Trim()
53+
if ($version) {
54+
Write-Output "Version: $version"
55+
}
2056
} catch {
2157
Write-Warning "Failed to fetch version information."
2258
}
@@ -65,11 +101,61 @@ if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdenti
65101
exit 1
66102
}
67103

104+
# Log execution context for debugging
105+
$scriptExecutionContext = Get-ScriptDisplay
106+
Write-DeployLog "Deployment started. Execution context: $scriptExecutionContext"
107+
108+
# Helper function to download scripts with retry logic
109+
function Get-DeploymentScript {
110+
param(
111+
[string]$ScriptName,
112+
[string]$LocalPath,
113+
[int]$MaxRetries = 3,
114+
[int]$RetryDelay = 5
115+
)
116+
117+
for ($attempt = 1; $attempt -le $MaxRetries; $attempt++) {
118+
try {
119+
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Stensel8/WinDeploy/$releaseTag/Scripts/Deployment/$ScriptName" -OutFile $LocalPath -UseBasicParsing -ErrorAction Stop
120+
Write-DeployLog "Downloaded $ScriptName to $LocalPath"
121+
return $true
122+
} catch {
123+
$errorMsg = $_.Exception.Message
124+
Write-Warning "Download attempt $attempt/$MaxRetries failed for $ScriptName`: $errorMsg"
125+
126+
if ($attempt -lt $MaxRetries) {
127+
# Diagnose the issue
128+
if ($errorMsg -match "403|401") {
129+
Write-Host "Possible issue: GitHub API rate limit reached" -ForegroundColor Yellow
130+
} elseif ($errorMsg -match "404") {
131+
Write-Host "Possible issue: $ScriptName not found in release $releaseTag" -ForegroundColor Yellow
132+
} elseif ($errorMsg -match "timeout|timed out") {
133+
Write-Host "Possible issue: Network timeout" -ForegroundColor Yellow
134+
}
135+
136+
Write-Host "Waiting $RetryDelay seconds before retry..." -ForegroundColor Cyan
137+
Start-Sleep -Seconds $RetryDelay
138+
}
139+
}
140+
}
141+
142+
# If all download attempts failed, try local copy
143+
$localSourcePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath "Deployment") -ChildPath $ScriptName
144+
if (Test-Path $localSourcePath) {
145+
Copy-Item $localSourcePath $LocalPath -Force
146+
Write-DeployLog "Copied local $ScriptName to $LocalPath"
147+
return $true
148+
}
149+
150+
Write-Warning "Cannot download or find $ScriptName after $MaxRetries attempts"
151+
return $false
152+
}
153+
68154
# Define deployment steps (customize as needed)
69155
$deploymentSteps = @(
70156
@{ Name = "Driver Installation"; ScriptName = "Install-Drivers.ps1" }
71157
@{ Name = "RMM Agent Installation"; ScriptName = "Install-RMMAgent.ps1" }
72-
@{ Name = "AutoRun Disable"; ScriptName = "Disable-AutoRun.ps1" }
158+
@{ Name = "Windows Hardening"; ScriptName = "Harden-Windows.ps1" }
73159
@{ Name = "Application Installation"; ScriptName = "Install-Applications.ps1" }
74160
@{ Name = "Bloatware Removal"; ScriptName = "Remove-Bloat.ps1" }
75161
@{ Name = "Theme Configuration"; ScriptName = "Set-Theme.ps1" }
@@ -88,39 +174,46 @@ foreach ($step in $deploymentSteps) {
88174
Write-Output " $($step.Name)"
89175
Write-Output "======================================== "
90176
Write-Output ""
177+
91178
$localPath = Join-Path -Path $dlRoot -ChildPath $step.ScriptName
92-
$scriptAvailable = $false
93-
try {
94-
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Stensel8/WinDeploy/$releaseTag/Scripts/Deployment/$($step.ScriptName)" -OutFile $localPath -UseBasicParsing -ErrorAction Stop
95-
Write-DeployLog "Downloaded $($step.ScriptName) to $localPath"
96-
$scriptAvailable = $true
97-
} catch {
98-
# If download fails, use local copy if available
99-
$localSourcePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath "Deployment") -ChildPath $step.ScriptName
100-
if (Test-Path $localSourcePath) {
101-
Copy-Item $localSourcePath $localPath -Force
102-
Write-DeployLog "Copied local $($step.ScriptName) to $localPath"
103-
$scriptAvailable = $true
104-
} else {
105-
Write-Warning "Cannot download or find $($step.ScriptName): $_"
106-
$allSuccessful = $false
107-
continue
108-
}
109-
}
179+
180+
# Download script with retry logic
181+
$scriptAvailable = Get-DeploymentScript -ScriptName $step.ScriptName -LocalPath $localPath
182+
110183
if ($scriptAvailable) {
111184
$argumentList = "-ExecutionPolicy Bypass -File `"$localPath`""
112185
$proc = Start-Process pwsh -ArgumentList $argumentList -Wait -NoNewWindow -PassThru
113186
if ($proc.ExitCode -ne 0) {
187+
Write-Warning "$($step.Name) completed with errors (Exit Code: $($proc.ExitCode))"
114188
$allSuccessful = $false
115189
}
190+
} else {
191+
Write-Warning "Skipping $($step.Name) - script unavailable"
192+
$allSuccessful = $false
116193
}
117194
}
118195

119-
# Download optional fix Spotlight script. Sometimes Spotlight option is not present and needs a little help.
196+
# Download optional fix Spotlight script with retry
197+
Write-Output ""
198+
Write-Output "Downloading optional scripts..."
120199
try {
121200
$fixScriptPath = Join-Path $dlRoot "Fix-Spotlight.ps1"
122-
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Stensel8/WinDeploy/$releaseTag/Scripts/Archived/Fix-Spotlight.ps1" -OutFile $fixScriptPath -UseBasicParsing -ErrorAction Stop
123-
Write-DeployLog "Downloaded Fix-Spotlight.ps1 to $fixScriptPath as an optional script to fix missing Spotlight options on the system."
201+
$downloaded = $false
202+
for ($attempt = 1; $attempt -le 3; $attempt++) {
203+
try {
204+
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Stensel8/WinDeploy/$releaseTag/Scripts/Archived/Fix-Spotlight.ps1" -OutFile $fixScriptPath -UseBasicParsing -ErrorAction Stop
205+
Write-DeployLog "Downloaded Fix-Spotlight.ps1 to $fixScriptPath as an optional script to fix missing Spotlight options on the system."
206+
$downloaded = $true
207+
break
208+
} catch {
209+
if ($attempt -lt 3) {
210+
Start-Sleep -Seconds 5
211+
}
212+
}
213+
}
214+
if (-not $downloaded) {
215+
Write-DeployLog "Optional: Could not download Fix-Spotlight.ps1 after 3 attempts"
216+
}
124217
} catch {
125218
Write-DeployLog "Optional: Could not download Fix-Spotlight.ps1: $_"
126219
}

0 commit comments

Comments
 (0)