This folder contains the Azure Functions backend for queueing VM assessment jobs, running the PowerShell analyzer, and serving result metadata and artifact links.
- Accepts HTTP requests to create and inspect assessment jobs.
- Stores job state in Azure Table Storage.
- Uploads JSON, CSV, HTML, log, and manifest artifacts to Blob Storage.
- Runs the VM assessment PowerShell script through a queue-triggered worker.
- Caches VM pricing in Table Storage with queue-based targeted refresh on cache miss.
- Caches regional VM SKU/spec catalogs in Table Storage with queue-based refresh and timer-driven bulk refresh.
submitAssessmentatPOST /api/assessmentsCreates a VM assessment job and writes a message to the assessment queue.listAssessmentsatGET /api/assessmentsLists recent jobs, optionally filtered byclientId.getAssessmentStatusatGET /api/assessments/{jobId}Returns job status plus manifest data when available.getAssessmentResultsatGET /api/assessments/{jobId}/resultsReturns the job record, manifest, and artifact links.getAssessmentArtifactatGET /api/assessments/{jobId}/artifacts/{artifactName}Returns metadata and a direct link for one artifact. Valid artifact names arejson,csv,html,log, andmanifest.getRuntimeContextatGET /api/contextReturns configured tenant, default client, default subscriptions, and storage target metadata.
runAssessmentJobQueue-triggered worker that runs the PowerShell VM analyzer and persists artifacts.refreshPricingCacheQueue-triggered worker for one pricing cache key.refreshVmSkuCatalogQueue-triggered worker for one region/family VM SKU catalog refresh.scheduleVmSkuCatalogRefreshTimer-triggered worker that enqueues bulk VM SKU catalog refresh jobs for configured target regions and families.
Endpoint:
POST /api/assessments
Body:
{
"tool": "vm",
"clientId": "contoso-prod",
"targetTenantId": "00000000-0000-0000-0000-000000000000",
"subscriptionIds": [
"11111111-1111-1111-1111-111111111111"
],
"vmNames": [
"vm-app-01",
"vm-app-02"
],
"daysToInspect": 14,
"configBlobPath": "configs/vm/custom-config.jsonc",
"refreshAdvisor": false,
"outputPrefix": "vm-analysis-api",
"requestedBy": "portal"
}Response:
{
"jobId": "job-1776880000000-abcd1234",
"clientId": "contoso-prod",
"status": "Queued",
"requestedAt": "2026-04-22T20:00:00.000Z",
"targetTenantId": "00000000-0000-0000-0000-000000000000",
"subscriptionIds": [
"11111111-1111-1111-1111-111111111111"
],
"message": "Queued for execution"
}Examples:
GET /api/assessmentsGET /api/assessments?clientId=contoso-prod&limit=10
GET /api/assessments/{jobId}returns the current job state and manifest if one exists.GET /api/assessments/{jobId}/resultsreturns the completed result envelope with artifact links.GET /api/assessments/{jobId}/artifacts/htmlreturns the HTML artifact link and metadata only.
All HTTP functions use authLevel: function.
When deployed to Azure, call them with either:
?code=<function-key>on the URLx-functions-key: <function-key>in the request headers
Examples:
$baseUrl = "https://<your-function-app>.azurewebsites.net/api"
$functionKey = "<function-key>"
Invoke-RestMethod `
-Method Post `
-Uri "$baseUrl/assessments?code=$functionKey" `
-ContentType "application/json" `
-Body (@{
tool = "vm"
clientId = "contoso-prod"
subscriptionIds = @("11111111-1111-1111-1111-111111111111")
daysToInspect = 14
requestedBy = "manual-test"
} | ConvertTo-Json)Invoke-RestMethod `
-Method Get `
-Uri "$baseUrl/assessments/$jobId/results?code=$functionKey"Use local.settings.template.json as the local baseline and map the same values to Function App settings in Azure.
ASSESSMENT_PROVIDER_TENANT_IDASSESSMENT_LOCATIONASSESSMENT_DEFAULT_CLIENT_IDASSESSMENT_DEFAULT_SUBSCRIPTION_IDSASSESSMENT_STORAGE_SUBSCRIPTION_IDASSESSMENT_STORAGE_RESOURCE_GROUPASSESSMENT_STORAGE_ACCOUNT_NAME
AzureWebJobsStorageASSESSMENT_QUEUE_NAMEASSESSMENT_TABLE_NAMEASSESSMENT_RESULTS_CONTAINERASSESSMENT_CONFIG_CONTAINERASSESSMENT_REFERENCE_CONTAINER
ASSESSMENT_PRICING_TABLE_NAMEASSESSMENT_PRICING_REFRESH_QUEUE_NAMEASSESSMENT_PRICING_CACHE_MAX_AGE_MINUTESASSESSMENT_PRICING_LOOKUP_HELPER_PATH
ASSESSMENT_VM_SKU_TABLE_NAMEASSESSMENT_VM_SKU_REFRESH_QUEUE_NAMEASSESSMENT_VM_SKU_CACHE_MAX_AGE_MINUTESASSESSMENT_VM_SKU_REFRESH_SCHEDULEASSESSMENT_VM_SKU_TARGET_REGIONSASSESSMENT_VM_SKU_TARGET_FAMILIESASSESSMENT_VM_SKU_LOOKUP_HELPER_PATH
ASSESSMENT_SCRIPT_PATHASSESSMENT_DEFAULT_CONFIG_PATHASSESSMENT_OUTPUT_PREFIX
- Copy local.settings.template.json to
local.settings.json. - Fill in the tenant, subscription, and storage metadata placeholders.
- Install dependencies with
npm install. - Build with
npm run build. - Start Azurite with
npm run start:storage. - Start the Functions host with
npm start.
Local notes:
- The pricing cache and VM SKU catalog cache both use Table Storage and queue writes, so Azurite must be running when
AzureWebJobsStorage=UseDevelopmentStorage=true. - Azurite-generated files are intentionally ignored from git.
- The local launcher scripts resolve installed entry points and prepend the active Node.js path to avoid Windows shell PATH issues.
- The build step syncs analyzer assets into functions/assets/azure-vm-analysis/azure-vm-assessment.ps1 so the deployed package remains self-contained.
- The synced
functions/assets/azure-vm-analysisdirectory is generated build output and is intentionally ignored from git. Rebuild or runnpm run sync:assetsafter changing the source analyzer under../azure-vm-analysis.
- functions/scripts/start-azurite.js
Starts Azurite in functions/.azurite with
--skipApiVersionCheck. - functions/scripts/start-functions-host.js
Starts Azure Functions Core Tools with the current Node installation added to
PATH. - functions/scripts/sync-analyzer-assets.js Copies the PowerShell analyzer and related assets into the deployable Functions package.
- functions/src/scripts/pricingLookupCli.ts Cache-aware pricing lookup used by the PowerShell analyzer.
- functions/src/scripts/vmSkuCatalogLookupCli.ts Cache-aware VM SKU/spec catalog lookup used by the PowerShell analyzer.
submitAssessmentvalidates the request and creates a job row.- The job ID is written to the assessment queue.
runAssessmentJobdequeues the job and runs the PowerShell analyzer.- The analyzer uses the Functions helper CLIs for pricing and VM SKU catalog lookups when available.
- Cache misses do a live lookup, write through to table storage, and enqueue a targeted refresh job.
- Artifacts are uploaded to Blob Storage and the job row is updated to
CompletedorFailed.
- The current analyzer still uses the PowerShell VM assessment engine at azure-vm-analysis/azure-vm-assessment.ps1.
configBlobPathlets the API request point at a blob-backed config file instead of requiring inline analyzer settings.- Artifact endpoints generate SAS links when the storage connection string includes a shared key. Otherwise they fall back to direct blob URL shape plus blob metadata.
- The timer-driven VM SKU catalog refresh does nothing until
ASSESSMENT_VM_SKU_TARGET_REGIONSis populated.