Moved code into separate functions, refactored existing functions, fixed logical errors in if-statements

This commit is contained in:
Zehadi Alam
2024-07-07 22:27:27 -04:00
parent 146c1601bd
commit 325413de13
+57 -85
View File
@@ -1695,6 +1695,22 @@ function Install-WinGet {
} }
} }
function Confirm-WinGetInstallation {
$wingetPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
if (-not (Test-Path $wingetPath)) {
WriteLog "WinGet is not installed. Downloading preview version of WinGet and its dependencies..."
Install-WinGet -InstallWithDependencies $true
}
elseif (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
WriteLog "WinGet is not on the path. Downloading preview version of WinGet without dependencies..."
Install-WinGet -InstallWithDependencies $false
}
elseif (-not ((& winget.exe --version) -like "*preview*")) {
WriteLog "The preview version of WinGet is not installed. Downloading preview version of WinGet without dependencies..."
Install-WinGet -InstallWithDependencies $false
}
}
function New-WinGetSettings { function New-WinGetSettings {
$wingetSettingsFile = "$env:LOCALAPPDATA\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json" $wingetSettingsFile = "$env:LOCALAPPDATA\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json"
$wingetSettings = @( $wingetSettings = @(
@@ -1742,28 +1758,26 @@ function Add-Win32SilentInstallCommand {
) )
$appName = $AppFolder $appName = $AppFolder
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Include "*.exe", "*.msi" -File -ErrorAction Stop $installerPath = Get-ChildItem -Path "$appFolderPath\*" -Include "*.exe", "*.msi" -File -ErrorAction Stop
$installer = Split-Path -Path $installerPath -Leaf if (-not $installerPath) {
WriteLog "No win32 app installers were found. Skipping the inclusion of $AppFolder"
Remove-Item -Path $AppFolderPath -Recurse -Force
return $false
}
$yamlFile = Get-ChildItem -Path "$appFolderPath\*" -Include "*.yaml" -File -ErrorAction Stop $yamlFile = Get-ChildItem -Path "$appFolderPath\*" -Include "*.yaml" -File -ErrorAction Stop
$yamlContent = Get-Content -Path $yamlFile -Raw $yamlContent = Get-Content -Path $yamlFile -Raw
$silentInstallSwitch = [regex]::Match($yamlContent, 'Silent:\s*(.+)').Groups[1].Value $silentInstallSwitch = [regex]::Match($yamlContent, 'Silent:\s*(.+)').Groups[1].Value.Replace("'", "").Trim()
$silentInstallSwitch = $silentInstallSwitch.Replace("'", "").Trim()
if (-not $silentInstallSwitch) { if (-not $silentInstallSwitch) {
WriteLog "Silent install switch for $appName could not be found. Skipping the inclusion of $appName." WriteLog "Silent install switch for $appName could not be found. Skipping the inclusion of $appName."
Remove-Item -Path $appFolderPath -Recurse -Force Remove-Item -Path $appFolderPath -Recurse -Force
return return $false
} }
$installerFileExtension = [System.IO.Path]::GetExtension($installer) $installer = Split-Path -Path $installerPath -Leaf
if ($installerFileExtension -eq ".exe") { if ($installerPath.Extension -eq ".exe") {
$silentInstallCommand = "`"D:\win32\$appFolder\$installer`" $silentInstallSwitch" $silentInstallCommand = "`"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
} }
elseif ($installerFileExtension -eq ".msi") { elseif ($installerPath.Extension -eq ".msi") {
$silentInstallCommand = "msiexec /i `"D:\win32\$appFolder\$installer`" $silentInstallSwitch" $silentInstallCommand = "msiexec /i `"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
} }
else {
WriteLog "No win32 app installers were found. Skipping the inclusion of $appName"
Remove-Item -Path $AppFolderPath -Recurse -Force
return
}
$cmdFile = "$AppsPath\InstallAppsandSysprep.cmd" $cmdFile = "$AppsPath\InstallAppsandSysprep.cmd"
$cmdContent = Get-Content -Path $cmdFile $cmdContent = Get-Content -Path $cmdFile
$cmdContent = $cmdContent[0..($lineNumber - 2)] + $silentInstallCommand.Trim() + $cmdContent[($lineNumber - 1)..($cmdContent.Length - 1)] $cmdContent = $cmdContent[0..($lineNumber - 2)] + $silentInstallCommand.Trim() + $cmdContent[($lineNumber - 1)..($cmdContent.Length - 1)]
@@ -1771,6 +1785,16 @@ function Add-Win32SilentInstallCommand {
Set-Content -Path $cmdFile -Value $cmdContent Set-Content -Path $cmdFile -Value $cmdContent
} }
function Set-InstallStoreAppsFlag {
$cmdPath = "$AppsPath\InstallAppsandSysprep.cmd"
$cmdContent = Get-Content -Path $cmdPath
if ($cmdContent -match 'set "INSTALL_STOREAPPS=false"') {
WriteLog "Setting INSTALL_STOREAPPS flag to true in InstallAppsandSysprep.cmd file."
$updatedcmdContent = $cmdContent -replace 'set "INSTALL_STOREAPPS=false"', 'set "INSTALL_STOREAPPS=true"'
Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $updatedcmdContent
}
}
function Get-WinGetApp { function Get-WinGetApp {
param ( param (
[string]$WinGetAppName, [string]$WinGetAppName,
@@ -1780,11 +1804,11 @@ function Get-WinGetApp {
$wingetSearchResult = & winget.exe search --id "$WinGetAppId" --exact --accept-source-agreements --source winget $wingetSearchResult = & winget.exe search --id "$WinGetAppId" --exact --accept-source-agreements --source winget
if ($wingetSearchResult -contains "No package found matching input criteria.") { if ($wingetSearchResult -contains "No package found matching input criteria.") {
WriteLog "$WinGetAppName not found in WinGet repository. Skipping download." WriteLog "$WinGetAppName not found in WinGet repository. Skipping download."
return # Return false to not increment line number for silent install command.
return $false
} }
$appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetAppName $appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetAppName
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
$appFolder = Split-Path -Path $appFolderPath -Leaf
WriteLog "Downloading $WinGetAppName..." WriteLog "Downloading $WinGetAppName..."
$wingetDownloadResult = & winget.exe download --id "$WinGetAppId" --exact --download-directory "$appFolderPath" --scope machine --source winget --architecture "$WindowsArch" | Out-String $wingetDownloadResult = & winget.exe download --id "$WinGetAppId" --exact --download-directory "$appFolderPath" --scope machine --source winget --architecture "$WindowsArch" | Out-String
if ($wingetDownloadResult -match "No applicable installer found") { if ($wingetDownloadResult -match "No applicable installer found") {
@@ -1793,28 +1817,20 @@ function Get-WinGetApp {
if ($wingetDownloadResult -notmatch "Installer downloaded") { if ($wingetDownloadResult -notmatch "Installer downloaded") {
WriteLog "$WinGetAppName did not successfully download." WriteLog "$WinGetAppName did not successfully download."
Remove-Item -Path $appFolderPath -Recurse -Force Remove-Item -Path $appFolderPath -Recurse -Force
return return $false
} }
WriteLog "$WinGetAppName has completed downloading to $appFolderPath" WriteLog "$WinGetAppName has completed downloading to $appFolderPath"
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop $installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop
$installer = Split-Path -Path $installerPath -Leaf
$installerFileExtension = [System.IO.Path]::GetExtension($installer)
$uwpExtensions = @(".appx", ".appxbundle", ".msix", ".msixbundle") $uwpExtensions = @(".appx", ".appxbundle", ".msix", ".msixbundle")
if ($uwpExtensions -contains $installerFileExtension) { if ($uwpExtensions -contains $installerPath.Extension) {
New-Item -Path "$AppsPath\MSStore\$WinGetAppName" -ItemType Directory -Force | Out-Null New-Item -Path "$AppsPath\MSStore\$WinGetAppName" -ItemType Directory -Force | Out-Null
Move-Item -Path "$appFolderPath\*" -Destination "$AppsPath\MSStore\$WinGetAppName" -Force Move-Item -Path "$appFolderPath\*" -Destination "$AppsPath\MSStore\$WinGetAppName" -Force
Remove-Item -Path $appFolderPath -Force Remove-Item -Path $appFolderPath -Force
$cmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" Set-InstallStoreAppsFlag
if ($cmdContent -match 'set "INSTALL_STOREAPPS=false"') {
WriteLog "Setting INSTALL_STOREAPPS flag to true in InstallAppsandSysprep.cmd file."
$updatedcmdContent = $cmdContent -replace 'set "INSTALL_STOREAPPS=false"', 'set "INSTALL_STOREAPPS=true"'
Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $updatedcmdContent
}
# Since a Win32 app was not received, returning false to not increment line number for silent install command
return $false return $false
} }
else { else {
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath -LineNumber $LineNumber Add-Win32SilentInstallCommand -AppFolder $WinGetAppName -AppFolderPath $appFolderPath -LineNumber $LineNumber
} }
} }
@@ -1839,13 +1855,12 @@ function Get-StoreApp {
WriteLog "$StoreAppName is a win32 app. Adding to $AppsPath\win32 folder" WriteLog "$StoreAppName is a win32 app. Adding to $AppsPath\win32 folder"
$appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreAppName $appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreAppName
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
$appFolder = Split-Path -Path $appFolderPath -Leaf
WriteLog "Downloading $StoreAppName for $WindowsArch architecture..." WriteLog "Downloading $StoreAppName for $WindowsArch architecture..."
$wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String $wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String
if ($wingetDownloadResult -match "No applicable installer found") { if ($wingetDownloadResult -match "No applicable installer found") {
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..." WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String $wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String
if ($wingetDownloadResult -match $StoreAppName){ if ($wingetDownloadResult -match "Installer downloaded"){
WriteLog "Downloaded $StoreAppName without specifying architecture." WriteLog "Downloaded $StoreAppName without specifying architecture."
} }
else { else {
@@ -1854,7 +1869,7 @@ function Get-StoreApp {
return return
} }
} }
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath -LineNumber $LineNumber Add-Win32SilentInstallCommand -AppFolder $StoreAppName -AppFolderPath $appFolderPath -LineNumber $LineNumber
# Since a Win32 app was received, returning false to increment line number for silent install command # Since a Win32 app was received, returning false to increment line number for silent install command
return $false return $false
} }
@@ -1865,22 +1880,11 @@ function Get-StoreApp {
WriteLog "Attempting to download $StoreAppName and dependencies..." WriteLog "Attempting to download $StoreAppName and dependencies..."
WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.' WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.'
$wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String $wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String
if ($wingetDownloadResult -match "The request is not supported") {
WriteLog "The download request is not supported for $StoreAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
return
}
# Many store apps can be found by winget search, but the download of the apps are unsupported.
if ($wingetDownloadResult -match "No applicable Microsoft Store package download information found.") {
WriteLog "No applicable Microsoft Store package download information found for $StoreAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
return
}
# For some apps, specifying the architecture leads to no results found for the app. In those cases, the command will be run without the architecture parameter. # For some apps, specifying the architecture leads to no results found for the app. In those cases, the command will be run without the architecture parameter.
if ($wingetDownloadResult -match "No applicable installer found") { if ($wingetDownloadResult -match "No applicable installer found") {
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..." WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String $wingetDownloadResult = & winget.exe download "$StoreAppId" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String
if ($wingetDownloadResult -match "Installer downloaded") { if ($wingetDownloadResult -match "Microsoft Store package download completed") {
WriteLog "Downloaded $StoreAppName without specifying architecture." WriteLog "Downloaded $StoreAppName without specifying architecture."
# If $WindowsArch -eq 'ARM64', remove all dependency files that are not ARM64 # If $WindowsArch -eq 'ARM64', remove all dependency files that are not ARM64
if ($WindowsArch -eq 'ARM64') { if ($WindowsArch -eq 'ARM64') {
@@ -1902,27 +1906,16 @@ function Get-StoreApp {
return return
} }
} }
$cmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" elseif ($wingetDownloadResult -notmatch "Microsoft Store package download completed") {
if ($cmdContent -match 'set "INSTALL_STOREAPPS=false"') { WriteLog "Download not supported for $StoreAppName. Skipping download."
WriteLog "Setting INSTALL_STOREAPPS flag to true in InstallAppsandSysprep.cmd file." Remove-Item -Path $appFolderPath -Recurse -Force
$updatedcmdContent = $cmdContent -replace 'set "INSTALL_STOREAPPS=false"', 'set "INSTALL_STOREAPPS=true"' return
Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $updatedcmdContent
} }
Set-InstallStoreAppsFlag
WriteLog "$StoreAppName has completed downloading. Identifying the latest version of $StoreAppName." WriteLog "$StoreAppName has completed downloading. Identifying the latest version of $StoreAppName."
$packages = Get-ChildItem -Path "$appFolderPath\*" -Exclude "Dependencies\*", "*.xml", "*.yaml" -File -ErrorAction Stop $packages = Get-ChildItem -Path "$appFolderPath\*" -Exclude "Dependencies\*", "*.xml", "*.yaml" -File -ErrorAction Stop
# WinGet downloads multiple versions of certain store apps. The latest version of the package will be determined based on the date of the file signature. # WinGet downloads multiple versions of certain store apps. The latest version of the package will be determined based on the date of the file signature.
$latestPackage = "" $latestPackage = $packages | Sort-Object { (Get-AuthenticodeSignature $_.FullName).SignerCertificate.NotBefore } -Descending | Select-Object -First 1
$latestDate = [datetime]::MinValue
foreach ($package in $packages) {
$signature = Get-AuthenticodeSignature -FilePath $package.FullName
if ($signature.Status -eq 'Valid') {
$signatureDate = $signature.SignerCertificate.NotBefore
if ($signatureDate -gt $latestDate) {
$latestPackage = $package.FullName
$latestDate = $signatureDate
}
}
}
# Removing all packages that are not the latest version # Removing all packages that are not the latest version
WriteLog "Latest version of $StoreAppName has been identified as $latestPackage. Removing old versions of $StoreAppName that may have downloaded." WriteLog "Latest version of $StoreAppName has been identified as $latestPackage. Removing old versions of $StoreAppName that may have downloaded."
foreach ($package in $packages) { foreach ($package in $packages) {
@@ -1945,35 +1938,12 @@ function Get-Apps {
) )
$apps = Get-Content -Path $AppsList -Raw | ConvertFrom-Json $apps = Get-Content -Path $AppsList -Raw | ConvertFrom-Json
if (-not $apps) { if (-not $apps) {
WriteLog "No apps were specified in AppsList.txt file." WriteLog "No apps were specified in AppList.json file."
return return
} }
$wingetApps = @() $wingetApps = $apps.apps | Where-Object { $_.source -eq "winget" }
$storeApps = @() $storeApps = $apps.apps | Where-Object { $_.source -eq "msstore" }
foreach ($app in $apps.apps) { Confirm-WinGetInstallation
if ($app.source -eq "winget") {
$wingetApps += $app
}
elseif ($app.source -eq "msstore") {
$storeApps += $app
}
}
$wingetInstalled = Get-ChildItem -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe" -ErrorAction SilentlyContinue
if (-not $wingetInstalled) {
WriteLog "WinGet is not installed. Downloading preview version of WinGet and its dependencies..."
Install-WinGet -InstallWithDependencies $true
}
$wingetOnPath = Get-Command winget -ErrorAction SilentlyContinue
if (-not $wingetOnPath) {
WriteLog "WinGet is not on the path. Downloading preview version of WinGet without dependencies..."
Install-WinGet -InstallWithDependencies $false
}
$wingetVersion = & winget.exe --version
# Preview release is needed to enable storeDownload experimental feature
if (-not ($wingetVersion -like "*preview*")) {
WriteLog "The preview version of WinGet is not installed. Downloading preview version of WinGet without dependencies..."
Install-WinGet -InstallWithDependencies $false
}
$lineNumber = 13 $lineNumber = 13
$win32Folder = Join-Path -Path $AppsPath -ChildPath "Win32" $win32Folder = Join-Path -Path $AppsPath -ChildPath "Win32"
$storeAppsFolder = Join-Path -Path $AppsPath -ChildPath "MSStore" $storeAppsFolder = Join-Path -Path $AppsPath -ChildPath "MSStore"
@@ -1986,6 +1956,7 @@ function Get-Apps {
$result = Get-WinGetApp -WinGetAppName $wingetApp.Name -WinGetAppId $wingetApp.Id -LineNumber $lineNumber $result = Get-WinGetApp -WinGetAppName $wingetApp.Name -WinGetAppId $wingetApp.Id -LineNumber $lineNumber
if ($null -eq $result) { if ($null -eq $result) {
$lineNumber++ $lineNumber++
WriteLog "Line number incremented to $lineNumber"
} }
} }
catch { catch {
@@ -2004,6 +1975,7 @@ function Get-Apps {
$result = Get-StoreApp -StoreAppName $storeApp.Name -StoreAppId $storeApp.Id -LineNumber $lineNumber $result = Get-StoreApp -StoreAppName $storeApp.Name -StoreAppId $storeApp.Id -LineNumber $lineNumber
if ($result -eq $false) { if ($result -eq $false) {
$lineNumber++ $lineNumber++
WriteLog "Line number incremented to $lineNumber"
} }
} }
catch { catch {