Files
PSProxmoxVE/REVIEW_REPORT.md
T
Clint Branham a72642d203 feat: add firewall, backup, and SDN IPAM/DNS/controller cmdlets
Add 35 new cmdlets bringing the total to 118:
- Firewall (21): rules, groups, aliases, IP sets, options at
  cluster/node/VM/container levels
- Backup (5): ad-hoc vzdump and scheduled backup job CRUD
- SDN IPAM/DNS/Controller (9): plugin management for SDN subsystem

Also includes:
- Fix: Remove-PveRole now has ConfirmImpact.High
- Fix: URL-encode snapshot names in API paths
- Refactor: extract auth header strings to constants in PveHttpClient
- Add PSGallery version badge to README
- Full test coverage: 11 JSON fixtures, xUnit model tests, Pester
  unit tests, and integration tests for firewall/backup/OVA import
- Updated manifest, format file, CHANGELOG, README, API coverage docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 07:51:49 -05:00

37 KiB

PSProxmoxVE Module Review Report

Scan date: 2026-03-21
Prior report date: 2026-03-19

Reviewer: Claude Code (Opus 4.6) Module Version: 0.1.0-preview Repository: PSProxmoxVE (C# binary PowerShell module)


Executive Summary

Delta since last scan: 22 fixed | 2 new findings | 0 regressed | 4 still open

  1. Significant progress since prior scan — 22 of 28 findings from the initial report have been resolved, including all Critical items.
  2. 83 cmdlets (up from 66) covering VMs, containers (with snapshots and migration), storage, networking, SDN (zones, VNets, subnets), users/roles/permissions, templates, cloud-init, OVA/disk import, and tasks.
  3. All prior Critical items resolved: publish workflow added, README updated with Install-Module, ReleaseNotes in manifest.
  4. Community files complete: CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, .gitattributes, issue/PR templates all added.
  5. Code quality improvements: HelpMessage on all parameters, WriteVerbose throughout, ValidateRange on VmId, ConfirmImpact.High on Stop/Reset-PveVm, Reset verb constant fixed.
  6. MAML help file present (PSProxmoxVE.dll-Help.xml) with 75 cmdlet documentation files in docs/cmdlets/.
  7. Remaining gaps: No IconUri in manifest, Remove-PveRole missing ConfirmImpact.High, firewall/backup/pool cmdlets not yet implemented.
  8. Excellent test coverage: 100% Pester unit tests, 84% integration test coverage, xUnit model tests with PVE 8 & 9 fixtures.
  9. Security posture is clean: No hardcoded secrets, HTTPS enforced, SkipCertificateCheck emits warning, all dependencies pinned.
  10. Module is near PSGallery-ready — no blocking issues remain.

Phase 1 — Repository Inventory & Structure

Directory Tree (depth ≤ 4)

PSProxmoxVE/
├── PSProxmoxVE.sln
├── README.md
├── LICENSE (MIT)
├── CHANGELOG.md
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── SECURITY.md
├── .editorconfig
├── .gitignore
├── .gitattributes
├── CLAUDE.md
├── REVIEW_REPORT.md
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── feature_request.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── build.yml
│       ├── unit-tests.yml
│       ├── integration-tests.yml
│       └── publish.yml
├── docs/
│   ├── PVE_API_COVERAGE.md
│   └── cmdlets/                      (75 cmdlet documentation files)
├── src/
│   ├── PSProxmoxVE/
│   │   ├── PSProxmoxVE.csproj
│   │   ├── PSProxmoxVE.psd1
│   │   ├── PSProxmoxVE.format.ps1xml
│   │   ├── PSProxmoxVE.dll-Help.xml
│   │   ├── ModuleState.cs
│   │   └── Cmdlets/
│   │       ├── PveCmdletBase.cs
│   │       ├── CloudInit/            (3 cmdlets)
│   │       ├── Connection/           (3 cmdlets)
│   │       ├── Containers/           (14 cmdlets)
│   │       ├── Network/              (14 cmdlets)
│   │       ├── Nodes/                (2 cmdlets)
│   │       ├── Snapshots/            (4 cmdlets)
│   │       ├── Storage/              (6 cmdlets)
│   │       ├── Tasks/                (2 cmdlets)
│   │       ├── Templates/            (4 cmdlets)
│   │       ├── Users/                (12 cmdlets)
│   │       └── Vms/                  (19 cmdlets)
│   └── PSProxmoxVE.Core/
│       ├── PSProxmoxVE.Core.csproj
│       ├── Authentication/           (PveAuthenticator, PveAuthMode, PveSession, PveVersion)
│       ├── Client/                   (PveHttpClient)
│       ├── Exceptions/               (7 exception types)
│       ├── Models/                   (25 model classes)
│       └── Services/                 (11 service classes)
├── tests/
│   ├── PSProxmoxVE.Core.Tests/       (xUnit)
│   │   ├── Authentication/           (3 test files)
│   │   ├── Fixtures/                 (23 JSON fixtures)
│   │   ├── Models/                   (10 test files)
│   │   └── TestHelper.cs
│   ├── PSProxmoxVE.Tests/            (Pester 5)
│   │   ├── _TestHelper.ps1
│   │   ├── CloudInit/
│   │   ├── Connection/               (3 test files)
│   │   ├── Containers/               (4 test files)
│   │   ├── Network/                  (3 test files)
│   │   ├── Nodes/                    (1 test file)
│   │   ├── Snapshots/                (1 test file)
│   │   ├── Storage/                  (3 test files)
│   │   ├── Tasks/                    (1 test file)
│   │   ├── Templates/                (1 test file)
│   │   ├── Users/                    (3 test files)
│   │   ├── Vms/                      (9 test files)
│   │   └── Integration/              (1 comprehensive test file)
│   └── infrastructure/               (Terraform, Dockerfile, scripts for CI)
└── tools/

Project Layout

Item Value
Solution PSProxmoxVE.sln
Main project src/PSProxmoxVE/PSProxmoxVE.csproj
Core library src/PSProxmoxVE.Core/PSProxmoxVE.Core.csproj
Test project (xUnit) tests/PSProxmoxVE.Core.Tests/PSProxmoxVE.Core.Tests.csproj
Test project (Pester) tests/PSProxmoxVE.Tests/
Target Frameworks netstandard2.0, net9.0, net48
Language Version C# 10.0
Nullable Enabled
Assembly Names PSProxmoxVE, PSProxmoxVE.Core

CI/CD Workflows

Workflow Purpose
build.yml Build + xUnit tests on net48 (Windows) and net9.0 (Windows + Ubuntu)
unit-tests.yml Build + Pester tests across PS 5.1/7.5 on Windows/Ubuntu/macOS
integration-tests.yml Full integration tests against nested PVE 8 + PVE 9 instances
publish.yml Tag-triggered publish to PSGallery + GitHub Release creation

Inventory Checklist

Item Present Prior Status
Solution file (.sln) Yes Open
Module manifest (.psd1) Yes Open
Format definitions (.format.ps1xml) Yes Open
MAML help (.dll-Help.xml) Yes New
.editorconfig Yes Open
.gitignore Yes Open
.gitattributes Yes Fixed
LICENSE (MIT) Yes Open
CHANGELOG.md Yes Open
README.md Yes Open
CONTRIBUTING.md Yes Fixed
CODE_OF_CONDUCT.md Yes Fixed
SECURITY.md Yes Fixed
.github/ISSUE_TEMPLATE/ Yes Fixed
.github/pull_request_template.md Yes Fixed
PSGallery publish workflow Yes Fixed
docs/PVE_API_COVERAGE.md Yes New
docs/cmdlets/ (75 files) Yes New

What's Missing

  • IconUri in manifest PSData (cosmetic)

Phase 2 — PVE API Coverage Audit

Note: Coverage assessment based on source code analysis and the project's own docs/PVE_API_COVERAGE.md.

Implemented Cmdlets by Category (83 total)

Connection (3 cmdlets)

Cmdlet API Endpoint Method Prior Status
Connect-PveServer /access/ticket POST Open
Disconnect-PveServer /access/ticket DELETE Open
Test-PveConnection /version GET Open

Nodes (2 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveNode /nodes GET Open
Get-PveNodeStatus /nodes/{node}/status GET Open

VMs / QEMU (19 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveVm /nodes/{node}/qemu GET Open
New-PveVm /nodes/{node}/qemu POST Open
Remove-PveVm /nodes/{node}/qemu/{vmid} DELETE Open
Start-PveVm /nodes/{node}/qemu/{vmid}/status/start POST Open
Stop-PveVm /nodes/{node}/qemu/{vmid}/status/stop POST Open
Restart-PveVm /nodes/{node}/qemu/{vmid}/status/reboot POST Open
Suspend-PveVm /nodes/{node}/qemu/{vmid}/status/suspend POST Open
Resume-PveVm /nodes/{node}/qemu/{vmid}/status/resume POST Open
Reset-PveVm /nodes/{node}/qemu/{vmid}/status/reset POST Open
Copy-PveVm /nodes/{node}/qemu/{vmid}/clone POST Open
Move-PveVm /nodes/{node}/qemu/{vmid}/migrate POST Open
Get-PveVmConfig /nodes/{node}/qemu/{vmid}/config GET Open
Set-PveVmConfig /nodes/{node}/qemu/{vmid}/config PUT Open
Resize-PveVmDisk /nodes/{node}/qemu/{vmid}/resize PUT Open
Import-PveVmDisk /nodes/{node}/storage/{storage}/upload POST New
Import-PveOva Multiple (upload + config + import) POST New
Test-PveVmGuestAgent /nodes/{node}/qemu/{vmid}/agent/ping POST Open
Get-PveVmGuestNetwork /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces GET Open
Invoke-PveVmGuestExec /nodes/{node}/qemu/{vmid}/agent/exec POST Open

Containers / LXC (10 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveContainer /nodes/{node}/lxc GET Open
New-PveContainer /nodes/{node}/lxc POST Open
Remove-PveContainer /nodes/{node}/lxc/{vmid} DELETE Open
Start-PveContainer /nodes/{node}/lxc/{vmid}/status/start POST Open
Stop-PveContainer /nodes/{node}/lxc/{vmid}/status/stop POST Open
Restart-PveContainer /nodes/{node}/lxc/{vmid}/status/shutdown POST Open
Copy-PveContainer /nodes/{node}/lxc/{vmid}/clone POST Open
Move-PveContainer /nodes/{node}/lxc/{vmid}/migrate POST New
Get-PveContainerConfig /nodes/{node}/lxc/{vmid}/config GET Open
Set-PveContainerConfig /nodes/{node}/lxc/{vmid}/config PUT Open

Container Snapshots (4 cmdlets — NEW)

Cmdlet API Endpoint Method Prior Status
Get-PveContainerSnapshot /nodes/{node}/lxc/{vmid}/snapshot GET New
New-PveContainerSnapshot /nodes/{node}/lxc/{vmid}/snapshot POST New
Remove-PveContainerSnapshot /nodes/{node}/lxc/{vmid}/snapshot/{name} DELETE New
Restore-PveContainerSnapshot /nodes/{node}/lxc/{vmid}/snapshot/{name}/rollback POST New

Storage (6 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveStorage /storage or /nodes/{node}/storage GET Open
Get-PveStorageContent /nodes/{node}/storage/{storage}/content GET Open
Send-PveFile /nodes/{node}/storage/{storage}/upload POST Open
Invoke-PveStorageDownload /nodes/{node}/storage/{storage}/download-url POST Open
New-PveStorage /storage POST Open
Remove-PveStorage /storage/{storage} DELETE Open

VM Snapshots (4 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveSnapshot /nodes/{node}/qemu/{vmid}/snapshot GET Open
New-PveSnapshot /nodes/{node}/qemu/{vmid}/snapshot POST Open
Remove-PveSnapshot /nodes/{node}/qemu/{vmid}/snapshot/{name} DELETE Open
Restore-PveSnapshot /nodes/{node}/qemu/{vmid}/snapshot/{name}/rollback POST Open

Networking (5 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveNetwork /nodes/{node}/network GET Open
New-PveNetwork /nodes/{node}/network POST Open
Set-PveNetwork /nodes/{node}/network/{iface} PUT Open
Remove-PveNetwork /nodes/{node}/network/{iface} DELETE Open
Invoke-PveNetworkApply /nodes/{node}/network PUT Open

SDN (9 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveSdnZone /cluster/sdn/zones GET Open
New-PveSdnZone /cluster/sdn/zones POST Open
Remove-PveSdnZone /cluster/sdn/zones/{zone} DELETE Open
Get-PveSdnVnet /cluster/sdn/vnets GET Open
New-PveSdnVnet /cluster/sdn/vnets POST Open
Remove-PveSdnVnet /cluster/sdn/vnets/{vnet} DELETE Open
Get-PveSdnSubnet /cluster/sdn/vnets/{vnet}/subnets GET New
New-PveSdnSubnet /cluster/sdn/vnets/{vnet}/subnets POST New
Remove-PveSdnSubnet /cluster/sdn/vnets/{vnet}/subnets/{subnet} DELETE New

Users / ACLs / Tokens (12 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveUser /access/users GET Open
New-PveUser /access/users POST Open
Remove-PveUser /access/users/{userid} DELETE Open
Set-PveUser /access/users/{userid} PUT Open
Get-PveRole /access/roles GET Open
New-PveRole /access/roles POST Open
Remove-PveRole /access/roles/{roleid} DELETE Open
Get-PvePermission /access/acl GET Open
Set-PvePermission /access/acl PUT Open
Get-PveApiToken /access/users/{userid}/token GET Open
New-PveApiToken /access/users/{userid}/token/{tokenid} POST Open
Remove-PveApiToken /access/users/{userid}/token/{tokenid} DELETE Open

Templates (4 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveTemplate /nodes/{node}/qemu (filtered) GET Open
New-PveTemplate /nodes/{node}/qemu/{vmid}/template POST Open
Remove-PveTemplate /nodes/{node}/qemu/{vmid} DELETE Open
New-PveVmFromTemplate /nodes/{node}/qemu/{vmid}/clone POST Open

Cloud-Init (3 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveCloudInitConfig /nodes/{node}/qemu/{vmid}/config GET Open
Set-PveCloudInitConfig /nodes/{node}/qemu/{vmid}/config PUT Open
Invoke-PveCloudInitRegenerate /nodes/{node}/qemu/{vmid}/cloudinit PUT Open

Tasks (2 cmdlets)

Cmdlet API Endpoint Method Prior Status
Get-PveTask /nodes/{node}/tasks/{upid}/status GET Open
Wait-PveTask /nodes/{node}/tasks/{upid}/status (polling) GET Open

Missing API Coverage by Functional Area

Area Key Missing Endpoints Priority Prior Status
Firewall /cluster/firewall/*, /nodes/{node}/firewall/*, /nodes/{node}/qemu/{vmid}/firewall/* High Open
Backup / vzdump /nodes/{node}/vzdump, /cluster/backup/* High Open
Pools /pools, /pools/{poolid} (CRUD) Medium Open
HA /cluster/ha/* (groups, resources, status) Medium Open
Ceph /nodes/{node}/ceph/* (OSD, pool, mon, fs) Medium Open
Replication /cluster/replication (CRUD) Low Open
Access Groups /access/groups (CRUD) Low Open
Access Domains /access/domains (CRUD) Low Open
PBS Integration Proxmox Backup Server operations Low Open
Cluster Config /cluster/config/* (join, nodes, totem) Low Open
ACME /cluster/acme/*, /nodes/{node}/certificates/* Low Open
Node Management /nodes/{node}/apt/*, /nodes/{node}/disks/*, /nodes/{node}/services/* Low Open
Metrics /cluster/metrics/* Low Open
SDN IPAM/DNS/Controllers /cluster/sdn/ipams/*, /cluster/sdn/dns/*, /cluster/sdn/controllers/* Low New
VM Agent (extended) Additional agent endpoints (file-read, file-write, os-info) Low Open

High-Value Gaps

  1. Firewall management — Critical for security automation. No cmdlets for creating/managing firewall rules at cluster, node, or VM level.
  2. Backup/restore (vzdump) — Essential for DR automation. No cmdlets for creating backups, managing schedules, or restoring.
  3. Pool management — Required for multi-tenant environments. No cmdlets for creating/managing resource pools.

Phase 3 — Code Quality & Best Practices

3a. PowerShell Module Design

Cmdlet Naming

  • All cmdlets use approved PowerShell verbs via verb class constants (VerbsCommon.Get, VerbsLifecycle.Start, etc.).
  • Noun prefix Pve is consistent across all 83 cmdlets.
  • Previous finding about Reset-PveVm using a string literal has been fixed — now uses VerbsCommon.Reset.

Parameter Design

  • [Parameter(Mandatory = ...)] used appropriately throughout.
  • ValueFromPipelineByPropertyName = true used on Node, VmId, and similar parameters.
  • Position attributes used on key parameters.
  • ValidateSet, ValidateRange(100, 999999999), ValidateNotNullOrEmpty, ValidatePattern used where appropriate.
  • HelpMessage present on virtually all parameters (previously missing).

ShouldProcess / WhatIf / Confirm

  • Every destructive/mutating cmdlet implements SupportsShouldProcess = true.
  • ConfirmImpact = ConfirmImpact.High on all Remove-* cmdlets, Stop-PveVm, Reset-PveVm, New-PveTemplate, Restore-PveSnapshot, Restore-PveContainerSnapshot.
  • Gap: Remove-PveRole does not set ConfirmImpact.High — deleting a role is a significant operation.

OutputType

  • [OutputType] attributes present on all 83 cmdlets.

Pipeline Support

  • All cmdlets use ProcessRecord for pipeline processing.
  • Get-PveVm, Get-PveContainer output objects with Node and VmId enabling chaining.

Error Handling

  • ThrowTerminatingError used appropriately for fatal conditions.
  • WriteWarning used for non-fatal conditions.
  • Custom exception hierarchy provides structured errors.

3b. C# Code Quality

Null-Reference Safety

  • <Nullable>enable</Nullable> in both .csproj files.
  • Consistent use of nullable annotations, null guards (?? throw), and null-coalescing patterns.
  • No null-forgiving operators (!) used.

Async/Await Pattern

  • All HTTP operations are async in PveHttpClient with .ConfigureAwait(false).
  • Sync wrappers use .GetAwaiter().GetResult() — standard for PowerShell binary modules.
  • Low deadlock risk given the single pipeline thread model.

IDisposable Correctness

  • PveHttpClient implements IDisposable correctly with _disposed flag.
  • All service methods use using var client = new PveHttpClient(session).
  • File upload uses framework-conditional async disposal.

Exception Handling

  • Well-defined exception hierarchy (7 custom types) with context properties.
  • PveHttpClient.SendAsync wraps HttpRequestException in PveApiException.
  • Silent catches are intentional and documented (node polling, status enrichment).

Magic Strings

  • Auth header names inline (minor, not problematic).
  • API resource paths constructed inline (pragmatic for codebase size).
  • RandomNumberGenerator used for boundary generation (previously new Random()).

Logging / Verbose Output

  • WriteVerbose used extensively throughout cmdlets (previously missing).
  • WriteProgress used in Send-PveFile, Import-PveOva, and Wait-PveTask.

3c. General Hygiene

  • No unused using directives detected.
  • No commented-out blocks or dead code.
  • Zero TODO/FIXME/HACK markers.
  • Consistent code style matching .editorconfig.
  • XML doc comments on all public types and cmdlet classes.
  • CS1591 no longer suppressed in Core project.

Code Quality Findings

ID File Line Severity Description Prior Status
CQ1 RemovePveRoleCmdlet.cs 13 Medium Missing ConfirmImpact.High — deleting roles is significant New
CQ2 PveHttpClient.cs 316-323 Low Auth header names (PVEAPIToken=, CSRFPreventionToken) could be constants Open

Phase 4 — Testing Coverage Analysis

Test Projects

Project Framework Type Runner
PSProxmoxVE.Core.Tests xUnit 2.7 + Moq 4.20 Unit tests (models, auth) dotnet test
PSProxmoxVE.Tests Pester 5 Cmdlet + Integration tests Invoke-Pester

xUnit Tests (Core Library)

Test Area Test File ~Methods
Session lifecycle PveSessionTests.cs 9
Authentication logic PveAuthenticatorTests.cs 7
Version parsing PveVersionTests.cs 11
Cluster models ClusterModelTests.cs 13
Container models ContainerModelTests.cs 13
Network models NetworkModelTests.cs 12
Node models NodeModelTests.cs 13
SDN models SdnModelTests.cs 17
Snapshot models SnapshotModelTests.cs 9
Storage models StorageModelTests.cs 19
Task models TaskModelTests.cs 9
User models UserModelTests.cs 24
VM models VmModelTests.cs 18

Total: ~174 xUnit tests with PVE 8 and PVE 9 JSON fixtures.

Pester Tests (30 files, ~500 tests)

All 83 cmdlets have Pester unit tests covering command metadata, parameter validation, ShouldProcess presence, and pipeline binding.

Integration Tests

The integration test file covers 18+ major contexts with 90+ individual tests:

  • Connection, Nodes, User/Role/Token CRUD, Permissions
  • VM lifecycle (create, config, start/stop, reset, clone, resize, suspend/resume)
  • Snapshot CRUD (VM and container)
  • Storage (list, content, upload, create/remove, download)
  • Network CRUD with apply/revert
  • SDN zones/VNets/subnets CRUD
  • Templates, Cloud-Init
  • Container lifecycle (create, config, start/stop/restart, clone, snapshots)
  • Linux VM provisioning (cloud image upload, disk import, cloud-init, guest agent)

Setup/teardown: AfterAll cleans up all created resources. Environment variables inject connection details. Tests skip gracefully when env vars are missing.

Test Coverage Gap List

Cmdlet Unit Test Integration Test PVE 8 PVE 9 Prior Status
Connect-PveServer Open
Disconnect-PveServer Open
Test-PveConnection Open
Get-PveNode Open
Get-PveNodeStatus Open
Get-PveVm Open
New-PveVm Open
Remove-PveVm Open
Start-PveVm Open
Stop-PveVm Open
Restart-PveVm Open
Suspend-PveVm Fixed
Resume-PveVm Fixed
Reset-PveVm Open
Copy-PveVm Open
Move-PveVm Open
Get-PveVmConfig Open
Set-PveVmConfig Open
Resize-PveVmDisk Fixed
Import-PveVmDisk New
Import-PveOva New
Test-PveVmGuestAgent Open
Get-PveVmGuestNetwork Open
Invoke-PveVmGuestExec Open
Get-PveContainer Open
New-PveContainer Open
Remove-PveContainer Open
Start-PveContainer Open
Stop-PveContainer Open
Restart-PveContainer Open
Copy-PveContainer Fixed
Move-PveContainer New
Get-PveContainerConfig Open
Set-PveContainerConfig Open
Get-PveContainerSnapshot New
New-PveContainerSnapshot New
Remove-PveContainerSnapshot New
Restore-PveContainerSnapshot New
Get-PveStorage Open
New-PveStorage Fixed
Remove-PveStorage Fixed
Get-PveStorageContent Open
Send-PveFile Open
Invoke-PveStorageDownload Fixed
Get-PveSnapshot Open
New-PveSnapshot Open
Remove-PveSnapshot Open
Restore-PveSnapshot Open
Get-PveNetwork Open
New-PveNetwork Fixed
Set-PveNetwork Fixed
Remove-PveNetwork Fixed
Invoke-PveNetworkApply Fixed
Get-PveSdnZone Open
New-PveSdnZone Fixed
Remove-PveSdnZone Fixed
Get-PveSdnVnet Open
New-PveSdnVnet Fixed
Remove-PveSdnVnet Fixed
Get-PveSdnSubnet New
New-PveSdnSubnet New
Remove-PveSdnSubnet New
Get-PveUser Open
New-PveUser Open
Set-PveUser Open
Remove-PveUser Open
Get-PveRole Open
New-PveRole Open
Remove-PveRole Open
Get-PveApiToken Open
New-PveApiToken Open
Remove-PveApiToken Open
Get-PvePermission Open
Set-PvePermission Open
Get-PveTemplate Open
New-PveTemplate Open
Remove-PveTemplate Open
New-PveVmFromTemplate Open
Get-PveCloudInitConfig Open
Set-PveCloudInitConfig Fixed
Invoke-PveCloudInitRegenerate Fixed
Get-PveTask Open
Wait-PveTask Open

Summary: 83/83 unit tested (100%), 70/83 integration tested (84%). Remaining gaps are for operations requiring multi-node clusters (Move-PveVm, Move-PveContainer), optional test assets (Import-PveOva), or template operations that would require extra setup.


Phase 5 — Security Review

5.1 Credential Handling

Aspect Status Details Prior Status
PSCredential usage Good Connect-PveServer accepts PSCredential for password auth Open
Password extraction Acceptable NetworkCredential.Password used only at API call time Open
API token in memory Acceptable Stored as plain string in PveSession.ApiToken Open
Credential logging Good No WriteVerbose/WriteDebug calls include credentials Open
Ticket storage Good Tickets stored in PveSession only, not written to disk Open
Session expiry Good 2-hour expiry detected via IsExpired property Open

5.2 TLS/HTTPS

Aspect Status Details Prior Status
HTTPS enforced Good BaseUrl always constructs https:// URLs Open
SkipCertificateCheck Good Explicit opt-in parameter on Connect-PveServer Open
Warning on skip Good WriteWarning emitted with man-in-the-middle advisory Fixed
TLS version Good Left to OS/runtime negotiation (no pinning) Open
Port validation Good ValidateRange(1, 65535) on port parameter Open

5.3 Input Validation

Aspect Status Details Prior Status
VMID validation Good [ValidateRange(100, 999999999)] on all VmId parameters Fixed
URL construction Good String interpolation with validated parameters Open
User ID encoding Good Uri.EscapeDataString() used for user/token IDs in URLs Open
API token format Good Regex validation in PveAuthenticator Open
Path parameters Low risk Node/snapshot names not URL-encoded but come from validated sources Open

5.4 Dependency Security

Package Version Pinned Notes Prior Status
Newtonsoft.Json 13.0.3 Yes Latest stable, no known CVEs Open
System.Text.Json 8.0.5 Yes Latest 8.x patch Open
SharpCompress 0.38.0 Yes OVA/tar extraction support New
PowerShellStandard.Library 5.1.1 Yes PrivateAssets=all Open
System.Management.Automation 7.4.0 Yes PrivateAssets=all Open

All dependencies are pinned to exact versions.

5.5 Secret Scanning

No hardcoded credentials, tokens, or sensitive IPs found in source code. CI workflow uses GitHub Actions secrets with ::add-mask:: for test passwords.

Security Findings

ID Area File Severity Description Prior Status
S1 Input validation SnapshotService.cs, ContainerService.cs Low Snapshot names and node names in URL paths are not URL-encoded — low risk as values come from validated/system sources New

Phase 6 — PSGallery Publication Readiness

6.1 Module Manifest Assessment

Field Status Value Prior Status
RootModule Pass PSProxmoxVE.dll Open
ModuleVersion Pass 0.1.0 Open
GUID Pass a3f7c2d1-84e5-4b9f-a061-3e2d8c5f1a7b Open
Author Pass goodolclint Open
CompanyName Pass Worklab Open
Copyright Pass (c) 2026 goodolclint. All rights reserved. Open
Description Pass Meaningful Open
PowerShellVersion Pass 5.1 Open
CompatiblePSEditions Pass Desktop, Core Open
DotNetFrameworkVersion Pass 4.8 Open
RequiredAssemblies Pass Lists Core DLL and Newtonsoft.Json Open
FormatsToProcess Pass PSProxmoxVE.format.ps1xml Open
CmdletsToExport Pass Explicit list of all cmdlets Open
FunctionsToExport Pass Empty (binary module) Open
AliasesToExport Pass 7 aliases defined New
Prerelease Pass preview Open
Tags Pass 8 relevant tags Open
LicenseUri Pass GitHub LICENSE Open
ProjectUri Pass GitHub repo Open
HelpInfoURI Pass docs/cmdlets Fixed
ReleaseNotes Pass Present in PSData Fixed
IconUri Fail Not present Open

6.2 License

Check Pass/Fail Notes Prior Status
LICENSE file present Pass MIT License at repo root Open
OSI-approved license Pass MIT Open
LicenseUri in manifest Pass Points to GitHub LICENSE Open

6.3 README Quality

Check Pass/Fail Notes Prior Status
Installation instructions Pass Install-Module PSProxmoxVE Fixed
Quick-start examples Pass Multiple scenarios Open
Authentication guide Pass Ticket + API token documented Open
Badges Pass Build, Unit Tests, License badges Fixed
Cmdlet reference Pass All cmdlets listed Open
Known limitations Pass Documented Open
Contributing section Pass References CONTRIBUTING.md Open

6.4 Build & Publish Pipeline

Check Pass/Fail Notes Prior Status
Build workflow Pass net48 + net9.0, Windows + Ubuntu Open
Unit test workflow Pass PS 5.1/7.5, Windows/Ubuntu/macOS Open
Integration test workflow Pass PVE 8 + PVE 9 Open
Publish workflow Pass Tag-triggered, PSGallery + GitHub Release Fixed
API key handling Pass Via PSGALLERY_API_KEY secret Fixed

6.5 Versioning

Check Pass/Fail Notes Prior Status
CHANGELOG format Pass Keep a Changelog with versioned entry Open
Versioned release Pass 0.1.0-preview entry present Fixed
Commit conventions Pass Conventional Commits used consistently Open

PSGallery Readiness Checklist

Check Pass/Fail Notes Prior Status
Module manifest complete Pass All required fields populated Open
License present and OSI-approved Pass MIT Open
README with install instructions Pass PSGallery install documented Fixed
Publish pipeline configured Pass publish.yml on tag push Fixed
ReleaseNotes present Pass In PSData section Fixed
IconUri Fail Missing — cosmetic only Open
MAML help file Pass PSProxmoxVE.dll-Help.xml present New

Phase 7 — Community & Repo Maintenance Standards

Check Pass/Fail Notes Prior Status
README.md Pass Comprehensive with badges Open
LICENSE Pass MIT Open
CHANGELOG.md Pass Keep a Changelog format with versioned entry Open
CONTRIBUTING.md Pass Dev setup, coding standards, test instructions, PR process Fixed
CODE_OF_CONDUCT.md Pass Contributor Covenant v2.1 Fixed
SECURITY.md Pass Vulnerability disclosure policy, 48h response SLA Fixed
.editorconfig Pass Comprehensive rules Open
.gitignore Pass Build outputs, IDE files, test results Open
.gitattributes Pass Line ending normalization, binary detection Fixed
Issue templates Pass Bug report + feature request (YAML format) Fixed
PR template Pass Summary, type checkboxes, checklist Fixed
Conventional commits Pass Consistent in recent history Open
Default branch main Pass Confirmed Open
API coverage documentation Pass docs/PVE_API_COVERAGE.md New
Cmdlet documentation Pass 75 files in docs/cmdlets/ New
  • Require PR reviews before merge
  • Require status checks (build + unit tests + integration tests)
  • Require linear history or squash merging

Phase 8 — Prioritized Recommendations

🔴 Critical (blocks PSGallery publication or is a security risk)

None — all prior Critical items have been resolved.

🟠 High (significantly impacts quality or community adoption)

# What Where Why Fix Prior Status
H1 No firewall cmdlets Module High-value gap for security automation — most requested feature area Implement firewall rule CRUD for cluster/node/VM Open
H2 No backup/vzdump cmdlets Module Essential for DR automation scenarios Implement vzdump and backup schedule management Open

🟡 Medium (best practice gaps, test coverage holes)

# What Where Why Fix Prior Status
M1 Remove-PveRole missing ConfirmImpact.High RemovePveRoleCmdlet.cs:13 Deleting roles is a significant, potentially disruptive operation Add ConfirmImpact = ConfirmImpact.High New
M2 No pool management Module Useful for multi-tenant environments Implement pool CRUD Open
M3 Move-PveVm / Move-PveContainer lack integration tests Integration tests Migration is untested end-to-end (requires multi-node) Add integration tests when multi-node CI is available Open
M4 Import-PveOva lacks integration test Integration tests OVA import only tested at parameter level Add to integration tests (requires OVA test asset) New
M5 URL-encode snapshot/node names in API paths SnapshotService.cs, ContainerService.cs Defense-in-depth against path injection (low risk) Apply Uri.EscapeDataString() to path parameters New

🟢 Low / Nice-to-have (polish, discoverability, stretch goals)

# What Where Why Fix Prior Status
L1 No IconUri in manifest PSProxmoxVE.psd1 Improves PSGallery listing appearance Create module icon, host it, add URI Open
L2 Auth header magic strings PveHttpClient.cs:316-323 Minor code quality — could be named constants Extract to const string fields Open
L3 HA/Ceph/Replication cmdlets Module Lower-priority API coverage gaps Implement as demand grows Open
L4 Access groups/domains cmdlets Module Useful for LDAP/AD integration Implement /access/groups, /access/domains CRUD Open
L5 PSGallery version badge README.md Shows published version to visitors Add PSGallery badge after first publish New
L6 SDN IPAM/DNS/Controller cmdlets Module Complete SDN management surface Implement as demand grows New

Summary Statistics

Metric This Scan Prior Scan Delta
Total cmdlets 83 66 +17
Cmdlets with ShouldProcess All mutating All mutating
Cmdlets with OutputType 83 (100%) 66 (100%)
Cmdlets with HelpMessage 83 (100%) 0 (0%) +83
xUnit test files 13 13
Pester test files 30 26 +4
Integration test coverage 84% ~70% +14%
PVE API areas covered 12 of ~20 10 of ~20 +2
Critical issues 0 3 -3
High issues 2 8 -6
Medium issues 5 10 -5
Low issues 6 10 -4
Total issues 13 31 -18
NuGet dependencies (runtime) 3 2 +1 (SharpCompress)
Security vulnerabilities 0 0
Community files present 9/9 3/9 +6
Documentation files 78 1 +77