Skip to content

Customizing the Post-setup.ps1 Script

The Post-setup.ps1 file is a PowerShell script that runs automatically on the first logon to the Desktop after Windows completes setup. EASYDEPLOY copies the script to C:\CoreSystem\Post-setup.ps1 on the system partition. Windows Setup invokes the script via FirstLogonCommands in unattend.xml.

This is the ideal environment to apply post-installation tweaks: system customization, automatic app installation, wallpaper setup, and temporary cleanup.

Windows first boot after installation
│
▼
Automatic Desktop logon (AutoLogon) (if configured)
│
▼
FirstLogonCommands invokes PowerShell with:
if (Test-Path C:\CoreSystem\Post-setup.ps1) { Unblock-File …; & … }
│
▼
Script starts running (with Administrator privileges)
│
▼
Script completes and reboots the device (Reboot) if required
Section titled “2. Recommended Script Structure (Standard Template)”

The built-in sample profile (1.Tweaks) is designed with an optimized logical structure. You can use it as a reference template:

Terminal window
# 0. Define display header and timeout configuration
Write-Host "=== [CoreSystem] POST-SETUP ===" -ForegroundColor Cyan
$GlobalTimeoutSec = 300
# 1. Declare Internet connectivity check function (retry up to 6 times, 5-second interval)
function Wait-ForInternet { … }
# 2. Check network — internet-dependent tasks only run when connected
$HasInternet = Wait-ForInternet
# 3. [Step X/7] Sync files/resources from Cloud (e.g., Notes.txt, etc.)
# 4. [Step X/7] Download and set wallpaper
# 5. [Step X/7] Automatically install applications (via WinGet or msi/exe installers)
# 6. [Step X/7] Clean up system resources (clear Event Logs, clean Panther/CoreSystem after reboot)
# 7. [Step X/7] Restore ExecutionPolicy to RemoteSigned

3.1. Internet Connectivity Check Loop (Required if the script needs to fetch network resources)

Section titled “3.1. Internet Connectivity Check Loop (Required if the script needs to fetch network resources)”
Terminal window
function Wait-ForInternet {
$retry = 0
while ($retry -lt 6) {
if (Test-Connection -ComputerName 8.8.8.8 -Count 1 -Quiet) { return $true }
Start-Sleep -Seconds 5
$retry++
}
return $false
}
$HasInternet = Wait-ForInternet

3.2. Download and Configure Wallpaper from URL

Section titled “3.2. Download and Configure Wallpaper from URL”
Terminal window
$Url = "https://coresystem.vn/osd/wallpaper.jpg"
$Dest = "C:\Windows\Web\Wallpaper\CoreSystem\wallpaper.jpg"
if ($HasInternet) {
New-Item -ItemType Directory -Path (Split-Path $Dest) -Force | Out-Null
Invoke-WebRequest -Uri $Url -OutFile $Dest -UseBasicParsing -TimeoutSec $GlobalTimeoutSec
# Apply wallpaper change via P/Invoke calling SystemParametersInfo from user32.dll
}

3.3. Automatic App Installation via Windows Package Manager (WinGet — available on Windows 11)

Section titled “3.3. Automatic App Installation via Windows Package Manager (WinGet — available on Windows 11)”
Terminal window
$apps = @("7zip.7zip", "Google.Chrome", "Microsoft.PowerToys")
foreach ($app in $apps) {
if ($HasInternet) {
winget install --id $app --accept-package-agreements --accept-source-agreements --silent
}
}

3.4. Clean Up System Logs and Automatically Remove Temporary Data

Section titled “3.4. Clean Up System Logs and Automatically Remove Temporary Data”
Terminal window
Get-EventLog -LogName * -ErrorAction SilentlyContinue |
ForEach-Object { Clear-EventLog -LogName $_.Log -ErrorAction SilentlyContinue }
# Remove Panther & CoreSystem directories on the next boot
$RunOnce = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
Set-ItemProperty $RunOnce -Name "CleanupPanther" -Value "cmd.exe /c rmdir /s /q C:\Windows\System32\Panther" -Force
Set-ItemProperty $RunOnce -Name "CleanupCoreSystem" -Value "cmd.exe /c rmdir /s /q C:\CoreSystem" -Force
Terminal window
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force

5. Operational and Deployment Recommendations

Section titled “5. Operational and Deployment Recommendations”
  • Quick customization: Any changes to Post-setup.ps1 on the USB do not require rebuilding the application. EASYDEPLOY reads directly from EASYDEPLOY\Profiles\<ProfileName>\. Overwrite the file and reboot to test.
  • Default profile: Changing the default profile (when the USB is empty) is managed by CoreSystem. IT/MSP partners only manage their own profiles on the USB (see Creating a New Profile).