Winget PowerShell Help
Anonymous
powershell
08/01/2024 9:18 AM
18.4 KB
212
No Index
#Set the execution policy for the current process to Unrestricted. This change applies only to the current script or session.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force
# Function to check if the script is running as Administrator
function Test-IsAdmin {
$currentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$currentPrincipal = New-Object System.Security.Principal.WindowsPrincipal($currentIdentity)
return $currentPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
# Function to restart the script with elevated permissions
function Start-Elevated {
$scriptPath = $PSCommandPath
Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -Verb RunAs
exit
}
<###########################################################################################################
# Only need if Install-Module Microsoft.WinGet.Client & Install-PackageProvider -Name NuGet are required
# Check if the script is running as Administrator; if not, restart with elevated permissions
if (-not (Test-IsAdmin)) {
Start-Elevated
}
###########################################################################################################>
# Define log file path
$logDirectory = "C:\CompanyName-IT"
$logFile = "$logDirectory\winget_install_log.txt"
# Create log directory if it doesn't exist
if (-not (Test-Path -Path $logDirectory)) {
New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null
}
# Function to log messages
function Write-Log {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Host $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to install winget & dependencies
Function Install_Winget {
$instDir = "C:\Winget"
if (-not (Test-Path -Path $instDir)) {
New-Item -ItemType Directory -Path $instDir -Force | Out-Null
}
$webClient = New-Object System.Net.WebClient
Write-Log "Downloading WinGet and its dependencies..."
try {
# Step 1: Download Microsoft.VCLibs.x64.14.00.Desktop
Write-Log "Step 1: Downloading Microsoft.VCLibs.x64.14.00.Desktop..."
$urlMSVclibs = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
$outputMSVclibs = "$instDir\Microsoft.VCLibs.x64.14.00.Desktop.appx"
$webClient.DownloadFile($urlMSVclibs, $outputMSVclibs)
Write-Log "Download complete: Microsoft.VCLibs.x64.14.00.Desktop.appx"
Add-AppxPackage -Path $outputMSVclibs -ErrorAction SilentlyContinue
Write-Log "Microsoft.VCLibs.x64.14.00.Desktop installed successfully."
# Step 2: Download Microsoft.UI.Xaml.2.8.x64
Write-Log "Step 2: Downloading Microsoft.UI.Xaml.2.8.x64..."
$urlMSXamlx64 = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.x64.appx"
$outputMSXamlx64 = "$instDir\Microsoft.UI.Xaml.2.8.x64.appx"
$webClient.DownloadFile($urlMSXamlx64, $outputMSXamlx64)
Write-Log "Download complete: Microsoft.UI.Xaml.2.8.x64.appx"
Add-AppxPackage -Path $outputMSXamlx64 -ErrorAction SilentlyContinue
Write-Log "Microsoft.UI.Xaml.2.8.x64 installed successfully."
# Step 3: Download Microsoft.DesktopAppInstaller (Winget)
Write-Log "Step 3: Downloading Microsoft.DesktopAppInstaller..."
$urlWingetLic = "https://github.com/microsoft/winget-cli/releases/download/v1.7.10582/5e4a105df01840b0bbf00985e4f57c1e_License1.xml"
$outputWingetLic = "$instDir\5e4a105df01840b0bbf00985e4f57c1e_License1.xml"
$urlWinget = "https://github.com/microsoft/winget-cli/releases/download/v1.7.10582/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$outputWinget = "$instDir\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$webClient.DownloadFile($urlWingetLic, $outputWingetLic)
$webClient.DownloadFile($urlWinget, $outputWinget)
Write-Log "Download complete: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
Add-AppxPackage -Path $outputWinget -ErrorAction SilentlyContinue
#Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope AllUsers -Force # Is this needed? Need to check.
#Install-Module Microsoft.WinGet.Client -Scope AllUsers -Force # Is this needed? Need to check.
Write-Log "WinGet client installed successfully."
}
catch {
Write-Log "An error occurred: $_"
}
finally {
$webClient.Dispose()
}
Write-Log "All steps completed successfully."
}
# Function to verify Winget install
function Verify_Winget {
try {
Write-Log "Initializing Winget..."
Start-Sleep -Seconds 15
# Verify Winget installation
$msAppInstallerInstalled = Get-AppxPackage -Name 'Microsoft.DesktopAppInstaller' -ErrorAction SilentlyContinue
if ($msAppInstallerInstalled) {
$wingetVer = (winget --version)
Write-Log "Winget $wingetVer is installed."
} else {
Write-Log "Winget is not installed."
}
}
catch {
Write-Log "An error occurred during verification: $_"
exit 1
}
}
# Define the list of applications to install using winget
$applicationsToInstall = @(
"SlackTechnologies.Slack",
"Google.Chrome",
"Box.Box",
"Box.BoxTools",
"Zoom.Zoom",
"Mozilla.Firefox",
"Notepad++.Notepad++",
"DominikReichl.KeePass",
"7zip.7zip",
"Greenshot.Greenshot",
"Microsoft.EdgeWebView2Runtime",
"Microsoft.OpenJDK.21",
"Microsoft.Office",
"Zoom.ZoomOutlookPlugin",
"Microsoft.Teams"
)
# Function to install an application using winget
function Install-App {
param (
[string]$appName
)
Write-Log "Checking $appName..."
# Winget Error Code Hash Table # https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md
$errorCodes = @{
-1978335231 = "Internal Error"
-1978335230 = "Invalid command line arguments"
-1978335229 = "Executing command failed"
-1978335228 = "Opening manifest failed"
-1978335227 = "Cancellation signal received"
-1978335226 = "Running ShellExecute failed"
-1978335225 = "Cannot process manifest. The manifest version is higher than supported. Please update the client."
-1978335224 = "Downloading installer failed"
-1978335223 = "Cannot write to index; it is a higher schema version"
-1978335222 = "The index is corrupt"
-1978335221 = "The configured source information is corrupt"
-1978335220 = "The source name is already configured"
-1978335219 = "The source type is invalid"
-1978335218 = "The MSIX file is a bundle"
-1978335217 = "Data required by the source is missing"
-1978335216 = "None of the installers are applicable for the current system"
-1978335215 = "The installer file's hash does not match the manifest"
-1978335214 = "The source name does not exist"
-1978335213 = "The source location is already configured under another name"
-1978335212 = "No packages found"
-1978335211 = "No sources are configured"
-1978335210 = "Multiple packages found matching the criteria"
-1978335209 = "No manifest found matching the criteria"
-1978335208 = "Failed to get Public folder from source package"
-1978335207 = "Command requires administrator privileges to run"
-1978335206 = "The source location is not secure"
-1978335205 = "The Microsoft Store client is blocked by policy"
-1978335204 = "The Microsoft Store app is blocked by policy"
-1978335203 = "The feature is currently under development. It can be enabled using winget settings."
-1978335202 = "Failed to install the Microsoft Store app"
-1978335201 = "Failed to perform auto complete"
-1978335200 = "Failed to initialize YAML parser"
-1978335199 = "Encountered an invalid YAML key"
-1978335198 = "Encountered a duplicate YAML key"
-1978335197 = "Invalid YAML operation"
-1978335196 = "Failed to build YAML doc"
-1978335195 = "Invalid YAML emitter state"
-1978335194 = "Invalid YAML data"
-1978335193 = "LibYAML error"
-1978335192 = "Manifest validation succeeded with warning"
-1978335191 = "Manifest validation failed"
-1978335190 = "Manifest is invalid"
-1978335189 = "App exist but no applicable updates found"
-1978335188 = "winget upgrade --all completed with failures"
-1978335187 = "Installer failed security check"
-1978335186 = "Download size does not match expected content length"
-1978335185 = "Uninstall command not found"
-1978335184 = "Running uninstall command failed"
-1978335183 = "ICU break iterator error"
-1978335182 = "ICU casemap error"
-1978335181 = "ICU regex error"
-1978335180 = "Failed to install one or more imported packages"
-1978335179 = "Could not find one or more requested packages"
-1978335178 = "Json file is invalid"
-1978335177 = "The source location is not remote"
-1978335176 = "The configured rest source is not supported"
-1978335175 = "Invalid data returned by rest source"
-1978335174 = "Operation is blocked by Group Policy"
-1978335173 = "Rest API internal error"
-1978335172 = "Invalid rest source url"
-1978335171 = "Unsupported MIME type returned by rest API"
-1978335170 = "Invalid rest source contract version"
-1978335169 = "Failed to connect to source"
-1978335168 = "Invalid response returned from rest source"
-1978335167 = "Rest source not found"
-1978335166 = "Invalid source identifier"
-1978335165 = "Source mismatch"
-1978335164 = "YAML syntax error"
-1978335163 = "Unsupported YAML version"
-1978335162 = "Missing required YAML field"
-1978335161 = "Invalid YAML parser state"
-1978335160 = "Failed to parse manifest"
-1978335159 = "API retry limit reached"
-1978335158 = "API limit reached"
-1978335157 = "Invalid action specified"
-1978335156 = "Invalid command-line arguments"
-1978335155 = "Unknown argument provided"
-1978335154 = "Invalid configuration provided to parser"
-1978335153 = "Parser syntax error"
-1978335152 = "Unknown parser error"
-1978335151 = "System command is invalid"
-1978335150 = "System command not supported"
-1978335149 = "System command failed"
-1978335148 = "System command timed out"
-1978335147 = "System command returned invalid result"
-1978335146 = "System command returned an invalid file"
-1978335145 = "System command returned an invalid path"
-1978335144 = "System command returned an invalid parameter"
-1978335143 = "System command returned invalid format"
-1978335142 = "System command returned invalid state"
-1978335141 = "System command returned invalid output"
-1978335140 = "System command returned invalid input"
-1978335139 = "System command timed out"
-1978335138 = "System command failed with unknown error"
}
try {
$process = Start-Process -FilePath "winget" -ArgumentList "install --id $appName --silent --scope `"machine`" --accept-package-agreements --accept-source-agreements" -NoNewWindow -PassThru -Wait
# Log the exit code for debugging
$exitCode = $process.ExitCode
# Check exit code
if ($errorCodes.ContainsKey($exitCode) -eq 0) {
Write-Log "$appName processed successfully."
} else {
if ($errorCodes.ContainsKey($exitCode)) {
$errorMessage = "Error: $($errorCodes[$process.ExitCode])."
} else {
$errorMessage = "Error: Unknown error code."
}
Write-Log "$errorMessage"
# Optionally, retry the process without --scope "machine"
if ($exitCode -ne -1978335189) {
Write-Log "Cannot install machine wide. Retry 1:1"
$process = Start-Process -FilePath "winget" -ArgumentList "install --id $appName --silent --accept-package-agreements --accept-source-agreements" -NoNewWindow -PassThru -Wait
$exitCode = $process.ExitCode
# Check exit code
if ($exitCode -eq 0) {
Write-Log "$appName processed successfully."
} else {
$errorMessage = "Error: $($errorCodes[$process.ExitCode])."
}
}
}
}
catch {
# Handle any unexpected errors
$errorMessage = "An unexpected error occurred. Reason: $_"
Write-Log "$errorMessage Check error log for details."
}
}
# Call the Winget install function
Install_Winget
# Call the Winget verification function
Verify_Winget
Write-Log "Starting Application Installs..."
# Loop through applications and install or update each one
foreach ($app in $applicationsToInstall) {
Install-App -appName $app
Start-Sleep -Seconds 5 # Pause the script for 5 seconds
}
Write-Log "Applications have been installed."
# Create a Windows native notification
$notificationMessage = "Welcome to CompanyName! Your standard applications have been installed."
$notificationCommand = "New-BurntToastNotification -Text 'Installation Complete', '$notificationMessage'"
if (-not (Get-Command New-BurntToastNotification -ErrorAction SilentlyContinue)) {
Install-Module -Name BurntToast -Force -Scope CurrentUser -Confirm:$false
Import-Module BurntToast
}
Invoke-Expression $notificationCommand
Write-Log "Installation notification displayed."
Write-Log "Script execution completed."Editor is loading...
Leave a Comment