Getting Started with the Config CLI
The same executable as Flow Config, driven by options — connection arguments, output formats, and logging.
Everything Flow Config can do, it can do from the command line. It is the same executable, driven by options instead of a window — so a model can be built, audited, and promoted by script rather than by clicking.
Why use it#
Repeatability. A model built by script can be rebuilt identically, on another instance, next year.
Review. A script is a diff. A day of clicking is not.
Scale. Four hundred measures across twelve lines is tedious by hand and trivial in a loop.
Environment promotion. Development to test to production as a repeatable pipeline rather than a manual ritual.
Auditing. The listing verbs answer questions about a model — which measures lack units, which calculations divide without a guard — that would take hours to answer by navigating a tree.
Invoking it#
The executable is Flow Config.exe, in the Config directory of the installation:
%ProgramFiles%\Flow Software\Flow\Config\Flow Config.exe
Every invocation needs connection arguments:
"Flow Config.exe" --host <server> --database <db> [--user <u> --password <p>] <verb> [options]
| Option | Notes |
|---|---|
--host |
SQL Server instance |
--database |
Database name |
--user |
SQL login |
--password |
Its password |
Omit --user and --password to connect with Windows integrated security, as the account running the command.
It is --user, not --username. The parser accepts --user; the longer spelling is rejected as an unknown option. This is a common first stumble, and because a parse failure exits with code 1 before doing anything, it is at least a safe one.
Throughout this knowledge base the connection arguments are omitted from examples for brevity. In practice every command carries them.
Your first commands#
Prove the connection and see what is there:
# create a new instance
"Flow Config.exe" --host FLSRV01 --database FlowDemo --user sa --password ... \
--create --name "Demo Plant"
# list what exists
"Flow Config.exe" ... --list-measures
"Flow Config.exe" ... --list-connections
"Flow Config.exe" ... --list-chart-types
--create seeds more than an empty database. A new instance is not blank. It gets a root metric folder named after the instance and a time scheme called Production. If your calendar is going to be called Production, use the seeded one rather than creating a duplicate.
Output formats#
The listing verbs produce readable text by default. Add --output-format json for anything a script will consume:
"Flow Config.exe" ... --list-measures --output-format json
Always use JSON in a script. Text output is formatted for humans, column widths shift with content, and parsing it is fragile.
Logging#
--logfile <path> writes a log of the run. --log-file is accepted as a synonym; the CLI uses whichever one you pass.
Two things worth knowing about it in 7.2.0:
The log is reliable now. Parse errors, edition-gated verbs, and --help all write to the log file. Earlier builds did not create the log at all in those cases, so if you have scripts targeting an older Infohub, do not machine-parse its logs.
Progress indicators become static when output is redirected, so a captured log does not contain a screenful of spinner characters.
Capture with --log-file, not shell redirection. Redirecting the CLI's output from a Command Prompt (> out.txt) produces an empty file. The executable is GUI-subsystem and borrows the caller's console, so its output goes to that console rather than to your redirect. This affects Flow Config.exe called directly as much as the batch wrappers, it is long-standing rather than new in 7.2.0, and it does not affect Git Bash, CI runners or PowerShell pipelines, where there is no console to attach to.
Interactive use is unaffected — the text appears on screen normally. To capture it, use --log-file <path>, which works from every invocation path.
At an interactive Command Prompt, Flow Config.exe can return the prompt before its output appears. Windows does not wait for a GUI-subsystem executable started from cmd.exe, so the prompt comes back while the command is still running and its text arrives afterwards. The batch wrapper does wait, which is one reason it exists: run commands through it when you need the prompt to mean the command has finished.
Discovering the surface#
There are 506 options. Three ways to find what you need:
--help prints the grouped command overview.
--complete provides tab completion, derived from the parser's own option set — so what it offers is what the parser accepts:
"Flow Config.exe" --complete="--list-chart"
Pass --complete="--" to print every option, one per line.
The Complete CLI Option Reference in this knowledge base, generated from the source, is the exhaustive list.
Not everything is available in 7.2.0#
Several options exist in the parser but are gated in this release. Each reports a specific "not available in Flow 7.2.0" message rather than a generic error, so you can tell a gated verb from a typo:
--health--eventlog--view-definition,--import-definition,--propagate-definition--execute-filter--create-model-attribute-folder
A gated verb exits with code 1, the same as a parse failure.
--gap-skip-to was gated in earlier 7.2.0 builds and is now implemented — it moves an event scheme's processing position forward past a data gap. See Building a Model from the CLI.
Reading the result#
Every verb sets an exit code, and a script should read it rather than the printed text:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Parse failure, a gated verb, or a model, template or deployment verb that refused or failed |
| 5 | A database-level verb completed with a warning (--migrate left the version unchanged; --license saved a key it could not validate) |
| 10 | A database-level verb failed (--create, --migrate, --backup, --import, --license) |
Exit Codes and Error Handling covers these in detail, including the verbs whose exit 0 still needs an assertion afterwards.
Credentials in scripts#
Do not hard-code a SQL password in a script that gets committed or shared.
Take credentials from the environment:
$env:FLOW_SQL_USER = "flow_build"
$env:FLOW_SQL_PASSWORD = "<from your secret store>"
and pass them through. This is the convention Infohub's own QA and demo-model build scripts use — no script in that set contains a credential, each takes them from the environment, and leaving both unset falls back to integrated security with a note saying so.
Supplying a username with no password should be refused up front rather than surfacing later as an opaque SQL login failure.
Performance notes#
Most verbs are fast. Two things to know:
--list-connection-types is quick in 7.2.0. It previously loaded plugin package blobs and could take minutes on an instance with large packages. It no longer does.
Model-building runs are long by nature. A script creating several hundred measures makes several hundred invocations. That is normal — the demo models in Infohub's own QA set run to several hundred steps each.
A first useful script#
Audit rather than build, to get comfortable:
$conn = @('--host','FLSRV01','--database','FlowProd','--user',$env:FLOW_SQL_USER,'--password',$env:FLOW_SQL_PASSWORD)
$exe = "C:\Program Files\Flow Software\Flow\Config\Flow Config.exe"
# every measure, as JSON
$measures = & $exe @conn --list-measures --output-format json | ConvertFrom-Json
# which have no unit?
$measures | Where-Object { -not $_.UOM } | Select-Object Name, IntervalType
# how many of each retrieval type?
$measures | Group-Object RetrievalType | Select-Object Name, Count
The JSON from --list-measures carries MeasureID, Name, MetricID, EventSchemeID, ParentID, UOM, IntervalType, RetrievalType, Type, Active and Version. Field names are not a documented contract between versions, so look at the actual output once before relying on one.
Read-only, informative, and it answers questions that are genuinely tedious in the interface.
Where to go next#
- Building a Model from the CLI — folders, metrics, measures, chains
- Authoring Charts from the CLI — the chart verbs, which work differently
- Exit Codes and Error Handling — read this before writing anything that matters
- Scripting Patterns and Idempotency — how to make a script re-runnable