Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 42 additions & 41 deletions Tools/SandboxTest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
###

[CmdletBinding()]
Param(
param(
# Manifest
[Parameter(Position = 0, HelpMessage = 'The Manifest to install in the Sandbox.')]
[ValidateScript({
if (-Not (Test-Path -Path $_)) { throw "$_ does not exist" }
if (-not (Test-Path -Path $_)) { throw "$_ does not exist" }
return $true
})]
[String] $Manifest,
Expand All @@ -22,7 +22,7 @@ Param(
# MapFolder
[Parameter(HelpMessage = 'The folder to map in the Sandbox.')]
[ValidateScript({
if (-Not (Test-Path -Path $_ -PathType Container)) { throw "$_ is not a folder." }
if (-not (Test-Path -Path $_ -PathType Container)) { throw "$_ is not a folder." }
return $true
})]
[String] $MapFolder = $pwd,
Expand Down Expand Up @@ -165,7 +165,7 @@ function Initialize-Folder {
####
function Get-Release {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '',
Justification='The standard workflow that users use with other applications requires the use of plaintext GitHub Access Tokens')]
Justification = 'The standard workflow that users use with other applications requires the use of plaintext GitHub Access Tokens')]

param (
[Parameter()]
Expand All @@ -183,8 +183,7 @@ function Get-Release {
Write-Verbose 'Adding Bearer Token Authentication to Releases API Request'
$requestParameters.Add('Authentication', 'Bearer')
$requestParameters.Add('Token', $(ConvertTo-SecureString $GitHubToken -AsPlainText))
}
else {
} else {
# No token was provided or the token has expired
# If an invalid token was provided, an exception will have been thrown before this code is reached
Write-Warning @"
Expand Down Expand Up @@ -243,8 +242,7 @@ function Get-RemoteContent {
try {
$downloadTask = $script:HttpClient.GetByteArrayAsync($URL)
[System.IO.File]::WriteAllBytes($localfile.FullName, $downloadTask.Result)
}
catch {
} catch {
# If the download fails, write a zero-byte file anyways
$null | Out-File $localFile.FullName
}
Expand Down Expand Up @@ -347,7 +345,7 @@ function Test-FileChecksum {
####
function Test-GithubToken {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '',
Justification='The standard workflow that users use with other applications requires the use of plaintext GitHub Access Tokens')]
Justification = 'The standard workflow that users use with other applications requires the use of plaintext GitHub Access Tokens')]

param (
[Parameter(Mandatory = $true)]
Expand Down Expand Up @@ -403,7 +401,7 @@ function Test-GithubToken {
$tokenExpirationDays = [Math]::Round($tokenExpirationDays, 2) # We don't need all the precision the system provides

if ($cachedExpirationForParsing -eq [System.DateTime]::MaxValue.ToLongDateString().Trim()) {
Write-Verbose "The cached token contained content. It is set to never expire"
Write-Verbose 'The cached token contained content. It is set to never expire'
return $true
}

Expand All @@ -416,21 +414,18 @@ function Test-GithubToken {
Write-Verbose 'The cached token contained content, but it could not be parsed as a date. It will be re-validated'
Invoke-FileCleanup -FilePaths $cachedToken.FullName
# Do not return anything, since the token will need to be re-validated
}
else {
} else {
Write-Verbose "The cached token contained content, but the token expired $([Math]::Abs($tokenExpirationDays)) days ago"
# Leave the cached token so that it doesn't throw script exceptions in the future
# Invoke-FileCleanup -FilePaths $cachedToken.FullName
return $false
}
}
else {
} else {
# Either the token was empty, or the cached token is expired. Remove the cached token so that re-validation
# of the token will update the date the token was cached if it is still valid
Invoke-FileCleanup -FilePaths $cachedToken.FullName
}
}
else {
} else {
Write-Verbose 'Token was not found in the cache'
}

Expand Down Expand Up @@ -458,18 +453,18 @@ function Test-GithubToken {
Write-Verbose 'Token validated successfully. Adding to cache'
# Trim off any non-digit characters from the end
# Strip off the array wrapper since it is no longer needed
$tokenExpiration = $tokenExpiration[0] -replace '[^0-9]+$',''
$tokenExpiration = $tokenExpiration[0] -replace '[^0-9]+$', ''
# If the token doesn't expire, write a special value to the file
if (!$tokenExpiration -or [string]::IsNullOrWhiteSpace($tokenExpiration)) {
Write-Debug "Token expiration was empty, setting it to maximum"
Write-Debug 'Token expiration was empty, setting it to maximum'
$tokenExpiration = [System.DateTime]::MaxValue
}
# Try parsing the value to a datetime before storing it
if ([DateTime]::TryParse($tokenExpiration,[ref]$tokenExpiration)) {
if ([DateTime]::TryParse($tokenExpiration, [ref]$tokenExpiration)) {
Write-Debug "Token expiration successfully parsed as DateTime ($tokenExpiration)"
} else {
# TryParse Failed
Write-Warning "Could not parse expiration date as a DateTime object. It will be set to the minimum value"
Write-Warning 'Could not parse expiration date as a DateTime object. It will be set to the minimum value'
$tokenExpiration = [System.DateTime]::MinValue
}
# Explicitly convert to a string here to avoid implicit casting
Expand All @@ -483,7 +478,7 @@ function Test-GithubToken {
#### Start of main script ####

# Check if Windows Sandbox is enabled
if (-Not (Get-Command 'WindowsSandbox' -ErrorAction SilentlyContinue)) {
if (-not (Get-Command 'WindowsSandbox' -ErrorAction SilentlyContinue)) {
Write-Error -ErrorAction Continue -Category NotInstalled -Message @'
Windows Sandbox does not seem to be available. Check the following URL for prerequisites and further details:
https://docs.microsoft.com/windows/security/threat-protection/windows-sandbox/windows-sandbox-overview
Expand All @@ -501,20 +496,20 @@ if (!$SkipManifestValidation -and ![String]::IsNullOrWhiteSpace($Manifest)) {
Write-Error -Category NotInstalled 'WinGet is not installed. Manifest cannot be validated' -ErrorAction Continue
Invoke-CleanExit -ExitCode 3
}
Write-Information "--> Validating Manifest"
Write-Information '--> Validating Manifest'
$validateCommandOutput =
& {
# Store current output encoding setting
$prevOutEnc = [Console]::OutputEncoding
# Set [Console]::OutputEncoding to UTF-8 since winget uses UTF-8 for output
[Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
& {
# Store current output encoding setting
$prevOutEnc = [Console]::OutputEncoding
# Set [Console]::OutputEncoding to UTF-8 since winget uses UTF-8 for output
[Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()

winget.exe validate $Manifest
winget.exe validate $Manifest

# Reset the encoding to the previous values
[Console]::OutputEncoding = $prevOutEnc
}
switch ($LASTEXITCODE) {
# Reset the encoding to the previous values
[Console]::OutputEncoding = $prevOutEnc
}
switch ($LASTEXITCODE) {
'-1978335191' {
# Skip the first line and the empty last line
$validateCommandOutput | Select-Object -Skip 1 -SkipLast 1 | ForEach-Object {
Expand All @@ -532,7 +527,7 @@ if (!$SkipManifestValidation -and ![String]::IsNullOrWhiteSpace($Manifest)) {
Write-Warning 'Manifest validation succeeded with warnings'
Start-Sleep -Seconds 5 # Allow the user 5 seconds to read the warnings before moving on
}
Default {
default {
Write-Information $validateCommandOutput.Trim() # On the success, print an empty line after the command output
}
}
Expand Down Expand Up @@ -595,8 +590,7 @@ if ($script:AppInstallerParsedVersion -ge [System.Version]'1.9.25180') {
Algorithm = 'SHA256'
SaveTo = (Join-Path -Path $script:AppInstallerReleaseAssetsFolder -ChildPath $script:DependenciesZipFileName)
}
}
else {
} else {
$script:DependencySource = [DependencySources]::Legacy
# Add the VCLibs to the dependencies
Write-Debug 'Adding VCLibs UWP to dependency list'
Expand Down Expand Up @@ -626,8 +620,7 @@ else {
Algorithm = 'SHA256'
SaveTo = (Join-Path -Path $script:DependenciesCacheFolder -ChildPath 'Microsoft.UI.Xaml.2.7.x64.appx')
}
}
else {
} else {
# Add Xaml 2.8 to the dependencies
Write-Debug 'Adding Microsoft.UI.Xaml (v2.8) to dependency list'
$script:AppInstallerDependencies += @{
Expand Down Expand Up @@ -712,7 +705,7 @@ $script:SandboxWinGetSettings | ConvertTo-Json | Out-File -FilePath (Join-Path -
foreach ($dependency in $script:AppInstallerDependencies) { Copy-Item -Path $dependency.SaveTo -Destination $script:TestDataFolder -ErrorAction SilentlyContinue }

# Create a script file from the script parameter
if (-Not [String]::IsNullOrWhiteSpace($Script)) {
if (-not [String]::IsNullOrWhiteSpace($Script)) {
Write-Verbose "Creating script file from 'Script' argument"
$Script | Out-File -Path (Join-Path $script:TestDataFolder -ChildPath 'BoundParameterScript.ps1')
}
Expand Down Expand Up @@ -759,7 +752,7 @@ try {
} catch {
throw "Microsoft.Winget.Client was not installed successfully"
} finally {
# Check to be sure it acutally installed
# Check to be sure it actually installed
if (-not(Get-Module -ListAvailable -Name Microsoft.Winget.Client)) {
throw "Microsoft.Winget.Client was not found. Check that the Windows Package Manager PowerShell module was installed correctly."
}
Expand All @@ -779,6 +772,14 @@ Tip: you can type 'Update-EnvironmentVariables' to update your environment varia

Write-Host @'

--> Fixing slow MSI package installers
'@

reg add "HKLM\SYSTEM\CurrentControlSet\Control\CI\Policy" /v "VerifiedAndReputablePolicyState" /t REG_DWORD /d 0 /f # See: https://github.com/microsoft/Windows-Sandbox/issues/68#issuecomment-2754867968
CiTool.exe --refresh --json | Out-Null # Refreshes policy. Use json output param or else it will prompt for confirmation, even with Out-Null

Write-Host @'

--> Configuring Winget
'@
winget settings --Enable LocalManifestFiles
Expand Down Expand Up @@ -860,15 +861,15 @@ Write-Information @"
- Configuring Winget
"@

if (-Not [String]::IsNullOrWhiteSpace($Manifest)) {
if (-not [String]::IsNullOrWhiteSpace($Manifest)) {
Write-Information @"
- Installing the Manifest $(Split-Path $Manifest -Leaf)
- Refreshing environment variables
- Comparing ARP Entries
"@
}

if (-Not [String]::IsNullOrWhiteSpace($Script)) {
if (-not [String]::IsNullOrWhiteSpace($Script)) {
Write-Information @"
- Running the following script: {
$Script
Expand Down