Add script to download AzureRescueToolkit - #132
Add script to download AzureRescueToolkit#132Ajeet Singh (AjeetSingh-1) wants to merge 2 commits into
Conversation
Ajeet Singh (AjeetSingh-1)
left a comment
There was a problem hiding this comment.
Created a tool to troubleshooting Azure VM no-boot issues.
This script downloads the tool inside the rescue VM
|
@microsoft-github-policy-service agree |
Added a new script for downloading Azure Rescue Toolkit to assist in troubleshooting boot issues.
Gabriela Limoli (glimoli)
left a comment
There was a problem hiding this comment.
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:
- [Required] Move
AzureRescueToolkitto a repository under theAzure/GitHub organization — OR bundle the toolkit directly inrepair-script-library - [Required] Add SHA-256 hash verification after download, with the hash pinned in the script
- [Required] Add the required script header block (
.SYNOPSIS,.DESCRIPTION,.RESOLVES,.OS,.AUTHOR) - [Required] Wrap
Invoke-WebRequestintry-catchwith proper$STATUS_ERRORexit paths - [Required] Add telemetry instrumentation (
Log-Metriccalls) - [Nice-to-have] Replace
exitwithreturn, use$env:TEMP, add-UseBasicParsing,-TimeoutSec 120, fix path separator
Gabriela Limoli (glimoli)
left a comment
There was a problem hiding this comment.
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:
- [Required] Move
AzureRescueToolkitto a repository under theAzure/GitHub organization — OR bundle the toolkit directly inrepair-script-library - [Required] Add SHA-256 hash verification after download, with the hash pinned in the script
- [Required] Add the required script header block (
.SYNOPSIS,.DESCRIPTION,.RESOLVES,.OS,.AUTHOR) - [Required] Wrap
Invoke-WebRequestintry-catchwith proper$STATUS_ERRORexit paths - [Required] Add telemetry instrumentation (
Log-Metriccalls) - [Nice-to-have] Replace
exitwithreturn, use$env:TEMP, add-UseBasicParsing,-TimeoutSec 120, fix path separator
Created a tool that help troubleshooting Azure VM no-boot issues.
This script downloads the tool inside the rescue VM