| Property | Value |
|---|---|
| Version | 2.0 |
| Status | Stable |
| Applies To | Keldor public functions and user-facing command output |
| Last Updated | 2026-07-16 |
This standard defines canonical parameter names, output property names, compatibility rules, and migration guidance for Keldor public functions.
It extends the Keldor General Engineering Standard and the Keldor PowerShell Engineering Standard. Its goal is to make Keldor commands feel like one coherent toolkit: predictable inputs, stable objects, and migration paths that do not surprise existing users.
This standard applies to:
- Public function parameter names and aliases.
- Structured output property names.
- Compatibility aliases for renamed parameters.
- Legacy output property preservation.
- Migration planning for existing Keldor commands.
This standard does not require:
- Immediate breaking changes to existing functions.
- Immediate output object reshaping.
- Immediate
PSTypeNameadoption for legacy object contracts. - Rewriting unrelated command logic.
Fleet-oriented and infrastructure-oriented commands must accept pipeline-friendly inputs and emit normalized, structured objects with stable property names and native PowerShell/.NET types.
This rule applies to server inventory, remote execution, system health, service management, storage and filesystem health, network diagnostics, patch and package status, Azure resources, Azure Arc-enabled servers, virtualization, Nutanix and other infrastructure integrations, certificate and TLS inspection, fleet reporting, configuration compliance, CMDB discovery or reconciliation, and monitoring or remediation workflows. It is also recommended whenever pipeline composition and structured output provide meaningful value.
The contract is required for new commands in this scope. Existing commands follow the compatibility and migration rules in this document and the fleet migration audit.
Public commands that logically operate on one or more objects must support pipeline input when practical and
semantically appropriate. Use ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, or both. Do not
add pipeline binding when it would be ambiguous or unsafe.
Pipeline-aware commands must use the lifecycle blocks that their behavior needs:
- Use
beginfor one-time initialization. - Use
processfor each incoming item or target. - Use
endonly for aggregation, finalization, or cleanup. - Do not collect all input in memory unless aggregation is part of the command contract.
ComputerName is the canonical public parameter for a DNS name, FQDN, NetBIOS name, or IP address that identifies a
remote system. Do not expose separate ComputerName and HostName parameters for the same identity.
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true
)]
[Alias('HostName', 'DnsHostName', 'Name')]
[ValidateNotNullOrEmpty()]
[string[]]
$ComputerNameAliases may be reduced when they conflict with command semantics. Existing aliases remain compatibility-sensitive.
Use InputObject for a documented rich-object contract, not as an unstructured dumping ground:
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNull()]
[object[]]
$InputObjectHelp must identify the properties or types accepted through InputObject. Prefer a more specific parameter or type
when the accepted value has a well-defined domain name.
Use PSSession when an existing session can be reused. Commands that accept both ComputerName and PSSession must
use meaningful, separate parameter sets and must not reconnect when a valid session is supplied.
Use these names when the capability is implemented and meaningful; do not add unused fleet parameters:
ComputerName
InputObject
PSSession
Credential
KeyFilePath
Port
Transport
ThrottleLimit
ConnectionTimeout
OperationTimeout
RetryCount
RetryDelay
SessionOption
Credentialmust be[pscredential]. Plaintext password parameters are prohibited. Credential contents must never appear in output, logs, verbose messages, or errors.KeyFilePathidentifies an SSH private key. Validate syntax without eagerly reading or resolving the path when that would break remoting. Never emit key contents.Transportmust use explicit validated values when multiple transports are supported. A typical set isAuto,WSMan,SSH, andLocal. Help must state theAutoselection order and its security implications.ThrottleLimitmust be positive, conservatively bounded by default, and documented as caller-tunable for network, endpoint, and policy constraints. Unlimited concurrency must not be the default.ConnectionTimeout,OperationTimeout, andRetryDelayuse seconds. Include the unit in help.RetryCountis the number of additional attempts after the initial attempt. Do not retry authentication, authorization, invalid-parameter, or other clearly non-transient failures unless explicitly documented. Prefer bounded backoff for transient failures.
Each parameter set must represent a meaningful execution path. Do not create sets that differ only cosmetically.
[CmdletBinding(DefaultParameterSetName = 'ComputerName')]
param(
[Parameter(
Mandatory = $true,
ParameterSetName = 'ComputerName',
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true
)]
[Alias('HostName', 'DnsHostName')]
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName,
[Parameter(
Mandatory = $true,
ParameterSetName = 'Session',
ValueFromPipeline = $true
)]
[ValidateNotNull()]
[System.Management.Automation.Runspaces.PSSession[]]$PSSession
)Public parameters must use clear PascalCase names that describe the value being supplied.
Prefer established PowerShell conventions where they exist. Use the same canonical parameter name for the same concept across all public functions.
| Concept | Canonical Parameter |
|---|---|
| Target computer or remote host | ComputerName |
| User identity | UserName |
| Group identity | GroupName |
| Input filesystem path | Path |
| Output or destination filesystem path | DestinationPath |
| Registry key or value path | RegistryPath |
| IP address | IPAddress |
| Operating system name | OperatingSystem |
| CPU or OS architecture | Architecture |
| Operating system build number | BuildNumber |
- Use
ComputerName, notComputer,Host,Machine,Server, orName, when the value targets one or more computers. - Use
UserName, notUser,Username,LoggedOn, orName, when the value identifies a user. - Use
GroupName, notGroup, when the value identifies a group. - Use
Pathfor input paths. - Use
DestinationPathfor output paths, copied files, generated files, exports, and save locations. - Use
RegistryPathfor registry paths; avoidFullPathwhen the path is specifically a registry location. - Use
IPAddress, notIP,IPs,IPv4, orAddress, for an IP address parameter. - Use
BuildNumber, notBuild, for OS build numbers. - Boolean switch parameters should describe the action or mode clearly. Avoid vague switch names such as
Yes,No,On, orOfffor new public functions.
Structured output must use stable, descriptive PascalCase property names.
Fleet commands must return objects as their primary success output. Write-Host, Format-Table, Format-List, and
Out-String are presentation-boundary tools and must not produce a reusable command's primary result. Use explicit,
ordered [pscustomobject] definitions. Property order is a public usability characteristic and must be intentional.
$result = [pscustomobject][ordered]@{
ComputerName = $resolvedComputerName
IsSuccessful = $true
Status = 'Healthy'
CheckedAt = [datetimeoffset]::UtcNow
}
$result.PSObject.TypeNames.Insert(0, 'Keldor.SystemHealthResult')
$resultDefined public fleet contracts require a stable type name. Use Keldor.<Entity>, Keldor.<Entity>Result, or
Keldor.<Provider>.<Entity>, for example Keldor.SystemInfo, Keldor.RemoteCommandResult, Keldor.Azure.Server,
Keldor.Linux.Package, or Keldor.CertificateStatus. Do not introduce a .NET class only to attach a type name, and do
not change an established public type name without a compatibility plan.
Recommended property order is:
- Primary identity.
- Parent or scope identity.
- Platform or provider.
- Primary result or state.
- Detailed measurements.
- Error details.
- Timing and provenance.
Do not alphabetize properties when it makes the object harder to understand.
Use the same property name for the same concept across all object families. Do not use short aliases, abbreviations, or source-system field names as canonical properties unless they are industry standard.
| Concept | Canonical Output Property |
|---|---|
| Computer name | ComputerName |
| User name | UserName |
| Group name | GroupName |
| Filesystem path | Path |
| Destination filesystem path | DestinationPath |
| Registry path | RegistryPath |
| IP address | IPAddress |
| Operating system name | OperatingSystem |
| Architecture | Architecture |
| Build number | BuildNumber |
| Creation timestamp | Created |
| Modification timestamp | Modified |
| Collection timestamp | CollectedAt |
| Validation or check timestamp | CheckedAt |
| Normalized state | Status |
| Human-readable detail | Message |
- Use
ComputerName, notComputerorName, when the property identifies a computer. - Use
UserName, notUser,Username, orLoggedOn, when the property identifies a user. - Use
Path, notDirectory, when the value is a filesystem path. - Use
RegistryPath, notFullPath, for registry locations. - Use
InterfaceName,InterfaceAlias, andInterfaceIndex, notName,ConnectionID, andIndex, for network interfaces. - Use
IPAddress, notIP. - Use
OperatingSystem, notOS. - Use
Architecture, notBit. - Use
BuildNumber, notBuild. - Use
Messagefor human-readable detail. Do not overloadStatuswith long explanatory text.
Boolean properties must read naturally as true or false.
Use:
IsSuccessfulIsHealthyIsAvailableIsConnectedIsCompliantIsEnabledIsInstalledHasChangesCanRestartIsExpiredHasErrors
Avoid:
EnabledInstalledOnlineExpiredErrors
When preserving old output properties, keep the old boolean property if existing users may depend on it, and add the canonical Is* or Has* property in a separate compatibility-focused change.
Date and time properties must explain what the timestamp means.
Use:
Createdfor creation time.Modifiedfor last modification time.CollectedAtfor the time Keldor collected or generated the object.CheckedAtfor the time Keldor performed a check or test.StartedAtandCompletedAtfor operation boundaries.DiscoveredAt,UpdatedAt, andLastSeenAtfor the named lifecycle event.
Avoid vague names:
DateTimeWhenTimestamp
Use DateTime values when practical. If the source system returns a string or filetime value and converting it would change behavior, preserve the legacy property and add a canonical converted property in a separate, tested change.
Prefer [datetimeoffset] when timezone and transport semantics matter. Use [timespan] for Duration, or a numeric
type for explicitly named values such as DurationMilliseconds.
Public output contracts must preserve native values:
| Value | Preferred type |
|---|---|
| Boolean | [bool] |
| Count or byte quantity | Integer type |
| Percentage or measurement | Numeric type |
| Duration | [timespan] |
| Date/time | [datetime] or [datetimeoffset] |
| Version | [version] when semantically valid |
| IP address | [System.Net.IPAddress] when practical |
| URI | [uri] when practical |
Do not return display strings such as 15 GB, 72%, or 300 ms. Use numeric properties with explicit names such as
FreeSpaceBytes, FreeSpaceGB, FreeSpacePercent, or LatencyMilliseconds. Output values must be invariant and
culture-neutral; localization belongs at the presentation boundary.
Keldor.RemoteCommandResult uses this stable property order and meaning:
ComputerName
IsSuccessful
Output
ErrorCategory
ErrorCode
ErrorMessage
StartedAt
CompletedAt
Duration
Transport
AttemptCount
Output may hold one or more native PowerShell objects and must not be stringified merely for serialization.
AttemptCount is the total number of attempts actually made. One failed target must not suppress successful target
results unless the caller explicitly requests terminating behavior.
Keldor.SystemHealthResult and domain-specific health types should use this shape when the properties apply:
ComputerName
CheckName
IsHealthy
Status
Severity
Message
CurrentValue
ExpectedValue
ErrorCategory
ErrorCode
ErrorMessage
CheckedAt
Allowed severity values are Informational, Warning, Critical, and Unknown. Allowed health status values are
Passed, Failed, Skipped, and Unknown. A skipped or unavailable check must not report IsHealthy = $true.
When compatibility permits, use IsHealthy = $null and Status = 'Unknown' for an indeterminate result.
- The success stream contains only objects in the documented public contract. Capture or suppress incidental command and method output.
- The verbose stream describes non-sensitive target selection, transport selection, retries, provider choice, pagination, and progress details.
- The warning stream reports recoverable concerns, but never replaces a structured per-target failure result.
- Use non-terminating errors for individual target failures when other targets can continue. Honor
-ErrorAction. - Use terminating errors for invalid command-wide configuration, invalid authentication configuration, unsupported parameter combinations, missing dependencies that prevent all execution, and corrupted internal state.
- Never emit an error and then report the same operation as successful. Never expose credentials, tokens, secrets, connection strings, key material, or stack traces as normal output.
Pipeline support does not change the repository's
SupportsShouldProcess rules. A fleet command that changes
external or persistent state must set SupportsShouldProcess = $true and call $PSCmdlet.ShouldProcess() for each
target or discrete change. Read-only inventory, discovery, inspection, and health commands must not add
SupportsShouldProcess.
Use Status for normalized result state.
Good Status values are short and suitable for filtering:
Succeeded
Failed
Skipped
Online
Offline
Available
Unavailable
Compliant
NonCompliant
Unknown
Use Message for human-readable details:
[pscustomobject]@{
ComputerName = 'SERVER01'
Status = 'Failed'
Message = 'The remote registry service is unavailable.'
}Do not place long explanatory text in Status when a separate Message property is appropriate.
When renaming a public parameter:
- Add the canonical parameter name.
- Preserve the previous parameter name as an alias.
- Preserve commonly used legacy aliases unless they are unsafe or ambiguous.
- Update comment-based help to document the canonical parameter name.
- Do not remove old aliases in the same PR that introduces the canonical name.
Example:
param(
[Parameter(Mandatory = $true)]
[Alias('User', 'Username', 'SamAccountName')]
[string]$UserName
)Parameter aliases are the preferred compatibility mechanism. Do not keep duplicate parameters that represent the same value unless PowerShell binding rules require it.
Output property changes are higher risk than parameter name changes because users commonly pipe, filter, export, and serialize Keldor output.
When normalizing output:
- Preserve legacy output properties when removal would break users.
- Add canonical properties rather than renaming destructively.
- Keep the existing default display shape unless the PR is explicitly scoped to output formatting.
- Avoid changing property types in the same PR as property-name normalization.
- Document legacy properties as compatibility properties when help is updated.
Example additive migration:
[pscustomobject]@{
Computer = $ComputerName # legacy
ComputerName = $ComputerName # canonical
Status = 'Online'
}Legacy output properties may be removed only in a documented major-version migration.
| Bad | Good | Reason |
|---|---|---|
Computer |
ComputerName |
Matches PowerShell convention and pipeline property names. |
Host |
ComputerName |
Host conflicts with PowerShell host terminology. |
User |
UserName |
Clarifies identity value. |
Username |
UserName |
Uses consistent PascalCase word boundary. |
Group |
GroupName |
Clarifies identity value. |
DirectoryName |
Path |
A directory path is still a path. |
Destination |
DestinationPath |
Clarifies that the value is a path. |
FullPath |
RegistryPath |
Clarifies registry-specific meaning. |
IP |
IPAddress |
Avoids abbreviation drift. |
Build |
BuildNumber |
Clarifies numeric OS build. |
Yes / No |
Enable / Disable or IsEnabled |
Avoids unclear switch behavior. |
| Bad | Good | Reason |
|---|---|---|
Computer |
ComputerName |
Consistent computer identity property. |
User |
UserName |
Consistent user identity property. |
Group |
GroupName |
Consistent group identity property. |
Directory |
Path |
The value is a filesystem path. |
FullPath |
RegistryPath |
Registry path should be explicit. |
IP |
IPAddress |
Avoids abbreviation drift. |
OS |
OperatingSystem |
Clear and searchable. |
Bit |
Architecture |
Describes the concept accurately. |
Build |
BuildNumber |
Clarifies numeric build. |
Date |
Created, Modified, CollectedAt, or CheckedAt |
Explains timestamp meaning. |
When |
Created, Modified, CollectedAt, or CheckedAt |
Avoids vague timing. |
Enabled |
IsEnabled |
Boolean reads naturally. |
Installed |
IsInstalled |
Boolean reads naturally. |
Errors |
HasErrors |
Boolean reads naturally. |
Keldor migration work must be incremental and low risk.
- New fleet commands must comply with this standard.
- Existing commands without an established contract should move toward it through small, tested changes.
- Existing commands with known consumers require compatibility review before changing parameter names, aliases, parameter sets, type names, property names, property types, state values, or stream behavior.
- Preserve old parameters as aliases.
- Preserve legacy output properties when removal would break users.
- Normalize one object family per PR.
- Add a stable
PSTypeNameonly when the object shape already represents a defined contract and compatibility is demonstrated. - Do not mix parameter normalization, output reshaping, formatting changes, and unrelated logic modernization in the same PR.
- Add or update Pester tests for parameter aliases and output contracts where practical.
- Prefer additive changes first, then documented deprecation, then major-version removal if needed.
- Parameter-only normalization with aliases.
- Output contract tests for one object family.
- Add canonical output properties while preserving legacy properties.
- Update help and examples to use canonical names.
- Add formatting or type data only after output contracts stabilize.
- Add the documented Keldor
PSTypeNameafter the object family is stable and compatibility is demonstrated.
Normalize low-risk parameter names and preserve aliases:
BuildtoBuildNumber.ImagePathtoPath.FileNametoPath.DirectoryNametoPath.IPandIPstoIPAddress.User,Username, andSamAccountNametoUserName.DestinationtoDestinationPath.
Add parser or command-metadata tests that verify:
- Canonical parameter names exist.
- Legacy aliases remain available.
- Mandatory path and identity parameters have safe validation.
- Public output contracts are captured before reshaping.
Start with small, stable object families:
- Build number conversion.
- Directory statistics.
- Update history.
- Certificate inventory.
- Simple process result objects.
Defer wide or mixed-domain outputs until tests are strong:
- Hardware inventory.
- Network interface inventory.
- Endpoint security status.
- Active Directory compliance reports.
- Local user and group inventory.
After a canonical object family is stable, assign its documented Keldor type name one family at a time. Preserve established type names and use a compatibility plan for any unavoidable change.