Fix scoped variable formatting in verification log#2
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThis PR escapes the re-execution failure log message to output a literal ${name} placeholder and adds a properly quoted pwsh wrapper script to ensure correct path handling in PowerShell. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary of ChangesHello @ib-bsb-br, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new PowerShell script designed to automate the setup and configuration of Windows Sandbox. The script incorporates various advanced settings, such as vGPU, networking, audio/video input, and controlled clipboard/printer redirection, along with an integrated evasion script to detect virtualized environments. A key aspect of this update is ensuring the correct formatting of variable references within log messages to prevent PowerShell interpretation errors, specifically for re-execution failure logs during the verification phase. The overall goal is to provide a robust and configurable Windows Sandbox environment. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Pull Request Overview
No pull request changes were provided for review. The PR metadata section is empty, so I cannot determine the purpose of the changes or identify what files were modified.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Code Review
This pull request introduces a new PowerShell script for Windows Sandbox setup and fixes a variable formatting issue within it. The fix correctly uses ${name} to prevent PowerShell from misinterpreting it as a scoped variable, which is a good catch. I've reviewed the new script and found a few areas for improvement regarding consistency, correctness, and maintainability. My suggestions include replacing obsolete cmdlets, correcting logic for CPU core counting, clarifying log messages, and removing dead code.
|
@ib-bsb-br I've opened a new pull request, #3, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@ib-bsb-br, thank you for trying to invoke a review! To request a code review from me, please use the command |
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot Now i've tried the following implementation: #Requires -RunAsAdministrator
#Requires -Version 7.5.4
<#
.SYNOPSIS
Production-grade script fusing narrative procedural instructions for Windows Sandbox setup with evasion techniques.
Converts Tom/Jerry narrative: Enables feature, configures .wsb with vGPU/Networking/AudioInput/VideoInput/ClipboardRedirection + evasion probes (RAM/cores/MAC/install date/process checks, jitter).
Idempotent via HKLM markers; robust error handling; progress logging; confirmations for mutations.
.DESCRIPTION
Runnable at C:\Windows\SysWOW64\pwsh.ps1 on Windows 10 22H2 (admin). Supports -WhatIf/-Confirm/-Verbose/-Force.
.NOTES
No external calls; built-in only. Exit 0 success, 1 failure, 2 verification fail.
#>
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param(
[switch]$Force,
[switch]$NoShortcut
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Constants
$RegistryBase = 'HKLM:\Software\PwshSetup'
$StepsKey = Join-Path $RegistryBase 'Steps'
$ConfigDir = 'C:\ProgramData\WindowsSandbox'
$ConfigPath = Join-Path $ConfigDir 'AdminMax.wsb'
$ShortcutLnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Windows Sandbox (AdminMax).lnk'
$LogDir = $ConfigDir
$LogPath = Join-Path $LogDir 'setup.log'
$FeatureName = 'Containers-DisposableClientVM'
$RequiredPwshVersion = [version]'7.5.4'
$MinimumBuild = 18362
$TotalWeight = 300
$CurrentWeight = 0
# Runtime state
$script:HypervisorPresent = $false
$script:ExecutionPolicyArgument = 'Bypass'
$script:DisableRedirections = $true
# Logging with colors
$LogColors = @{INFO = 'White'; WARN = 'Yellow'; ERROR = 'Red'; SUCCESS = 'Green'}
function Write-Log {
param(
[Parameter(Mandatory)]
[string]$Message,
[ValidateSet('INFO','WARN','ERROR','SUCCESS')]
[string]$Level = 'INFO'
)
$ts = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
$line = "[{0}] [{1}] {2}" -f $ts, $Level, $Message
Write-Verbose $line
if ($VerbosePreference -eq 'Continue') {
Write-Host $line -ForegroundColor $LogColors[$Level]
}
try {
Add-Content -LiteralPath $LogPath -Value $line
} catch {
}
}
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
try {
Start-Transcript -Path $LogPath -Append
} catch {
Write-Log "Transcript start failed." 'WARN'
}
function Invoke-Preflight {
Write-Log "Preflight: Admin check." 'INFO'
$principal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Log "Exit:1 - Elevated required." 'ERROR'
throw "Exit:1 - Elevated required."
}
Write-Log "Preflight: PS version $RequiredPwshVersion+." 'INFO'
if ($PSVersionTable.PSVersion -lt $RequiredPwshVersion) {
Write-Log "Exit:2 - PS version mismatch." 'ERROR'
throw "Exit:2 - PS $RequiredPwshVersion+ required."
}
$osv = [Environment]::OSVersion.Version
Write-Log "Preflight: OS build $MinimumBuild+." 'INFO'
if ($osv.Build -lt $MinimumBuild) {
Write-Log "Exit:3 - OS unsupported." 'ERROR'
throw "Exit:3 - Build $MinimumBuild+ required."
}
$hvPresent = $false
try {
$ci = Get-ComputerInfo -Property 'HyperVisorPresent' -ErrorAction Stop
$hvPresent = [bool]$ci.HyperVisorPresent
} catch {
Write-Log "Exit:1 - HyperVisor query failed: $($_.Exception.Message)" 'WARN'
}
$script:HypervisorPresent = $hvPresent
if (-not $hvPresent) {
Write-Log "Enable VT-x/AMD-V in BIOS (F2/Del > Advanced > CPU > Virtualization > Enable; reboot)." 'WARN'
}
try {
$hyperType = & bcdedit /enum | Select-String 'hypervisorlaunchtype'
if (-not $hyperType) {
Write-Log "Set via bcdedit /set hypervisorlaunchtype auto; reboot." 'WARN'
}
} catch {
Write-Log "Exit:1 - bcdedit query failed: $($_.Exception.Message)" 'WARN'
}
try {
$uuid = (Get-WmiObject Win32_ComputerSystemProduct -ErrorAction Stop | Select-Object -ExpandProperty UUID)
if ($uuid -and $uuid -match '^[0-9A-F]{8}-') {
Write-Log "Nested virtualization possible (UUID $uuid)." 'WARN'
}
} catch {
Write-Log "Exit:1 - Nested virt check failed: $($_.Exception.Message)" 'WARN'
}
$script:DisableRedirections = Confirm-Action "Disable redirections to block pivots?"
if ($script:DisableRedirections) {
Write-Log "Clipboard and printer redirections will be disabled." 'INFO'
} else {
Write-Log "Clipboard and printer redirections remain enabled per operator override." 'WARN'
}
$certificates = @()
try {
if (Test-Path 'Cert:\LocalMachine\My') {
$certificates = Get-ChildItem -Path 'Cert:\LocalMachine\My' -ErrorAction Stop |
Where-Object { $_.Subject -like '*SelfSigned*' }
}
} catch {
Write-Log "Exit:1 - Certificate store query failed: $($_.Exception.Message)" 'WARN'
}
if ($certificates) {
$script:ExecutionPolicyArgument = 'AllSigned'
Write-Log "ExecutionPolicy AllSigned enforced via existing certificate." 'INFO'
} else {
if (Confirm-Action "Sign evade.ps1? (New-SelfSignedCertificate -Subject 'SandboxEvasion' -CertStoreLocation Cert:\LocalMachine\My)") {
Write-Log "Operator will supply signing certificate; maintain AllSigned posture once available." 'WARN'
} else {
$script:ExecutionPolicyArgument = 'Bypass'
Write-Log "No signing certificate; ExecutionPolicy Bypass will be used until signing completes." 'WARN'
}
}
Write-Log "Preflight complete." 'SUCCESS'
}
function Get-DesiredWsbContent {
$evasionPath = Join-Path $ConfigDir 'evade.ps1'
$evasionPsContent = @'
# Validation mode: set SANDBOX_VALIDATE=1 prior to runtime testing.
$validationMode = [bool]([Environment]::GetEnvironmentVariable('SANDBOX_VALIDATE'))
function Invoke-EvasionExit {
param([int]$Code = 0)
if ($validationMode) {
Write-Verbose "Validation guard exit($Code)"
return
}
exit $Code
}
$ram = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB
if ($ram -lt 2) { Invoke-EvasionExit 0 }
$cores = (Get-WmiObject Win32_Processor).NumberOfCores
if ($cores -lt 4) { Invoke-EvasionExit 0 }
Get-NetAdapter | ForEach-Object {
$mac = $_.MacAddress.Replace(':','')
if ($mac.Substring(0,6) -in @('000C29','001C14','005056')) { Invoke-EvasionExit 0 }
}
$installDate = [Management.ManagementDateTimeConverter]::ToDateTime((Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion -Name InstallDate -EA SilentlyContinue).InstallDate)
if ($installDate -and ((Get-Date) - $installDate).Days -lt 30) { Invoke-EvasionExit 0 }
$hooks = Get-Process | Where-Object { $_.PSSystemName -ne $env:COMPUTERNAME -or ($_.Path -like '*hook*') }
if ($hooks) { Invoke-EvasionExit 0 }
if (Get-Process | Where-Object { $_.ProcessName -in @('VBoxService','VMwareService','wireshark','procmon','ida') }) { Invoke-EvasionExit 0 }
$timer = Measure-Command { Start-Sleep -Milliseconds (Get-Random -Min 2000 -Max 10000) }
if ($timer.TotalMilliseconds -lt 1500) { Invoke-EvasionExit 0 }
Write-Output "Evasion checks passed; proceeding."
'@
$totalMemory = 0
try {
$totalMemory = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1MB
} catch {
Write-Log "Exit:1 - Memory query failed: $($_.Exception.Message)" 'WARN'
}
$mem = [math]::Min(14336, [math]::Floor([double]$totalMemory))
if ($mem -le 0) {
$mem = 4096
}
$vGpu = if ($script:HypervisorPresent) { 'Enable' } else { 'Disable' }
$clipboardSetting = if ($script:DisableRedirections) { 'Disable' } else { 'Enable' }
$printerSetting = $clipboardSetting
$mappedFolders = @"
<MappedFolders>
<MappedFolder>
<HostFolder>C:\Test</HostFolder>
<SandboxFolder>C:\Users\WDAGUtilityAccount\Desktop\Test</SandboxFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
"@
$logonCmd = " <LogonCommand><Command>powershell.exe -ExecutionPolicy $($script:ExecutionPolicyArgument) -File `"$evasionPath`"</Command></LogonCommand>"
$configuration = @"
<Configuration>
<vGPU>$vGpu</vGPU>
<Networking>Enable</Networking>
<AudioInput>Enable</AudioInput>
<VideoInput>Enable</VideoInput>
<ClipboardRedirection>$clipboardSetting</ClipboardRedirection>
<ProtectedClient>Enable</ProtectedClient>
<PrinterRedirection>$printerSetting</PrinterRedirection>
<MemoryInMB>$mem</MemoryInMB>
$mappedFolders$logonCmd
</Configuration>
"@.Trim()
$start = $configuration.IndexOf('<LogonCommand>')
$end = $configuration.IndexOf('</LogonCommand>')
$psContent = if ($start -ge 0 -and $end -gt $start) {
$configuration.Substring($start + 14, $end - $start - 14).Trim()
} else {
''
}
if ($psContent -eq '') {
throw 'Extraction failed'
}
[PSCustomObject]@{
WsbContent = $configuration
ScriptContent = $evasionPsContent.Trim()
LogonCommand = $psContent
}
}
function Compare-FileContent {
param(
[string]$Path,
[string]$Desired
)
if (-not (Test-Path $Path)) {
return $false
}
(Get-Content $Path -Raw -Encoding UTF8) -eq $Desired
}
function Confirm-Action {
param(
[string]$Prompt
)
if ($Force) {
return $true
}
if (-not $Force -and -not $PSCmdlet.ShouldContinue($Prompt, 'UserConfirm')) {
$answer = Read-Host "$Prompt [y/N]"
return $answer -match '^(y|yes)$'
}
return $true
}
function Invoke-Step {
param(
$Step
)
$stepKey = Join-Path $StepsKey $Step.Name
$systemTest = $Step.SystemTest
Write-Output "Executing step: $($Step.Name)"
Write-Log "Step $($Step.Name) evaluation." 'INFO'
$isSatisfied = & $systemTest
$markerData = $null
if (Test-Path $stepKey) {
$markerData = Get-ItemProperty $stepKey -ErrorAction SilentlyContinue
}
$marker = $markerData -and $markerData.Status -eq 'Completed'
$recent = $false
if ($markerData -and $markerData.PSObject.Properties.Match('Timestamp')) {
try {
$timestamp = [datetime]$markerData.Timestamp
$recent = $timestamp -gt (Get-Date).AddHours(-1)
} catch {
Write-Log "Exit:1 - Timestamp parse failed for $($Step.Name): $($_.Exception.Message)" 'WARN'
}
}
if ($isSatisfied -and $marker -and $recent) {
Write-Log "Step $($Step.Name): Satisfied (marker timestamp fresh)." 'SUCCESS'
$script:CurrentWeight += $Step.Weight / $TotalWeight * 100
Write-Progress -Activity "Sandbox Setup" -Status $Step.Name -PercentComplete $script:CurrentWeight
return
}
if ($isSatisfied -and $marker -and -not $recent) {
Write-Log "Step $($Step.Name): marker stale; re-running to refresh state." 'WARN'
}
if ($PSCmdlet.ShouldProcess($Step.Name, 'Execute')) {
try {
if ($Step.Name -eq 'EnsureWsb' -and $script:ExecutionPolicyArgument -eq 'Bypass' -and -not (Confirm-Action "Use Bypass ExecutionPolicy for evasion LogonCommand until signing completes?")) {
throw 'ExecutionPolicy bypass rejected by operator.'
}
& {
param($InnerStep)
switch ($InnerStep.Name) {
'EnableFeature' {
$state = (Get-WindowsOptionalFeature -Online -FeatureName $FeatureName).State
if ($state -eq 'Enabled') {
return
}
$result = Enable-WindowsOptionalFeature -Online -FeatureName $FeatureName -All -NoRestart
if ($result.RestartNeeded -and (Confirm-Action "Restart required. NOW?")) {
Restart-Computer -Force
} elseif ($result.RestartNeeded) {
Write-Log "Defer reboot; manual after." 'WARN'
}
}
'EnsureWsb' {
$desired = Get-DesiredWsbContent
New-Item $ConfigDir -ItemType Directory -Force | Out-Null
$evasionPath = Join-Path $ConfigDir 'evade.ps1'
$desired.ScriptContent | Out-File -FilePath $evasionPath -Encoding UTF8 -Force
if (-not (Test-Path $ConfigPath) -or -not (Compare-FileContent -Path $ConfigPath -Desired $desired.WsbContent)) {
$backup = "$ConfigPath.bak.$((Get-Date).ToString('yyyyMMdd-HHmmss'))"
if (Test-Path $ConfigPath -and (Confirm-Action "Backup existing WSB?")) {
Copy-Item $ConfigPath $backup -Force
Write-Log "Existing WSB backed up to $backup." 'INFO'
}
$desired.WsbContent | Out-File -FilePath $ConfigPath -Encoding UTF8 -Force
}
}
'EnsureShortcut' {
if ($NoShortcut) {
return
}
$shell = New-Object -ComObject WScript.Shell
$lnk = $shell.CreateShortcut($ShortcutLnk)
$lnk.TargetPath = $ConfigPath
$lnk.IconLocation = "$env:SystemRoot\System32\imageres.dll,209"
$lnk.Description = 'Narrative-fused Sandbox: AdminMax + Evasion Probes'
$lnk.Save()
}
}
} $Step
New-Item -Path $stepKey -Force | Out-Null
$now = Get-Date
Set-ItemProperty -Path $stepKey -Name 'Status' -Value 'Completed'
Set-ItemProperty -Path $stepKey -Name 'CompletedAt' -Value $now.ToString('yyyy-MM-dd HH:mm:ss')
Set-ItemProperty -Path $stepKey -Name 'Timestamp' -Value $now.ToString('o')
Write-Log "Step $($Step.Name) success." 'SUCCESS'
} catch {
Write-Log "Step $($Step.Name) error: $($_.Exception.Message)" 'ERROR'
if ($Step.Undo) {
Write-Log "Attempting undo for $($Step.Name)." 'WARN'
try {
& $Step.Undo
Write-Log "Undo for $($Step.Name) success." 'INFO'
} catch {
Write-Log "Undo fail: $($_.Exception.Message). Manual: $($Step.Name) remediation." 'ERROR'
}
}
throw
}
} else {
Write-Log "Step $($Step.Name): -WhatIf skip." 'INFO'
}
$script:CurrentWeight += $Step.Weight / $TotalWeight * 100
Write-Progress -Activity "Sandbox Setup" -Status $Step.Name -PercentComplete $script:CurrentWeight
}
function Invoke-Verification {
param(
[switch]$ReExecute
)
Write-Output "Verification phase."
$hvPresent = $false
try {
$ci = Get-ComputerInfo -Property 'HyperVisorPresent'
$hvPresent = [bool]$ci.HyperVisorPresent
} catch {
}
if (-not $hvPresent) {
Write-Log "HyperVisor absent post-setup." 'ERROR'
exit 2
}
$failed = @()
foreach ($step in $Steps) {
$satisfied = & $step.SystemTest
$stepMarkerPath = Join-Path $StepsKey $step.Name
$marker = Test-Path $stepMarkerPath -and (Get-ItemProperty $stepMarkerPath -Name 'Status' -EA SilentlyContinue).Status -eq 'Completed'
if (-not ($satisfied -and $marker)) {
$failed += $step.Name
}
Write-Verbose "Verify $($step.Name): State=$satisfied, Marker=$marker"
}
if ($failed -and $ReExecute) {
Write-Log "Re-executing steps: $($failed -join ', ')." 'WARN'
foreach ($name in $failed) {
$stepToInvoke = $Steps | Where-Object { $_.Name -eq $name }
if ($stepToInvoke) {
try {
Invoke-Step -Step $stepToInvoke
} catch {
Write-Log "Re-execution failed for ${name}: $($_.Exception.Message)" 'ERROR'
}
}
}
return Invoke-Verification
}
if ($failed) {
Write-Log "Failed: $($failed -join ', '). Remediate: Re-run or manual (e.g., Disable-WindowsOptionalFeature for feature)." 'ERROR'
exit 2
}
$evasionPath = Join-Path $ConfigDir 'evade.ps1'
if (Test-Path $evasionPath) {
$previousValue = [Environment]::GetEnvironmentVariable('SANDBOX_VALIDATE', 'Process')
try {
[Environment]::SetEnvironmentVariable('SANDBOX_VALIDATE', '1', 'Process')
& { . $evasionPath } -ErrorAction SilentlyContinue | Out-Null
Write-Verbose 'Syntax OK'
} catch {
Write-Log "evade.ps1 invalid: $($_.Exception.Message)" 'ERROR'
exit 2
} finally {
[Environment]::SetEnvironmentVariable('SANDBOX_VALIDATE', $previousValue, 'Process')
}
} else {
Write-Log "evade.ps1 missing at $evasionPath." 'WARN'
}
if (Test-Path $ConfigPath) {
try {
$xml = [xml](Get-Content $ConfigPath -Raw)
$commandText = $xml.Configuration.LogonCommand.Command
if ($commandText) {
$match = [regex]::Match($commandText, '-File\s+"(?<Path>[^"]+)"')
if ($match.Success) {
$targetPath = $match.Groups['Path'].Value
if (-not (Test-Path $targetPath)) {
Write-Log "LogonCommand target missing: $targetPath" 'ERROR'
exit 2
}
}
}
} catch {
Write-Log "LogonCommand dry-run failure: $($_.Exception.Message)" 'ERROR'
exit 2
}
}
Write-Log "Verification complete." 'SUCCESS'
}
$Steps = @(
@{
Name = 'EnableFeature'
Weight = 100
SystemTest = { (Get-WindowsOptionalFeature -Online -FeatureName $FeatureName).State -eq 'Enabled' }
Undo = { Disable-WindowsOptionalFeature -Online -FeatureName $FeatureName -All }
},
@{
Name = 'EnsureWsb'
Weight = 100
SystemTest = {
$desired = Get-DesiredWsbContent
Test-Path $ConfigPath -and (Compare-FileContent -Path $ConfigPath -Desired $desired.WsbContent)
}
Undo = {
$resolved = Resolve-Path "$ConfigPath.bak.*" -ErrorAction SilentlyContinue
if ($resolved) {
$latest = $resolved | Sort-Object -Property Path | Select-Object -Last 1
Copy-Item $latest.Path $ConfigPath -Force
Write-Log "Undo restored configuration from $($latest.Path)." 'INFO'
} else {
Write-Log 'No backup; suggest manual restore from known good' 'WARN'
}
}
},
@{
Name = 'EnsureShortcut'
Weight = 100
SystemTest = { -not $NoShortcut -and (Test-Path $ShortcutLnk) }
Undo = {
if (Test-Path $ShortcutLnk) {
Remove-Item $ShortcutLnk -Force -ErrorAction SilentlyContinue
Write-Log "Removed shortcut $ShortcutLnk." 'INFO'
} else {
Write-Log 'Shortcut already absent; nothing to undo.' 'INFO'
}
}
}
)
New-Item -Path $RegistryBase -Force | Out-Null
New-Item -Path $StepsKey -Force | Out-Null
try {
Invoke-Preflight
Write-Progress -Activity "Sandbox Setup" -Status "Init" -PercentComplete 0
foreach ($step in $Steps) {
Invoke-Step -Step $step
}
Invoke-Verification -ReExecute
Write-Output "Narrative fusion complete: Launch via $ConfigPath or shortcut. Evasion active on boot."
Write-Log "Exit:0" 'SUCCESS'
exit 0
} catch {
Write-Log "Fatal: $($_.Exception.Message). Exit:1" 'ERROR'
Write-Error $_
exit 1
} finally {
Write-Progress -Activity "Sandbox Setup" -Completed
try {
Stop-Transcript
} catch {
}
}but now i've got this errors: |
|
@ib-bsb-br I've opened a new pull request, #4, to work on those changes. Once the pull request is ready, I'll request review from you. |
There was a problem hiding this comment.
💡 Codex Review
https://github.com/ib-bsb-br/codex-scratchpad/blob/90f17a81390248feae8d1409f4d13ba18178ae26/"b/C:\\Windows\\SysWOW64\\pwsh.ps1"#L485-L488
Respect NoShortcut during verification
When -NoShortcut is passed, the shortcut creation block in Invoke-Step immediately returns but the step is still marked as completed afterward. The SystemTest for that step is -not $NoShortcut -and (Test-Path $ShortcutLnk), which evaluates to false whenever -NoShortcut is true. During Invoke-Verification, the step therefore always appears failed (satisfied = $false while the completion marker exists) and the script exits with code 2 even though the user explicitly opted out of creating a shortcut. This makes the -NoShortcut switch unusable. The check should treat the opt-out as success or skip adding the step entirely.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
Testing
https://chatgpt.com/codex/tasks/task_b_690654c59610832da1bea023fe40cec0
Summary by Sourcery
Bug Fixes: