Skip to content

Add script to download AzureRescueToolkit - #132

Open
Ajeet Singh (AjeetSingh-1) wants to merge 2 commits into
Azure:mainfrom
AjeetSingh-1:main
Open

Add script to download AzureRescueToolkit#132
Ajeet Singh (AjeetSingh-1) wants to merge 2 commits into
Azure:mainfrom
AjeetSingh-1:main

Conversation

@AjeetSingh-1

Copy link
Copy Markdown

Created a tool that help troubleshooting Azure VM no-boot issues.
This script downloads the tool inside the rescue VM

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a tool to troubleshooting Azure VM no-boot issues.
This script downloads the tool inside the rescue VM

@AjeetSingh-1 Ajeet Singh (AjeetSingh-1) left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@AjeetSingh-1

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Added a new script for downloading Azure Rescue Toolkit to assist in troubleshooting boot issues.

@glimoli Gabriela Limoli (glimoli) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VMRepair Script Testing — Automated Review

Script: src/windows/win-download-azurerescuetoolkit.ps1
Test Date: 2026-08-17
Overall Score: 52 / 100 — D
VM Execution: 6/6 PASS ✅ (quorum met — script ran without error on all configurations)
Merge Recommendation: ⛔ REQUEST CHANGES — DO NOT MERGE


This PR cannot be merged in its current form. While the script executes successfully in isolation, it introduces critical supply chain security risks and violates required repository conventions.


VM Execution Results

# Configuration Result Duration Exit Code
1 Windows Server 2019 / Standard_D2s_v3 ✅ PASS 4m 23s 0
2 Windows Server 2022 / Standard_D2s_v3 ✅ PASS 4m 11s 0
3 Windows Server 2019 / Standard_DS2_v2 ✅ PASS 4m 08s 0
4 Windows Server 2022 / Standard_DS2_v2 ✅ PASS 4m 19s 0
5 Windows Server 2019 / Standard_A2_v2 ✅ PASS 4m 31s 0
6 Windows Server 2022 / Standard_A2_v2 ✅ PASS 4m 17s 0

Quorum: 6/6 PASS — script runs and the file is downloaded successfully.
Post-execution: C:\Temp\AzureRescueToolkit.ps1 confirmed present after each run.


Score Breakdown

Dimension Score Points
Code Quality (PSScriptAnalyzer) A+ (100/100) 15.0
Header Documentation F (0/100) 0.0
VM Execution Pass Rate 100% 20.0
Telemetry Coverage 0% 0.0
Security 0% — 3 findings 0.0
Overall 52 / 100 — D

🔴 BLOCKING Issues

[SEC-001] Supply Chain Security Risk — Personal Repository Download Source

Severity: CRITICAL | Line 8

-Uri "https://raw.githubusercontent.com/AjeetSingh-1/vm-repair-tool/main/AzureRescueToolkit.ps1"

AjeetSingh-1/vm-repair-tool is a personal GitHub account, not an official Azure or Microsoft-controlled repository. This content:

  • Can be modified, deleted, or overwritten at any time without Microsoft governance or code review
  • Has no security controls, no CODEOWNERS, no required PR review
  • If the account is compromised, every future rescue VM that runs this script will download and execute the attacker's payload

This is the single most critical issue. No rescue VM script may download and execute content from a personal account on customer production VMs.

Required action: Host AzureRescueToolkit in a repository under the Azure/ GitHub organization, or bundle the toolkit directly within repair-script-library. Personal forks and personal accounts are not an acceptable source for production rescue VM content.


[SEC-002] No Integrity Verification After Download

Severity: CRITICAL | Lines 11–17

if (Test-Path "C:\Temp\AzureRescueToolkit.ps1")
{
    Log-Info "Download successful"
    exit $STATUS_SUCCESS
}

The script verifies only that the file exists — it does not verify its contents. A MITM attack, CDN compromise, or malicious push to the source repository would deliver an arbitrary payload that passes this check.

Required action: Pin a SHA-256 hash and verify after download:

$expectedHash = "REPLACE_WITH_AUTHORITATIVE_SHA256_HASH"
$actualHash = (Get-FileHash -Path "$env:TEMP\AzureRescueToolkit.ps1" -Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) {
    Log-Error "Integrity check FAILED. File may be corrupted or tampered. Expected: $expectedHash"
    return $STATUS_ERROR
}

[CONV-001] Missing Required Script Header

Severity: BLOCKING (Convention Violation)

All scripts in repair-script-library must include a .SYNOPSIS / .DESCRIPTION / .RESOLVES / .OS / .AUTHOR PowerShell comment-based help block, as required by adding_new_scripts.md. This script has no header at all.

Required action: Add a complete header before the script body:

<#
.SYNOPSIS
    Downloads AzureRescueToolkit to the rescue VM for troubleshooting no-boot scenarios.

.DESCRIPTION
    Fetches AzureRescueToolkit.ps1 from an official Microsoft-controlled source and
    places it at $env:TEMP for use during rescue VM operations.

.RESOLVES
    Azure VM no-boot scenarios requiring the AzureRescueToolkit diagnostic utility.

.OS
    Windows

.AUTHOR
    AjeetSingh-1
#>

🟠 HIGH Severity Issues

[ERR-001] No Error Handling on Invoke-WebRequest

Invoke-WebRequest is not wrapped in a try-catch block. Any network failure, DNS error, HTTP 4xx/5xx, or TLS error will throw an unhandled terminating exception rather than a clean return $STATUS_ERROR with a diagnostic message.

# Required pattern:
try {
    Invoke-WebRequest -Uri $downloadUri -OutFile "$env:TEMP\AzureRescueToolkit.ps1" `
        -UseBasicParsing -TimeoutSec 120 -ErrorAction Stop
} catch {
    Log-Error "Download failed: $_"
    return $STATUS_ERROR
}

[TEL-001] No Telemetry Instrumentation

No Log-Metric calls or structured telemetry. Missing signals: HTTP response code, download size, execution duration, OS version of rescue VM. Without this data, diagnosing failures at scale via Application Insights is not possible.


🟡 Non-Blocking Issues

# Line Finding Fix
C-01 2 Forward slash in $PSScriptRoot/common (Windows uses backslash) $PSScriptRoot\common\setup\init.ps1
C-02 7 Hardcoded C:\Temp — environment-specific path Use $env:TEMP
C-03 15, 20 exit $STATUS_SUCCESS/ERROR — VMRepair convention is return Replace exit with return
C-04 8 Missing -UseBasicParsing — required on Server Core (no IE engine) Add -UseBasicParsing
C-05 8 Missing -TimeoutSec — can hang indefinitely on degraded networks Add -TimeoutSec 120

Path Forward

To bring this PR to a mergeable state:

  1. [Required] Move AzureRescueToolkit to a repository under the Azure/ GitHub organization — OR bundle the toolkit directly in repair-script-library
  2. [Required] Add SHA-256 hash verification after download, with the hash pinned in the script
  3. [Required] Add the required script header block (.SYNOPSIS, .DESCRIPTION, .RESOLVES, .OS, .AUTHOR)
  4. [Required] Wrap Invoke-WebRequest in try-catch with proper $STATUS_ERROR exit paths
  5. [Required] Add telemetry instrumentation (Log-Metric calls)
  6. [Nice-to-have] Replace exit with return, use $env:TEMP, add -UseBasicParsing, -TimeoutSec 120, fix path separator

@glimoli Gabriela Limoli (glimoli) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VMRepair Script Testing — Automated Review

Script: src/windows/win-download-azurerescuetoolkit.ps1
Test Date: 2026-08-17
Overall Score: 52 / 100 — D
VM Execution: 6/6 PASS ✅ (quorum met — script ran without error on all configurations)
Merge Recommendation: ⛔ REQUEST CHANGES — DO NOT MERGE


This PR cannot be merged in its current form. While the script executes successfully in isolation, it introduces critical supply chain security risks and violates required repository conventions.


VM Execution Results

# Configuration Result Duration Exit Code
1 Windows Server 2019 / Standard_D2s_v3 ✅ PASS 4m 23s 0
2 Windows Server 2022 / Standard_D2s_v3 ✅ PASS 4m 11s 0
3 Windows Server 2019 / Standard_DS2_v2 ✅ PASS 4m 08s 0
4 Windows Server 2022 / Standard_DS2_v2 ✅ PASS 4m 19s 0
5 Windows Server 2019 / Standard_A2_v2 ✅ PASS 4m 31s 0
6 Windows Server 2022 / Standard_A2_v2 ✅ PASS 4m 17s 0

Quorum: 6/6 PASS — script runs and the file is downloaded successfully.
Post-execution: C:\Temp\AzureRescueToolkit.ps1 confirmed present after each run.


Score Breakdown

Dimension Score Points
Code Quality (PSScriptAnalyzer) A+ (100/100) 15.0
Header Documentation F (0/100) 0.0
VM Execution Pass Rate 100% 20.0
Telemetry Coverage 0% 0.0
Security 0% — 3 findings 0.0
Overall 52 / 100 — D

🔴 BLOCKING Issues

[SEC-001] Supply Chain Security Risk — Personal Repository Download Source

Severity: CRITICAL | Line 8

-Uri "https://raw.githubusercontent.com/AjeetSingh-1/vm-repair-tool/main/AzureRescueToolkit.ps1"

AjeetSingh-1/vm-repair-tool is a personal GitHub account, not an official Azure or Microsoft-controlled repository. This content:

  • Can be modified, deleted, or overwritten at any time without Microsoft governance or code review
  • Has no security controls, no CODEOWNERS, no required PR review
  • If the account is compromised, every future rescue VM that runs this script will download and execute the attacker's payload

This is the single most critical issue. No rescue VM script may download and execute content from a personal account on customer production VMs.

Required action: Host AzureRescueToolkit in a repository under the Azure/ GitHub organization, or bundle the toolkit directly within repair-script-library. Personal forks and personal accounts are not an acceptable source for production rescue VM content.


[SEC-002] No Integrity Verification After Download

Severity: CRITICAL | Lines 11–17

if (Test-Path "C:\Temp\AzureRescueToolkit.ps1")
{
    Log-Info "Download successful"
    exit $STATUS_SUCCESS
}

The script verifies only that the file exists — it does not verify its contents. A MITM attack, CDN compromise, or malicious push to the source repository would deliver an arbitrary payload that passes this check.

Required action: Pin a SHA-256 hash and verify after download:

$expectedHash = "REPLACE_WITH_AUTHORITATIVE_SHA256_HASH"
$actualHash = (Get-FileHash -Path "$env:TEMP\AzureRescueToolkit.ps1" -Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) {
    Log-Error "Integrity check FAILED. File may be corrupted or tampered. Expected: $expectedHash"
    return $STATUS_ERROR
}

[CONV-001] Missing Required Script Header

Severity: BLOCKING (Convention Violation)

All scripts in repair-script-library must include a .SYNOPSIS / .DESCRIPTION / .RESOLVES / .OS / .AUTHOR PowerShell comment-based help block, as required by adding_new_scripts.md. This script has no header at all.

Required action: Add a complete header before the script body:

<#
.SYNOPSIS
    Downloads AzureRescueToolkit to the rescue VM for troubleshooting no-boot scenarios.

.DESCRIPTION
    Fetches AzureRescueToolkit.ps1 from an official Microsoft-controlled source and
    places it at $env:TEMP for use during rescue VM operations.

.RESOLVES
    Azure VM no-boot scenarios requiring the AzureRescueToolkit diagnostic utility.

.OS
    Windows

.AUTHOR
    AjeetSingh-1
#>

🟠 HIGH Severity Issues

[ERR-001] No Error Handling on Invoke-WebRequest

Invoke-WebRequest is not wrapped in a try-catch block. Any network failure, DNS error, HTTP 4xx/5xx, or TLS error will throw an unhandled terminating exception rather than a clean return $STATUS_ERROR with a diagnostic message.

# Required pattern:
try {
    Invoke-WebRequest -Uri $downloadUri -OutFile "$env:TEMP\AzureRescueToolkit.ps1" `
        -UseBasicParsing -TimeoutSec 120 -ErrorAction Stop
} catch {
    Log-Error "Download failed: $_"
    return $STATUS_ERROR
}

[TEL-001] No Telemetry Instrumentation

No Log-Metric calls or structured telemetry. Missing signals: HTTP response code, download size, execution duration, OS version of rescue VM. Without this data, diagnosing failures at scale via Application Insights is not possible.


🟡 Non-Blocking Issues

# Line Finding Fix
C-01 2 Forward slash in $PSScriptRoot/common (Windows uses backslash) $PSScriptRoot\common\setup\init.ps1
C-02 7 Hardcoded C:\Temp — environment-specific path Use $env:TEMP
C-03 15, 20 exit $STATUS_SUCCESS/ERROR — VMRepair convention is return Replace exit with return
C-04 8 Missing -UseBasicParsing — required on Server Core (no IE engine) Add -UseBasicParsing
C-05 8 Missing -TimeoutSec — can hang indefinitely on degraded networks Add -TimeoutSec 120

Path Forward

To bring this PR to a mergeable state:

  1. [Required] Move AzureRescueToolkit to a repository under the Azure/ GitHub organization — OR bundle the toolkit directly in repair-script-library
  2. [Required] Add SHA-256 hash verification after download, with the hash pinned in the script
  3. [Required] Add the required script header block (.SYNOPSIS, .DESCRIPTION, .RESOLVES, .OS, .AUTHOR)
  4. [Required] Wrap Invoke-WebRequest in try-catch with proper $STATUS_ERROR exit paths
  5. [Required] Add telemetry instrumentation (Log-Metric calls)
  6. [Nice-to-have] Replace exit with return, use $env:TEMP, add -UseBasicParsing, -TimeoutSec 120, fix path separator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants