# List of apps installable from Microsoft Store using Winget
$storeApps = @(
"Microsoft.PowerToys", # PowerToys utilities
"Python.Python.3.12", # Python 3.12
"OpenAI.ChatGPT", # ChatGPT (official)
"Microsoft.3DViewer", # 3D Viewer
"Notion.Notion", # Notion app
"Microsoft.ScreenSketch" # Snipping Tool / Snip & Sketch
)
# Install each Microsoft Store app silently
foreach ($app in $storeApps) {
winget install --id $app --source msstore --silent --accept-source-agreements --accept-package-agreements
}
# Manual download apps (non-Store installers)
Write-Host "`nPlease download and install these manually:"
$webApps = @(
"🧭 Google Chrome: https://www.google.com/chrome/",
"🔁 Bulk Rename Utility: https://www.bulkrenameutility.co.uk/",
"🎞 HandBrake (Video Compressor): https://handbrake.fr/",
"📦 Microsoft Office: https://www.office.com/",
"🎧 Discord: https://discord.com/",
"📝 Obsidian (Markdown Notes): https://obsidian.md/",
"💬 WhatsApp Desktop: https://www.whatsapp.com/download",
"🐙 Git (Command Line): https://git-scm.com/downloads",
"📄 Foxit PDF Reader: https://www.foxit.com/pdf-reader/",
"🔧 SourceTree (Git GUI): https://www.sourcetreeapp.com/",
"☁️ Google Drive Desktop: https://www.google.com/drive/download/"
)
$webApps | ForEach-Object { Write-Host "👉 $_" }# --- Secure Setup Script ---
Write-Host "Starting secure setup...`n" -ForegroundColor Cyan
# Check if winget is available
if (-not (Get-Command winget.exe -ErrorAction SilentlyContinue)) {
Write-Error "❌ Winget not found. Please install 'App Installer' from Microsoft Store."
exit 1
}
# Function to check if app is already installed and get info
function Get-AppInfo($name) {
$info = @{
Name = $name
Installed = $false
InstallLocation = ""
}
# Search in winget list
$wingetMatch = winget list --exact | Where-Object { $_ -match $name }
if ($wingetMatch) {
$info.Installed = $true
}
# Search registry
$registryPaths = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
foreach ($path in $registryPaths) {
$apps = Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like "*$name*" }
foreach ($app in $apps) {
$info.Installed = $true
if ($app.InstallLocation -and $app.InstallLocation.Trim() -ne "") {
$info.InstallLocation = $app.InstallLocation
return $info
}
}
}
return $info
}
# Enable Microsoft Store source
winget source enable --name msstore | Out-Null
winget source update | Out-Null
# Microsoft Store apps
$storeApps = @{
"Microsoft.PowerToys" = "PowerToys"
"OpenAI.ChatGPT" = "ChatGPT"
"Microsoft.3DViewer" = "3D Viewer"
"Notion.Notion" = "Notion"
"Microsoft.SnippingTool" = "Snipping Tool"
}
# Verified winget apps
$verifiedWingetApps = @{
"Python.Python.3.12" = "Python 3.12"
"Google.Chrome" = "Google Chrome"
"TGRMNSoftware.BulkRenameUtility" = "Bulk Rename Utility"
"HandBrake.HandBrake" = "HandBrake"
"Discord.Discord" = "Discord"
"Obsidian.Obsidian" = "Obsidian"
"WhatsApp.WhatsAppDesktop" = "WhatsApp"
"Git.Git" = "Git"
"Foxit.FoxitReader" = "Foxit PDF Reader"
"Atlassian.SourceTree" = "SourceTree"
"Google.GoogleDrive" = "Google Drive"
}
# Track final report
$installReport = @()
# --- Install Microsoft Store apps ---
foreach ($id in $storeApps.Keys) {
$display = $storeApps[$id]
$appInfo = Get-AppInfo $display
if ($appInfo.Installed) {
Write-Host "`n✅ Already installed: $display" -ForegroundColor DarkGreen
} else {
Write-Host "`n>>> Installing from Microsoft Store: $display ..." -ForegroundColor Cyan
winget install --id $id --source msstore --exact --silent `
--accept-package-agreements --accept-source-agreements --scope machine
}
$installReport += $appInfo
}
# --- Install Verified Winget apps ---
foreach ($id in $verifiedWingetApps.Keys) {
$display = $verifiedWingetApps[$id]
$appInfo = Get-AppInfo $display
if ($appInfo.Installed) {
Write-Host "`n✅ Already installed: $display" -ForegroundColor DarkGreen
} else {
Write-Host "`n>>> Installing from Winget: $display ..." -ForegroundColor Yellow
$result = winget install --id $id --source winget --exact --silent `
--accept-package-agreements --accept-source-agreements --scope machine 2>&1
if ($result -match "No package found") {
Write-Warning "⚠️ Could not find exact match for: $display — running 'winget search'..."
winget search "$display"
}
# HandBrake .NET runtime handling
if ($id -eq "HandBrake.HandBrake" -and $result -match "No suitable installer.*DotNet") {
Write-Host "🛠 Installing .NET Desktop Runtime 8 (needed by HandBrake)..." -ForegroundColor Magenta
winget install --id Microsoft.DotNet.DesktopRuntime.8 --exact --silent --accept-package-agreements
Write-Host "🔁 Retrying HandBrake install..." -ForegroundColor Magenta
winget install --id HandBrake.HandBrake --exact --silent --accept-package-agreements --scope machine
}
# Refresh info after install
$appInfo = Get-AppInfo $display
}
$installReport += $appInfo
}
# --- Final Report ---
Write-Host "`n📄 --- Installation Report ---" -ForegroundColor Cyan
foreach ($entry in $installReport) {
$status = if ($entry.Installed) { "✅ Installed" } else { "❌ Not Found" }
$location = if ($entry.InstallLocation) { $entry.InstallLocation } else { "(No path info)" }
Write-Host "$status : $($entry.Name)"
Write-Host " ↪ Location: $location" -ForegroundColor Gray
}
Write-Host "`n✅ All secure installations attempted. Review logs above for results." -ForegroundColor Green