Merge pull request #38 from zehadialam/feature-app-download-automation

Improve WinGet Integration for Automated App Downloads and Installs
This commit is contained in:
rbalsleyMSFT
2024-07-12 22:49:22 -07:00
committed by GitHub
4 changed files with 226 additions and 238 deletions
+19
View File
@@ -0,0 +1,19 @@
{
"apps": [
{
"name": "7-Zip",
"id": "7zip.7zip",
"source": "winget"
},
{
"name": "Company Portal",
"id": "9WZDNCRFJ3PZ",
"source": "msstore"
},
{
"name": "Microsoft Teams",
"id": "Microsoft.Teams",
"source": "winget"
}
]
}
-2
View File
@@ -1,2 +0,0 @@
winget:7-Zip
store:Company Portal
@@ -33,11 +33,12 @@ for /d %%D in ("%basepath%\*") do (
set "licensefile=%%F" set "licensefile=%%F"
) )
if defined mainpackage ( if defined mainpackage (
if exist "!dependenciesfolder!" (
set "dism_command=DISM /Online /Add-ProvisionedAppxPackage /PackagePath:"!mainpackage!"" set "dism_command=DISM /Online /Add-ProvisionedAppxPackage /PackagePath:"!mainpackage!""
if exist "!dependenciesfolder!" (
for %%G in ("!dependenciesfolder!\*") do ( for %%G in ("!dependenciesfolder!\*") do (
set "dism_command=!dism_command! /DependencyPackagePath:"%%G"" set "dism_command=!dism_command! /DependencyPackagePath:"%%G""
) )
)
if defined licensefile ( if defined licensefile (
set "dism_command=!dism_command! /LicensePath:"!licensefile!"" set "dism_command=!dism_command! /LicensePath:"!licensefile!""
) else ( ) else (
@@ -48,9 +49,13 @@ for /d %%D in ("%basepath%\*") do (
!dism_command! !dism_command!
) )
) )
)
:remaining :remaining
endlocal endlocal
for /r "D:\" %%G in (.) do (
if exist "%%G\Notepad++" (
powershell -Command "Remove-AppxPackage -Package NotepadPlusPlus_1.0.0.0_neutral__7njy0v32s6xk6"
)
)
REM The below lines will remove the unattend.xml that gets the machine into audit mode. If not removed, the OS will get stuck booting to audit mode each time. REM The below lines will remove the unattend.xml that gets the machine into audit mode. If not removed, the OS will get stuck booting to audit mode each time.
REM Also kills the sysprep process in order to automate sysprep generalize REM Also kills the sysprep process in order to automate sysprep generalize
del c:\windows\panther\unattend\unattend.xml /F /Q del c:\windows\panther\unattend\unattend.xml /F /Q
+155 -189
View File
@@ -1660,102 +1660,72 @@ function Get-Office {
function Install-WinGet { function Install-WinGet {
param ( param (
[bool]$InstallWithDependencies [string]$Architecture
) )
$wingetPreviewLink = "https://aka.ms/getwingetpreview" $packages = @(
$wingetPackageDestination = "$env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" @{Name = "VCLibs"; Url = "https://aka.ms/Microsoft.VCLibs.$Architecture.14.00.Desktop.appx"; File = "Microsoft.VCLibs.$Architecture.14.00.Desktop.appx"},
if ($InstallWithDependencies) { @{Name = "UIXaml"; Url = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.$Architecture.appx"; File = "Microsoft.UI.Xaml.2.8.$Architecture.appx"},
$dependencies = @( @{Name = "WinGet"; Url = "https://aka.ms/getwinget"; File = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"}
@{
Source = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
Destination = "$env:TEMP\Microsoft.VCLibs.x64.14.00.Desktop.appx"
},
@{
Source = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.x64.appx"
Destination = "$env:TEMP\Microsoft.UI.Xaml.2.8.x64.appx"
}
) )
Start-BitsTransferWithRetry -Source $wingetPreviewLink -Destination $wingetPackageDestination foreach ($package in $packages) {
foreach ($dependency in $dependencies) { $destination = Join-Path -Path $env:TEMP -ChildPath $package.File
Start-BitsTransferWithRetry -Source $dependency.Source -Destination $dependency.Destination WriteLog "Downloading $($package.Name) from $($package.Url) to $destination"
Add-AppxPackage -Path $dependency.Destination Start-BitsTransferWithRetry -Source $package.Url -Destination $destination
Remove-Item -Path $dependency.Destination -Force -ErrorAction SilentlyContinue WriteLog "Installing $($package.Name)..."
} Add-AppxPackage -Path $destination -ErrorAction SilentlyContinue
Add-AppxPackage -Path $wingetPackageDestination WriteLog "Removing $($package.Name)..."
Remove-Item -Path $wingetPackageDestination -Force -ErrorAction SilentlyContinue Remove-Item -Path $destination -Force -ErrorAction SilentlyContinue
}
else {
# If WinGet was already installed, then installing the dependencies can cause an error if the system has a newer version of the dependencies than the ones downloaded.
WriteLog "Downloading WinGet..."
Start-BitsTransferWithRetry -Source $wingetPreviewLink -Destination $wingetPackageDestination
WriteLog "Installing WinGet..."
Add-AppxPackage -Path $wingetPackageDestination
WriteLog "Removing WinGet installer..."
Remove-Item -Path $wingetPackageDestination -Force -ErrorAction SilentlyContinue
} }
WriteLog "WinGet installation complete."
} }
function New-WinGetSettings { function Confirm-WinGetInstallation {
$wingetSettingsFile = "$env:LOCALAPPDATA\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json" $wingetPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
$wingetSettings = @( $minVersion = [version]"1.8.1911"
'{' if (-not (Test-Path -Path $wingetPath -PathType Leaf)) {
' "$schema": "https://aka.ms/winget-settings.schema.json",' WriteLog "WinGet is not installed. Downloading WinGet..."
' ' Install-WinGet -Architecture $WindowsArch
' // For documentation on these settings, see: https://aka.ms/winget-settings' return
' "experimentalFeatures": {'
' "storeDownload": true'
' },'
' "logging": {'
' "level": "verbose"'
' }'
'}'
)
$wingetSettingsContent = $wingetSettings -join "`n"
if (Test-Path -Path $wingetSettingsFile -PathType Leaf) {
$jsonContent = Get-Content -Path $wingetSettingsFile -Raw
# Check if storeDownload feature is already enabled
if ($jsonContent -notmatch '"storeDownload"\s*:\s*true') {
# Back up existing settings.json file
$backupWingetSettingsFile = $wingetSettingsFile + ".bak"
if (-not (Test-Path -Path $backupWingetSettingsFile -PathType Leaf)) {
WriteLog "Backing up existing WinGet settings.json file to $backupWingetSettingsFile"
Copy-Item -Path $wingetSettingsFile -Destination $backupWingetSettingsFile -Force | Out-Null
} }
WriteLog "Creating WinGet settings.json file to allow the storeDownload feature. Writing file to $wingetSettingsFile" if (-not (Get-Command -Name winget -ErrorAction SilentlyContinue)) {
$wingetSettingsContent | Out-File -FilePath $wingetSettingsFile -Encoding utf8 -Force WriteLog "WinGet is not on the path. Downloading WinGet..."
Install-WinGet -Architecture $WindowsArch
return
} }
else { $wingetVersion = & winget.exe --version
WriteLog "WinGet's settings.json file is already configured to enable the storeDownload feature." if ($wingetVersion -match 'v?(\d+\.\d+\.\d+)' -and [version]$matches[1] -lt $minVersion) {
} WriteLog "The installed version of WinGet $($matches[1]) does not support downloading MSStore apps. Downloading the latest version of WinGet..."
} Install-WinGet -Architecture $WindowsArch
else { return
WriteLog "Creating WinGet settings.json file to allow the storeDownload feature. Writing file to $wingetSettingsFile"
$wingetSettingsContent | Out-File -FilePath $wingetSettingsFile -Encoding utf8 -Force
} }
} }
function Add-Win32SilentInstallCommand { function Add-Win32SilentInstallCommand {
param ( param (
[string]$AppFolder, [string]$AppFolder,
[string]$AppFolderPath [string]$AppFolderPath,
[int]$LineNumber
) )
$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) {
$yamlFile = Get-ChildItem -Path "$appFolderPath\*" -Include *.yaml -File -ErrorAction Stop 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
$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"
} }
$cmdFile = "$AppsPath\InstallAppsandSysprep.cmd" $cmdFile = "$AppsPath\InstallAppsandSysprep.cmd"
@@ -1765,83 +1735,126 @@ 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]$WinGetApp, [string]$WinGetAppName,
[string]$WinGetAppId,
[int]$LineNumber [int]$LineNumber
) )
$wingetSearchResult = & winget.exe search --name "$WinGetApp" --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 "$WinGetApp 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 $WinGetApp $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 $WinGetApp..." $downloadParams = @(
$wingetDownloadResult = & winget.exe download --name "$WinGetApp" --exact --download-directory "$appFolderPath" --scope machine --source winget --architecture "$WindowsArch" | Out-String "download",
"--id", "$WinGetAppId",
"--exact",
"--download-directory", "$appFolderPath",
"--accept-package-agreements",
"--accept-source-agreements",
"--source", "winget",
"--scope", "machine",
"--architecture", "$WindowsArch"
)
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
if ($wingetDownloadResult -match "No applicable installer found") { if ($wingetDownloadResult -match "No applicable installer found") {
$wingetDownloadResult = & winget.exe download --name "$WinGetApp" --exact --download-directory "$appFolderPath" --scope machine --source winget | Out-String WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
if ($wingetDownloadResult -match "Installer downloaded") {
WriteLog "Downloaded $WinGetAppName without specifying architecture."
}
} }
if ($wingetDownloadResult -notmatch "Installer downloaded") { if ($wingetDownloadResult -notmatch "Installer downloaded") {
WriteLog "$WinGetApp did not successfully download." WriteLog "No installer found for $WinGetAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force Remove-Item -Path $appFolderPath -Recurse -Force
return return $false
}
WriteLog "$WinGetAppName has completed downloading to $appFolderPath"
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop
$uwpExtensions = @(".appx", ".appxbundle", ".msix", ".msixbundle")
if ($uwpExtensions -contains $installerPath.Extension) {
New-Item -Path "$AppsPath\MSStore\$WinGetAppName" -ItemType Directory -Force | Out-Null
Move-Item -Path "$appFolderPath\*" -Destination "$AppsPath\MSStore\$WinGetAppName" -Force
Remove-Item -Path $appFolderPath -Force
Set-InstallStoreAppsFlag
return $false
}
else {
Add-Win32SilentInstallCommand -AppFolder $WinGetAppName -AppFolderPath $appFolderPath -LineNumber $LineNumber
} }
WriteLog "$WinGetApp has completed downloading."
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath
} }
function Get-StoreApp { function Get-StoreApp {
param ( param (
[string]$StoreApp [string]$StoreAppName,
[string]$StoreAppId,
[int]$LineNumber
) )
$wingetSearchResult = & winget.exe search --name --exact "$StoreApp" --accept-source-agreements --source msstore $wingetSearchResult = & winget.exe search "$StoreAppId" --accept-source-agreements --source msstore
if ($wingetSearchResult -contains "No package found matching input criteria.") { if ($wingetSearchResult -contains "No package found matching input criteria.") {
WriteLog "$StoreApp not found in WinGet repository. Skipping download." WriteLog "$StoreAppName not found in WinGet repository. Skipping download."
return return
} }
# Skip the header lines and get the line with the app information WriteLog "Checking if $StoreAppName is a win32 app..."
$appResult = $wingetSearchResult | Select-Object -Skip 2 | Select-Object -First 1 $appIsWin32 = $StoreAppId.StartsWith("XP")
# Split the line by whitespace and get the second-to-last item (the Id) if ($appIsWin32) {
$appID = ($appResult -split '\s+')[-2] WriteLog "$StoreAppName is a win32 app. Adding to $AppsPath\win32 folder"
# Checking app ID to determine if store app is a win32 app $appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreAppName
WriteLog "Checking if $StoreApp is a win32 app..."
if ($appID.StartsWith("XP")) {
WriteLog "$StoreApp is a win32 app. Adding to $AppsPath\win32 folder"
$appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreApp
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
$appFolder = Split-Path -Path $appFolderPath -Leaf
WriteLog "Downloading $StoreApp for $WindowsArch architecture..."
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String
if ($wingetDownloadResult -match "No applicable installer found") {
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String
if ($wingetDownloadResult -match $StoreApp){
WriteLog "Downloaded $StoreApp without specifying architecture."
} }
else { else {
WriteLog "No installer found for $StoreApp. Skipping download." WriteLog "$StoreAppName is not a win32 app."
Remove-Item -Path $appFolderPath -Recurse -Force $appFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $StoreAppName
return
} }
}
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath
return
}
$appFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $StoreApp
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
# Invoke-Process is not used here because it terminates the script if the exit code of the process is not zero. WriteLog "Downloading $StoreAppName for $WindowsArch architecture..."
# WinGet's download command will return a non-zero exit code when downloading store apps, as attempting to download the license file always appears to cause an error. $downloadParams = @(
WriteLog "Downloading $StoreApp and dependencies..." "download", "$StoreAppId",
"--download-directory", "$appFolderPath",
"--accept-package-agreements",
"--accept-source-agreements",
"--source", "msstore",
"--scope", "machine",
"--architecture", "$WindowsArch"
)
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 --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String WriteLog "Attempting to download $StoreAppName and dependencies for $WindowsArch architecture..."
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
# 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 --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String $downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
if ($wingetDownloadResult -match $StoreApp){ $wingetDownloadResult = & winget.exe @downloadParams | Out-String
WriteLog "Downloaded $StoreApp without specifying architecture." if ($wingetDownloadResult -match "Microsoft Store package download completed") {
WriteLog "Downloaded $StoreAppName without specifying architecture."
}
}
if ($wingetDownloadResult -notmatch "Installer downloaded|Microsoft Store package download completed") {
WriteLog "Download not supported for $StoreAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
return
}
if ($appIsWin32) {
Add-Win32SilentInstallCommand -AppFolder $StoreAppName -AppFolderPath $appFolderPath -LineNumber $LineNumber
# Since a Win32 app was received, returning false to increment line number for silent install command
return $false
}
Set-InstallStoreAppsFlag
# 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') {
WriteLog 'Windows architecture is ARM64. Removing dependencies that are not ARM64.' WriteLog 'Windows architecture is ARM64. Removing dependencies that are not ARM64.'
@@ -1855,42 +1868,12 @@ function Get-StoreApp {
} }
} }
} }
} WriteLog "$StoreAppName has completed downloading. Identifying the latest version of $StoreAppName."
else {
WriteLog "No installer found for $StoreApp. 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 $StoreApp. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
return
}
$cmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
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
}
WriteLog "$StoreApp has completed downloading. Identifying the latest version of $StoreApp."
$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 $StoreApp has been identified as $latestPackage. Removing old versions of $StoreApp 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) {
if ($package.FullName -ne $latestPackage) { if ($package.FullName -ne $latestPackage) {
try { try {
@@ -1907,39 +1890,16 @@ function Get-StoreApp {
function Get-Apps { function Get-Apps {
param ( param (
[string]$AppsList [string]$AppList
) )
$apps = Get-Content -Path $AppsList $apps = Get-Content -Path $AppList -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" }
$apps | ForEach-Object { Confirm-WinGetInstallation
if ($_ -like 'winget:*') {
$wingetApps += $_.Substring(7).Trim()
}
elseif ($_ -like 'store:*') {
$storeApps += $_.Substring(6).Trim()
}
}
$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"
@@ -1949,8 +1909,11 @@ function Get-Apps {
} }
foreach ($wingetApp in $wingetApps) { foreach ($wingetApp in $wingetApps) {
try { try {
Get-WinGetApp -WinGetApp $wingetApp -LineNumber $lineNumber $result = Get-WinGetApp -WinGetAppName $wingetApp.Name -WinGetAppId $wingetApp.Id -LineNumber $lineNumber
if ($null -eq $result) {
$lineNumber++ $lineNumber++
WriteLog "Line number incremented to $lineNumber"
}
} }
catch { catch {
WriteLog "Error occurred while processing $wingetApp : $_" WriteLog "Error occurred while processing $wingetApp : $_"
@@ -1959,13 +1922,16 @@ function Get-Apps {
} }
} }
if ($storeApps) { if ($storeApps) {
New-WinGetSettings
if (-not (Test-Path -Path $storeAppsFolder -PathType Container)) { if (-not (Test-Path -Path $storeAppsFolder -PathType Container)) {
New-Item -Path $storeAppsFolder -ItemType Directory -Force | Out-Null New-Item -Path $storeAppsFolder -ItemType Directory -Force | Out-Null
} }
foreach ($storeApp in $storeApps) { foreach ($storeApp in $storeApps) {
try { try {
Get-StoreApp -StoreApp $storeApp $result = Get-StoreApp -StoreAppName $storeApp.Name -StoreAppId $storeApp.Id -LineNumber $lineNumber
if ($result -eq $false) {
$lineNumber++
WriteLog "Line number incremented to $lineNumber"
}
} }
catch { catch {
WriteLog "Error occurred while processing $storeApp : $_" WriteLog "Error occurred while processing $storeApp : $_"
@@ -3383,7 +3349,7 @@ if ($InstallApps) {
exit exit
} }
WriteLog "$AppsPath\InstallAppsandSysprep.cmd found" WriteLog "$AppsPath\InstallAppsandSysprep.cmd found"
Get-Apps -AppsList "$AppsPath\AppsList.txt" Get-Apps -AppList "$AppsPath\AppList.json"
if (-not $InstallOffice) { if (-not $InstallOffice) {
#Modify InstallAppsandSysprep.cmd to REM out the office install command #Modify InstallAppsandSysprep.cmd to REM out the office install command
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"