Part of the Payroll Engine open-source payroll automation framework. Full documentation at payrollengine.org.
The Payroll Console application provides API-like commands. See the Payroll Engine samples and tests for examples of how to use this tool. For a better understanding of the working concepts, it is recommended to read the Payroll Engine Whitepaper.
The application is controlled by two types of command line arguments:
- Command: a single command
- Command file: a file containing several commands.
- Prerequisites
- Commands
- Payrun Test Statistics
- Command Files
- Application Extensions
- Application Configuration
- API Key
- Application Logs
- Docker Support
- Build
- Solution Projects
- Third Party Components
- See Also
| Requirement | Minimum |
|---|---|
| .NET | 10.0 |
| Payroll Engine Backend | running and accessible |
The Payroll Console provides the following commands, grouped by area. For detailed descriptions including arguments, toggles and examples, see the Command Reference.
| Command | Description |
|---|---|
PayrollImport |
Import any payroll data from JSON/YAML/zip file |
PayrollExport |
Export any payroll data to JSON/YAML file |
PayrollConvert |
Convert payroll files between JSON and YAML (supports file masks, recursive) |
PayrollMerge |
Merge multiple payroll files into one file |
PayrollResults |
Report payroll data to screen and/or file |
CaseChangeExcelImport |
Import payroll case changes from Excel file |
RegulationExcelImport |
Transfer Excel regulation to file or backend |
| Command | Description |
|---|---|
PayrunTest |
Execute payrun and test the results |
PayrunEmployeeTest |
Execute employee payrun on a copy and test the results |
PayrunEmployeePreviewTest |
Execute employee payrun preview (no persistence) and test the results |
PayrunJobDelete |
Delete a payrun job with payroll results |
PayrunRebuild |
Rebuild payrun |
PayrunStatistics |
Display payrun statistics |
| Command | Description |
|---|---|
Report |
Report to file 1) |
DataReport |
Report data to JSON file |
ReportTest |
Test report output data |
| Command | Description |
|---|---|
CaseTest |
Test case availability, build data and user input validation |
| Command | Description |
|---|---|
ScriptExport |
Export regulation scripts to folder |
ScriptPublish |
Publish scripts from C# file |
| Command | Description |
|---|---|
LookupTextImport |
Import lookup data from text file |
RegulationRebuild |
Rebuild the regulation objects |
RegulationShare |
Manage regulation shares |
InstallRegulationPackage |
Install a regulation NuGet package into a PE backend tenant |
LexFetch |
Download a source document into the .lex folder of a data regulation |
LexAdd |
Add a lex entry with value and provenance |
LexVerifySource |
Look up the lex values in their sources, optionally record an automatic verification |
LexAttest |
Record the manual verification and the second review of lex entries |
LexSnapshot |
Create the compliance snapshot of a lex manifest |
LexVerify |
Verify that the snapshot is intact and current |
LexCheck |
Check lex manifests against the lookup values of their data regulation |
LexApply |
Write the lex values into the lookup values of the data regulation |
LexRollover |
Prepare the data regulation satellite of the next cycle |
| Command | Description |
|---|---|
LoadTestGenerate |
Generate scaled exchange files from a regulation template |
LoadTestSetupEmployees |
Bulk-import employees for load testing |
LoadTestSetupCases |
Bulk-import case changes for load testing |
PayrunLoadTest |
Execute payrun and measure performance (CSV timing report) |
LoadTestCleanup |
Delete load test employees from a tenant |
| Command | Description |
|---|---|
TenantDelete |
Delete tenant |
ChangePassword |
Change a user password |
UserVariable |
View and change the environment user variable |
| Command | Description |
|---|---|
HttpGet / HttpPost / HttpPut / HttpDelete |
Execute HTTP GET, POST, PUT or DELETE request |
LogTrail |
Trace the tenant log 2) |
Stopwatch |
Stopwatch based on environment user variable |
ActionReport |
Report custom actions from an assembly |
| Command | Description |
|---|---|
Write |
Write to the console and/or log file |
Help |
Show the command reference |
1) Based on FastReports.
2) Tenant logs are generated by the regulations and should not be confused with the application log.
The required command parameters and options/toggles are passed after the command name. An example of how to bulk import a payroll from a JSON file:
PayrollConsole PayrollImport MyPayroll.json /bulkThe Help command describes the commands and their parameters:
PayrollConsole Help PayrollImportWhen a PayrunTest, PayrunEmployeeTest, or PayrunEmployeePreviewTest run covers more than one payrun job, the console prints a statistics block after the individual job results. The block contains the key metrics used in the payroll industry to assess engine performance.
---------- Test statistics ----------
File Test.pt.json
Jobs 12
Results 240
Duration 4.2 sec
Fastest 83 ms - MyPayrun.Jan24
Slowest 1204 ms - MyPayrun.Mar24
ms/Employee 350 ms
Employees/h 10,285
Errors 2
-------------------------------------
| Field | Description |
|---|---|
File |
Test file name |
Jobs |
Number of payrun jobs executed |
Results |
Total number of wage type and collector assertions |
Duration |
Total wall-clock time of all jobs |
Fastest |
Shortest job duration with job name |
Slowest |
Longest job duration with job name (only shown when more than 2 jobs) |
ms/Employee |
Average calculation time per employee-period — the primary payroll benchmark. Each PayrollTestResult represents one employee × one payroll period, so this is total duration / result count. |
Employees/h |
System throughput derived as 3 600 000 / ms/Employee — the standard capacity metric in payroll operations, indicating how many employees can be processed per hour at the measured speed. |
Errors |
Number of failed assertions (only shown when > 0) |
ms/EmployeeandEmployees/hare the two standard payroll-industry benchmarks: one measures latency per employee, the other measures system capacity.
The command file is a file with the extension .pecmd that contains a series of instructions to the Payroll Engine Console. The lines of the file are executed sequentially and contain the following line types
- Comment starting with
# - Command instruction
- Start another command file
Example command file Delete.pecmd with a comment and a command statement:
# delete my tenant
TenantDelete MyTenant /trydeleteThe following example uses the Delete.pecmd command file and then runs the command to test the payrun:
# cleanup and execute test
Delete.pecmd
PayrunTest *.pt.jsonIf the called command file is in a different folder, it will be activated before execution:
Test1/Test.pecmd
Test2/Test.pecmdThis is necessary if the called command file is to be defined with local references. The keeppath option prevents directories from being changed:
Tools/Import1.pecmd /keeppath
Tools/Import2.pecmd /keeppathIn the example above, both import command files are run in the startup folder.
Command files can also be controlled by parameters. Such parameters are used with the placeholder $Name$ in the commands. In the following example, the command file OwnerTest.pecmd has the parameter Owner:
# payrun employee test
# argument owner: job owner
PayrunEmployeeTest fileMask:*.et.json owner:$owner$ /waitCalling this command file with the Owner parameter looks like this:
OwnerTest.pecmd owner:Test01The release package includes setup scripts that register the .pecmd extension with the
operating system. Registration is scoped to the current user and does not require
administrator privileges.
Important: Run the registration script from the published console folder (e.g.
Bin\Console\) wherePayrollEngine.PayrollConsole.exeis located, not from the source repository.
Windows — run from Bin\Console\:
.\Register-PecmdExtension.ps1To unregister:
.\Register-PecmdExtension.ps1 -UnregisterIf an older system-wide registration exists (installed via the legacy FileType.Reg.cmd
which required admin rights), remove it first before running the new script:
FileType.Unreg.cmdLinux / macOS — run from the published console folder:
./register-pecmd.shTo unregister:
./register-pecmd.sh --unregisterIf the console binary is not in the same directory as the script, pass the path explicitly:
.\Register-PecmdExtension.ps1 -ConsolePath "C:\Tools\PayrollEngine.PayrollConsole.exe"./register-pecmd.sh --console-path /opt/payrollengine/PayrollEngine.PayrollConsoleIn containerized environments, file type registration is not needed. Pass the
.pecmdfile directly as an argument todocker run.
The following toggles apply to all Payroll Console commands:
| Name | Description | Values | Command file |
|---|---|---|---|
| Display level | Command information level | full 1), compact, silent |
Preset for executing commands |
| Error mode | Show failed tests and errors | errors1), noerrors |
Preset for executing commands |
| Wait mode | Wait at the program end | waiterror1), wait, nowait |
Final application wait mode |
| Path mode | Path change mode | changepath1), keeppath |
Only for command files |
1) Default value.
The Payroll Console provides a plug-in mechanism for integrating custom commands:
- Command parameters with names and options
- Access to the Payroll REST API via the Payroll HTTP client
- Control output to console and logger
- Program exit code definition
The extension point is the command: an extension provides classes with the [Command("Name")] attribute, derived from CommandBase<TParameters> (PayrollEngine.Client.Core). Commands that do not access the backend override BackendCommand => false.
Important
Breaking change in version 1.2.0: assemblies placed directly into the extensions folder are no longer loaded. Each extension requires its own subfolder with an extension.json manifest. See Migration from earlier versions.
Each extension is a subfolder of the extensions folder next to the console executable. The folder contains the command assemblies, all dependencies and the manifest:
extensions/
MyExtension/
extension.json
MyExtension.dll
MyExtension.deps.json
SomeDependency.dll
The manifest extension.json is mandatory:
{
"name": "MyExtension",
"version": "1.0.0",
"description": "My console commands",
"requiresConsole": "1.2",
"assemblies": [ "MyExtension.dll" ],
"files": [
{ "path": "MyExtension.dll", "sha256": "3f2a..." },
{ "path": "MyExtension.deps.json", "sha256": "9b41..." },
{ "path": "SomeDependency.dll", "sha256": "c07e..." }
]
}| Field | Description | Required |
|---|---|---|
name |
Extension name, must match the folder name | yes |
version |
Extension version | yes |
description |
Extension description | no |
requiresConsole |
Required console extension API version (major.minor) |
yes |
assemblies |
Assemblies containing the commands; only these are scanned, all other assemblies are dependencies | yes |
files |
Extension files with their SHA-256 hash (relative paths) | yes |
All assemblies (*.dll, *.exe), native libraries (*.so, *.dylib) and dependency files (*.deps.json) of the extension folder must be listed in files. Other files are verified if they are listed.
The manifest is created or updated with the ExtensionManifest command, which computes the hashes of all files in the folder:
PayrollConsole ExtensionManifest bin\Release\net10.0 Name:MyExtensionValues of an existing manifest (version, description, assemblies) are kept unless overridden. Run the command after each build, then copy the folder to extensions/MyExtension/.
At startup, the console loads the extensions in alphabetical order of their folder names. Per extension:
- Read and validate the manifest.
- Check
requiresConsoleagainst the console extension API version: the major version must be equal and the minor version must not be higher than the console's. TheExtensionscommand shows the current API version. - Verify the hashes of all files listed in
files, and reject undeclared files. - Load the
assembliesinto a separate load context of the extension. Dependencies are resolved from the extension folder using the.deps.jsonfile. The contract assembliesPayrollEngine.Client.Core,PayrollEngine.CoreandPayrollEngine.Lexare always shared with the console. Other assemblies the extension does not provide are taken from the console. - Register all commands of the extension.
Rules:
- Each extension uses its own versions of its dependencies, independent of the console and of other extensions.
- Core commands take precedence and cannot be replaced.
- Command names are case-insensitive. If a command name is already registered, the whole extension is rejected, and the message names both sources.
- A rejected extension registers no commands. It does not affect the console or other extensions.
- Loaded extensions are logged as information, rejected extensions as warnings, including the reason.
The hash verification detects modified or unintended files. It is not a signature: replacing an assembly together with its manifest is not detected. Extensions run with the permissions of the console, including its backend configuration; only install extensions from trusted sources.
| Command | Description |
|---|---|
Extensions |
List the extensions with version, path, status (loaded or rejected with reason) and commands |
ExtensionManifest |
Create or update the manifest of an extension folder |
Help |
Shows the source of extension commands; Help MyCommand shows the source of any command (core or extension) |
Common rejection reasons:
| Reason | Solution |
|---|---|
Missing manifest extension.json |
Create the manifest with ExtensionManifest |
Hash mismatch of file ... |
The file has changed since the manifest was created; recreate the manifest |
Undeclared file(s) ... |
Add the file to the manifest or remove it from the folder |
Requires console extension API ... |
Update the console or build the extension for the installed console version |
Duplicate command ... |
Rename the command; core commands and previously loaded extensions take precedence |
Failed to load types of assembly ... |
A dependency is missing in the extension folder |
Assembly without extension folder ... |
Move the assembly into its own extension folder (see migration) |
- Develop the extension library in C# (example PayrollEngine.Client.Tutorials).
- Build the library and run
ExtensionManifeston the build output folder. - Copy the folder to
extensions/MyExtension/of the console. - Check the status with
PayrollConsole Extensions. - Display the command help
PayrollConsole Help MyCommandName. - Run the command with
PayrollConsole MyCommandName.
Earlier versions loaded every assembly in the extensions folder, including subfolders. Since version 1.2.0:
- Create the folder
extensions/<Name>/per extension, and move the extension assembly together with its dependencies into it. - Create the manifest:
PayrollConsole ExtensionManifest extensions\<Name>. If the command assembly is not named<Name>.dll, pass it withAssemblies:MyCommands.dll. - Verify with
PayrollConsole Extensions.
Assemblies remaining directly in extensions/ are reported as rejected.
The Payroll Console configuration appsettings.json contains the following settings:
| Setting | Description | Type | Default |
|---|---|---|---|
StartupCulture |
The payroll console process culture | string | System culture |
FullErrorLog |
Show full error details in log | bool | false |
AllowInsecureSsl |
Skip backend SSL certificate validation (dev only) | bool | false |
ApiSettings |
The backend api configuration | Backend API | |
Serilog |
Logger configuration | Serilog |
It is recommended that you save the application settings within your local User Secrets.
| Setting | Description | Type | Default |
|---|---|---|---|
BaseUrl |
The backend base url | string | |
Port |
The backend url port | string | |
Timeout |
The backend request timeout | TimeSpan | 100 seconds |
ApiKey |
The backend API key | string |
The backend API configuration can be declared in the following locations.
| Priority | Source | Content |
|---|---|---|
| 1. | Environment variable PayrollApiConnection |
Backend API configuration connection string. |
| 2. | Environment variable PayrollApiConfiguration |
Path to the backend API configuration JSON file. |
| 3. | File apisettings.json |
Backend API configuration JSON file located in the program folder. |
| 4. | File appsettings.json |
ApiSettings from the application configuration JSON file. |
The following is an example of a backend API configuration within a connection string:
BaseUrl=https://localhost; Port=44354; Timeout=02:46:40; ApiKey=MyApiKey; The following is an example of a JSON-based backend API configuration:
{
"BaseUrl": "https://localhost",
"Port": 44354,
"Timeout": "02:46:40",
"ApiKey": "MyApiKey"
}If a key is required to access the backend API, it must be obtained from one of the following sources (in order of priority):
- Environment variable
PayrollApiKey - Payroll HTTP configuration (see
PayrollEngine.Client.Core)
The payroll console stores its logs in the application folder logs.
The Payroll Console is available as a pre-built Docker image from the GitHub Container Registry.
Run a command against a Backend running in Docker Compose:
docker run --rm --network payroll-engine_default \
-e PayrollApiConnection="BaseUrl=http://backend-api:8080; Port=8080;" \
ghcr.io/payroll-engine/payrollengine.payrollconsole:latest \
PayrollImport MyPayroll.jsonRun tests:
docker run --rm --network payroll-engine_default \
-e PayrollApiConnection="BaseUrl=http://backend-api:8080; Port=8080;" \
ghcr.io/payroll-engine/payrollengine.payrollconsole:latest \
PayrollTest --testFile Tests/Test.All.pecmdRun against a Backend on the host machine:
docker run --rm \
-e PayrollApiConnection="BaseUrl=http://host.docker.internal; Port=5001;" \
ghcr.io/payroll-engine/payrollengine.payrollconsole:latest \
Helpdocker build -t payroll-console .
docker run --rm -it payroll-console HelpSee the Container Setup documentation for the full Docker Compose stack.
# Run from the project folder (PayrollConsole/)
dotnet run -- Help
# Publish self-contained binary
dotnet publish -c Release -r win-x64 --self-containedEnvironment variable used during build:
| Variable | Description |
|---|---|
PayrollEnginePackageDir |
Output directory for the NuGet package (optional) |
| Name | Type | Description |
|---|---|---|
PayrollEngine.PayrollConsole.Commands |
Library | Console commands |
PayrollEngine.PayrollConsole |
Exe | Console application |
- Excel conversion with ClosedXML — license
MIT - Logging with Serilog — license
Apache 2.0 - Lex source reading with PdfPig — license
Apache 2.0and ExcelDataReader — licenseMIT
All distributed components, their licenses and notices are listed in THIRD-PARTY-NOTICES.md; the file is part of every build output.
- Payroll Console — Automator role documentation
- Command Reference — full argument and toggle reference for all commands
- Client Services — SDK used by this tool
- PayrollEngine Examples — example
.pecmdfiles and test fixtures