Command Reference
Important
The Tabular Editor CLI is in Limited Public Preview. It is offered for evaluation with a Tabular Editor account; no license is required during preview. Commands, flags, and outputs may change before general availability. The preview build stops functioning after 2026-09-30. We recommend against using the CLI in production CI/CD pipelines during preview. Please refer to our license agreement.
This page gives a short description and one example per command. Every command accepts --help for exhaustive flag documentation:
te deploy --help # Help for a single command
te bpa run --help # Help for a command with subcommands
Note
During preview, the CLI's --help output is the authoritative reference for flags and options. The content on this page is hand-curated and will lag --help for anything added between preview releases.
Object paths
Object addressing in the CLI uses a single grammar that's shared across every command. Two flavours of path appear in the reference below:
<path>- resolves to exactly one object or container. Used by commands that operate on a single target:te get,te set,te add,te rm,te mv,te format -p,te deps,te macro run --on.<path-filter>- resolves to zero or more objects, with wildcard support. Used by commands that operate on a set:te ls,te bpa run --path, and other inspection-style commands.
Both path forms share the same syntax rules; they differ in only two places:
- Filter paths allow
*wildcards; object paths do not. - Object paths allow DAX bracket-suffix (e.g.
Sales[Amount]); filter paths do not.
Segments and separators
A path is a slash-separated sequence of segments. Each segment names a single step - a table, a child object, or a container keyword.
Sales— one segmentSales/Revenue— two segmentsRoles/Admin/Members/bob— four segments
Empty input and . both mean "the model root" - the implicit starting point for filter paths and the explicit subject for te get .-style queries.
Quoting
Most segment names work as-is. Quote a segment when its name contains spaces, slashes, brackets, or any character that would otherwise be parsed as syntax. The CLI follows DAX quoting conventions, so quoting in te paths matches what you'd type inside a DAX expression:
| Form | Use for | Escape rule |
|---|---|---|
'Net Sales' |
Tables, named objects with spaces. | Double the quote ('Bob''s' → Bob's). |
"Net Sales" |
Same as above; cross-shell convenience when single-quote escaping is awkward. | Double the quote ("He said ""hi""" → He said "hi"). |
[Sales Amount] |
DAX bracket-suffix on a table ('Sales'[Sales Amount]) or a lone-bracket model-wide reference ([Total Sales]). Object paths only. |
Double the closing bracket ([foo]]bar] → foo]bar). |
Inside quoted segments, * is treated as a literal character, not a wildcard. So 'Sa*' matches a table named exactly Sa*.
DAX-style references (object paths only)
Two DAX-shaped forms are accepted anywhere a <path> is allowed:
'Table'[Member]- equivalent toTable/Member. The bracket-suffix biases ambiguous matches toward columns and measures over hierarchies/partitions.[Member]- a lone measure or column, with no preceding table. Searches the whole model for a measure or column with that name. Measures win when both exist.
te get "'Sales'[Amount]" # Same as te get Sales/Amount
te get "'Net Sales'[Sales Amount]" # Spaced names via DAX form
te get "[Total Sales]" # Model-wide measure-or-column lookup
Containers and keywords
Several names act as container keywords. A keyword can stand alone (listing the whole container) or appear inside a path (jumping into that sub-collection on the current parent).
| Keyword | Scope | Meaning |
|---|---|---|
Tables, Measures, Columns, Hierarchies, Partitions |
Model | All objects of that kind across the model. |
Relationships, Roles, Perspectives, Cultures, DataSources, Expressions, CalculationGroups, Functions, Annotations |
Model | Model-level containers. |
Measures, Columns, Hierarchies, Partitions, Calendars, CalculationItems |
Table | Sub-containers under a table. |
Levels |
Hierarchy | Levels of a hierarchy. |
Members, TablePermissions (alias Permissions) |
Role | Children of a role. |
A few examples show how plain and container-scoped paths differ:
te get Sales/Revenue # Measure or column on Sales
te get Sales/Measures/Revenue # Same, container-scoped - disambiguates if other kinds share the name
te get Sales/Geography/Levels/Year # Specific level of a hierarchy
te get Roles/Admin/Members/bob@example.com # Role member
te get Sales/refreshPolicy # Refresh-policy sub-object on a table
te get "Measures/Revenue/KPI" # KPI sub-object of a measure
Quote a segment to force literal-name matching when a real object name happens to coincide with a keyword. The table literally named Tables is 'Tables', addressed by te get "'Tables'".
Wildcards in filter paths
Filter paths add a single wildcard character - * - that matches any run of characters within one segment (greedy, single-segment). Wildcards are how te ls and similar commands narrow their results.
te ls 'Sa*' # Tables whose name starts with Sa
te ls 'Sales/*Amount' # Children of Sales whose name ends with Amount
te ls '*/Amount' # An Amount column/measure across every table
te ls 'Roles/Re*/Members' # Members of every role matching Re*
A filter path with N segments produces N-level-deep results - wildcards never auto-expand a level beyond what you typed. The single-segment shortcut te ls Sales is the exception: an unqualified, non-wildcarded table name expands to the table's direct children to match the "show me what's in Sales" intent. te ls Sa*, in contrast, returns just the matching tables - no expansion.
DAX bracket-suffix is rejected in filter paths; quote names containing [ and ] if you need to match them literally.
Errors and hints
Misspelled segments emit a contextual error with a "did you mean" hint when the CLI can guess what you meant. Missing-parent paths fail before the leaf check, so the message points at the segment that's actually wrong. Empty containers (e.g., te ls Hierarchies on a model without hierarchies) emit a simply "nothing here" hint rather than an error.
Global options
These flags are available on every command and can be used before or after the subcommand name.
| Option | Description |
|---|---|
-m, --model <path> |
Path to semantic model (TMDL folder, .bim file, or TE folder). |
-s, --server <endpoint> |
Workspace name or endpoint (e.g., MyWorkspace, powerbi://..., asazure://..., localhost). |
-d, --database <name> |
Semantic model name on the workspace. |
--local |
Connect to a locally running Power BI Desktop instance (Windows only). |
--auth <method> |
Auth method: auto, interactive, spn, env, managed-identity (default: auto). |
--output-format <format> |
Stdout format: text (default), json, csv, tmsl (alias bim), tmdl. csv is honored by commands that emit tabular data; tmsl/tmdl only by te get and te ls for whole-object serialization. Commands reject formats they don't support. |
--error-format <format> |
Stderr format for errors, warnings, and hints: text (default) or json. Other values fall back to text. Independent of --output-format, so you can pair JSON stdout with plain-text errors (or vice versa). |
--recent [N] |
Use a recently used model. No value = interactive picker; N = Nth most recent (1 = last used). |
--non-interactive |
Disable all interactive prompts. Fail with an actionable error if required input is missing. |
--debug |
Enable debug logging to stderr (connection strings, auth flow, timing). |
For commands that read a model, the resolution order is:
positional <model> argument → --model global flag → --server/--database (remote) → active connection from te connect → --recent.
Model I/O
load
Load a semantic model and display a summary of the model — name, compatibility level, and high-level object counts (tables, measures, columns).
te load ./model # TMDL folder
te load model.bim # BIM file
te load -s MyWorkspace -d MyModel # Remote workspace
save
Save a model to disk. Use it to write a remote workspace model to local files, convert formats, or persist edits back to the source.
te save accepts:
-o, --output-path <path>- target file or folder. Optional - when omitted,te savewrites back to the source location, preserving the original format.--serialization <fmt>-tmdl,bim,te-folder,pbip,database.json. Defaults to inferring from the loaded model (BIM source → BIM, TMDLSemanticModel/→ TMDL underdefinition/).--force- skip validation and overwrite existing output. Some refusals (ambiguous containers, multi-SemanticModelproject roots) fire even under--force.--skip-bpa- bypass the BPA gate entirely.--fix-bpa- auto-fix BPA violations where rules define a fix expression.--bpa-rules <path>- repeatable; overridebpa.rulesfrom your CLI config for this single save. Built-in rules still apply unlessbpa.builtInRulesisfalse.--skip-validation- skip DAX semantic analysis and validation for fast passthrough downloads.--supporting-files- generate Fabric supporting files (.platform,definition.pbism).
te save # Save back to source (no -o needed)
te save ./model.bim -o ./tmdl-out # Convert BIM to TMDL
te save -o ./project --serialization pbip # Save as a PBIP project
te save -o ./out -s my-workspace -d my-model --skip-validation # Fast download
Tip
Use te save -o <path> -s <workspace> -d <model> to download a remote model to disk. Pair with --skip-validation for the fastest passthrough when you only need the bytes (no DAX semantic analysis).
open
Open a model in Tabular Editor 3 Desktop. Windows only (requires TE3 to be installed).
te open ./my-model
init
Create a new empty semantic model at the given path.
te init ./new-model
Model editing
set
Set a property on a model object. Accepts a <path>.
te set accepts:
-q <property>- property name (e.g.,expression,formatString,description,isHidden).-i <value>- value (use-to read from stdin).--save/--save-to <path>- persist changes.
te set Sales/Amount -q expression -i "SUM(Sales[Amt])" --save
te set "'Net Sales'[Sales Amount]" -q formatString -i "#,0" --save # DAX form with spaced names
te set Sales -q isHidden -i true --save
add
Add an object to the model. Pass a <path> for the new object (the parent must already exist; the leaf segment is the new name) and the type via -t / --type. Relationships keep their shorthand syntax (Sales[Key]->Dim[Key]).
te add accepts:
-t, --type <type>- object type. Common values:Table,Measure,Column,CalculatedColumn,Hierarchy,Role,Perspective,Culture,CalculationGroup,CalculationItem. Tab-completion is supported; the full list can be retrieved by runningte add --help.--if-not-exists- exit0without error if the object already exists. Use this for idempotent CI/CD pipelines.
te add Sales/Revenue -t Measure -i "SUM(Sales[Amount])" --save
te add Sales -t Table --save
te add "Sales[ProdKey]->Product[ProdKey]" --save # Relationship shorthand
te add Sales/MarketingFlag -t CalculatedColumn -i "Sales[Amount] > 1000" --if-not-exists --save
te add Perspectives/Default/Sales --save # Include Sales in the Default perspective
te add Roles/Reader -t Role --save # New role at the model level
For data-bound tables, te add also supports schema detection from SQL, Lakehouse, or Warehouse sources. See te add --help for --source, --endpoint, --source-table, --columns, etc.
rm
Remove an object. Checks dependents by default to prevent breaking existing references.
te rm accepts:
<path>— positional argument: the object to remove.--force— bypass the dependents check.--if-exists— exit0without error if the object doesn't exist. Use this for idempotent CI/CD pipelines.--dry-run— preview the removal without applying it.--save— persist the change to the loaded model.
te rm Sales/Revenue --save
te rm "'Sales'[Revenue]" --save # DAX form
te rm Sales/Revenue --dry-run # Preview only
te rm Sales/OldMeasure --if-exists --save # Idempotent
mv
Move or rename a model object. Both source and destination are <path> arguments.
te mv Sales/Revenue Finance/Revenue --save # Move measure to another table
te mv Sales/Revenue Sales/TotalRevenue --save # Rename measure
replace
Find and replace text across model objects. Dry-run by default; add --save to apply.
te replace accepts:
--in <scope>- scope:names,expressions,descriptions,displayFolders,formatStrings,annotations,all(default:all).--regex- treat the find pattern as a regular expression.--case-sensitive- enable case-sensitive matching.--dry-run- preview changes without applying. Default behavior.--save- persist the mutation to the source location. Mutually exclusive with--revertand--stage.--save-to <path>- save to a different path (implies--save).--serialization <fmt>- model serialization:tmdl,bim,te-folder.--force- save even if the replacement introduces DAX validation errors.
--in expressions walks every expression-bearing property:
- Measure:
Expression,DetailRowsExpression - KPI:
TargetExpression,StatusExpression,TrendExpression - Partition: source M, polling M
- Table permission:
FilterExpression - Calculation group: selection expressions
- Calculated column: DAX expression
Adding new expression-shaped properties to the model surfaces them automatically.
te replace "OldTable" "NewTable" --in expressions --save
te replace "SUM" "SUMX" --regex --in expressions --save
Inspection
ls
List objects with filesystem-like navigation. Takes a <path-filter> argument supporting wildcards. Both model-level containers (Tables, Measures, Columns, Hierarchies, Relationships, Roles, Perspectives, Cultures) and table-scoped containers (Sales/Measures, Sales/Columns, …) are supported.
te ls accepts:
--type <kind>- narrow to one object kind (table,measure,column,hierarchy,partition,relationship,role,perspective,culture). With no<path-filter>this is equivalent to typing the matching container keyword.--paths-only- emit one object path per line, suitable for piping toxargs,te get, orte set.--no-multiline- collapse multi-line cells (typically DAX or M expressions) to a single line and truncate, so rows stay scannable in wide tables. Text output only; JSON/CSV/TMSL output is unaffected.--output-format tmsl(aliasbim) - emit the matching objects as a TMSL/BIM script. Useful forte ls Tables --output-format bim > tables.json.--output-format tmdlis not supported byls(TMDL is single-object only - usete get).
te ls # All tables in the model
te ls Sales # All children of Sales (columns + measures + hierarchies + partitions)
te ls Sales/Measures # Just Sales's measures
te ls 'Sales/*Amount' # Children of Sales whose name ends with Amount
te ls 'Sa*' # Tables whose name starts with Sa (no auto-expansion)
te ls '*/Amount' # An Amount column/measure across every table
te ls 'Roles/Re*/Members' # Members of every role matching Re*
te ls Sales/Geography/Levels # All levels of the Geography hierarchy
te ls "'Net Sales'/'Sales Amount'" # Quote names containing spaces
te ls Measures --paths-only # One Table/Measure per line for piping
te ls --type measure # Same as `te ls Measures`
te ls Measures --no-multiline # Wide table with column dividers, single-line DAX
te ls Tables --output-format bim > tables.json # All tables emitted as TMSL/BIM
get
Get properties of a model object. Takes a <path>.
te get accepts:
-q, --query <property>- fetch a single property (e.g.expression,formatString).-t, --type <kind>- disambiguate when the path matches multiple table-children (e.g. a column and a hierarchy with the same name). Values:Measure,Column,CalculatedColumn,Hierarchy,Calendar,Partition,CalculationItem.--output-format tmsl(aliasbim) - emit the resolved object as TMSL/BIM JSON.--output-format tmdl- emit the resolved object as TMDL (named objects only).
te get and te ls share a single descriptor catalog, so every property surfaces the same way across formats - the text table, JSON, and CSV all see the same set, and adding a new property to the model exposes it everywhere.
te get Sales/Amount -q expression # Print DAX
te get "'Sales'[Amount]" # DAX form: same as Sales/Amount
te get "[Total Sales]" # Lone-bracket: model-wide measure-or-column
te get "'Net Sales'[Sales Amount]" -q expression # DAX form with spaced names
te get "Sales/Revenue/KPI" # KPI sub-object of a measure
te get Sales --output-format tmdl # Emit the table as TMDL
te get Sales --output-format bim # Emit the table as TMSL/BIM
te get Model -q description
find
Search for text across model objects.
te find accepts:
--in <scope>- as perte replace(defaultall).--regex,--case-sensitive,--paths-only.--no-multiline- collapse multi-line match context to a single line. Text output only.
--in expressions covers every IExpressionObject in the model - including KPI TargetExpression / StatusExpression / TrendExpression, measure DetailRowsExpression, partition source/polling M, table-permission FilterExpression, and calculation-group MultipleOrEmptySelection / NoSelection expressions - so a literal like 123 set on a KPI's target turns up the same way a measure body would.
te find "CALCULATE" --in expressions
te find "Revenue" --in names
te find "CALCULATE" --in expressions --paths-only | xargs -I{} te get {} -q expression
diff
Compare two models for structural differences. Returns the following exit codes: 0 = identical, 1 = differences found, 2 = error.
te diff ./model-v1 ./model-v2
te diff old.bim new.bim
deps
Analyze an object's upstream and downstream dependencies, or surface unused objects across the model. The single-object form takes a <path>.
te deps accepts:
--unused- list measures, calculated columns, and all data columns that no DAX references and that aren't used in any relationship, hierarchy level, sort-by, variation, AlternateOf base, or calendar time role. Each result shows(hidden)in text mode and anisHiddenfield in JSON.--hidden- narrow--unusedto hidden objects only. Hidden, unused objects are the safest prune candidates because nothing user-facing depends on them.
te deps Sales/Revenue # Upstream + downstream for one object
te deps "'Sales'[Revenue]" # DAX form is accepted everywhere a <path> is
te deps --unused # All unused measures and columns
te deps --unused --hidden # Only hidden, unused objects
Analysis and quality
validate
Validate model expressions, schema integrity, and TOM errors.
te validate accepts:
--ci <fmt>- emit CI annotations to stderr:vstsorgithub.--trx <path>- write results as a VSTEST.trxfile.
te validate ./model
te validate --ci github --trx results.trx
bpa run
Run Best Practice Analyzer rules against a model.
te bpa run accepts:
<model>- positional argument: path to model (alternative to the--modelglobal flag).-r, --rules <rules>- path(s) or URL(s) to BPA rule file(s) in JSON format. Repeatable. Replaces the user-rule layer for this invocation: see Rule sources and resolution below.--no-model-rules- exclude BPA rules embedded in the model's annotations.--no-defaults- exclude built-in default BPA rules.--vpax <file>- load VertiPaq Analyzer stats from a.vpaxfile to enable VPA-aware rules.--vpa-rules- include built-in VPA-aware rules (requires--vpaxor a pre-annotated model).--allow-external-rules- allow fetching BPA rule files from URLs embedded in model annotations.--rule <id>- run only specific rule(s) by ID. Repeatable.--path <path-filter>- limit analysis to the tables containing the matched objects. Accepts literal names, container keywords, and wildcards (e.g.,'Sales','Sa*','Sales/Measures','*/Amount').--fix- apply fix expressions to auto-fix violations where possible.--save- save the model back to source after applying fixes.--save-to <path>- save the model to a different path after applying fixes.--serialization <fmt>- model serialization:tmdl,bim,te-folder.--fail-on <severity>- failure threshold:error(default) orwarning. Exits with code1when violations meet the threshold.--ci <fmt>- emit CI logging commands to stderr:vsts(Azure DevOps),github(GitHub Actions).--trx <path>- write results as a VSTEST.trxfile to the specified path.--no-multiline- collapse multi-line cell content in the violations table to a single line. Text output only.
te bpa run --fail-on error --ci github
te bpa run --fix --save
te bpa run --rule PERF_UNUSED_HIDDEN_COLUMN
te bpa run --path Sales # Tables touched by the Sales filter only
te bpa run --path 'Sa*' # Wildcard - every table starting with Sa
te bpa run --path Sales/Measures # Path filter applied to the matched tables
Rule sources and resolution
Each te bpa run invocation assembles rules from three independent layers:
- User rules - exactly one source wins, in priority order:
-r, --rules <rules>flag, accepts a file path or URL (highest)TE_BPA_RULESenvironment variablebpa.rulesarray from CLI config (~/.config/te/config.json)
- Built-in defaults - loaded unless
--no-defaultsis passed orbpa.builtInRulesisfalsein config. Individual built-ins listed inbpa.disabledBuiltInRuleIdsare skipped. - Model-embedded rules - rules in the model's
BestPracticeAnalyzer_Rulesannotation, loaded unless--no-model-rulesis passed. External URL annotations are skipped unless--allow-external-rulesis also passed.
Duplicate rule IDs are de-duplicated (user rules win over built-ins). Rule IDs in the model's BestPracticeAnalyzer_IgnoreRules annotation are then removed.
The Rules loaded: line in the output attributes each contributing layer, for example:
Rules loaded: 41 from 1 file(s) from bpa.rules config + built-in defaults + model annotations
bpa rules
Manage BPA rule collections — list, inspect, initialize, and toggle rules in your local rules file or in model annotations. Built-in rules are read-only - to skip one without losing the rest, use te bpa rules disable (do not edit the built-in set directly).
Subcommands:
| Subcommand | Purpose |
|---|---|
add <id> [model] |
Add a new BPA rule. |
disable |
Disable a built-in BPA rule for the current user. |
enable |
Re-enable a previously disabled built-in BPA rule. |
ignore <rule-id> [model] |
Add a rule to the model's ignore list. |
init |
Create an empty BPA rules file at the resolved path. |
list |
List BPA rules from all sources with status. |
rm <rule-id> [model] |
Remove a BPA rule. |
set <rule-id> [model] |
Update a BPA rule's properties. |
unignore <rule-id> [model] |
Remove a rule from the model's ignore list. |
All te bpa rules subcommands accept:
--rules-file <path>- path to a BPA rules JSON file. Defaults to the first existing entry ofbpa.rulesin your CLI config (~/.config/te/config.json), or theTE_BPA_RULESenvironment variable.--model-rules- operate on rules embedded in the model annotation instead of a file.
Important
te bpa rules set and te bpa rules rm refuse to mutate built-in rule IDs. Attempting to do so exits with code 1 and points at te bpa rules disable. To customize a built-in rule's behavior, disable the built-in and add a custom copy with a different ID:
te bpa rules disable TE3_BUILT_IN_DATE_TABLE_EXISTS
te bpa rules add MY_DATE_TABLE_EXISTS
bpa rules list
List rules from all sources (built-in, user, model).
te bpa rules list accepts:
- (default) Active rules only.
--all- include disabled and ignored rules.--disabled- only built-in rule IDs the user has disabled viate bpa rules disable.--ignored- only rules whose IDs appear inBestPracticeAnalyzer_IgnoreRuleson the model.--no-defaults- exclude built-in rules from output.
te bpa rules list # Active rules
te bpa rules list --all # Include disabled and ignored rules
te bpa rules list --ignored
Disabled built-in rules are flagged with a [disabled] marker next to the rule ID.
bpa rules init
Create an empty BPA rules file ([]) at the configured path. Use this once before invoking te bpa rules set / te bpa rules rm against a path that does not yet exist.
te bpa rules init accepts:
--force- overwrite an existing file with[]. Required if the target file exists.--rules-file <path>- target file path. Can appear before or after theinitsubcommand.
Path resolution (first match wins): --rules-file → TE_BPA_RULES env var → first entry of bpa.rules[] in your CLI config → ./BPARules.json (current working directory).
te bpa rules init
te bpa rules init --rules-file ./MyRules.json
te bpa rules init --force
bpa rules disable
Disable an individual built-in BPA rule. The rule ID is added to bpa.disabledBuiltInRuleIds in your CLI config. Subsequent gate runs (deploy, save, mutation) and te bpa run skip the disabled rule.
The command is idempotent — running disable against an already-disabled rule succeeds without modifying the config. It exits with code 1 if <rule-id> is not a built-in rule; use te bpa rules list to see valid built-in IDs.
te bpa rules disable TE3_BUILT_IN_DATE_TABLE_EXISTS
bpa rules enable
Re-enable a previously disabled built-in BPA rule by removing the rule ID from bpa.disabledBuiltInRuleIds. Exits with code 1 if the rule isn't currently disabled.
te bpa rules enable TE3_BUILT_IN_DATE_TABLE_EXISTS
vertipaq
Analyze VertiPaq storage statistics.
te vertipaq accepts:
--columns,--relationships,--partitions,--all.--export <file.vpax>- export VertiPaq stats to a.vpaxfile for offline analysis.--import <file.vpax>- load a previously exported.vpaxfile and analyze it offline.--obfuscate- obfuscate names and expressions in exported VPAX.--top <N>,--stats,--annotate,--save.
te vertipaq # Columns by size (default)
te vertipaq --all # Tables, columns, relationships, partitions
te vertipaq --export stats.vpax
te vertipaq --import stats.vpax # Analyze offline
format
Format DAX or M/Power Query expressions.
te format accepts:
-e, --expression <text>- format a single inline expression.-p, --path <path>- format a specific measure/column.--lang <dax|m>- defaultdax.--save/--save-to- persist formatted expressions.
te format --save # Format all DAX
te format -p Sales/Amount --save # Single measure
te format -e "SUM ( Sales[Amount] )" # Inline
te format --lang m --save # Format M
Execution
query
Execute a DAX query against a deployed model.
te query accepts:
-q, --query <dax>- inline query.--file <file.dax>- query from file.--limit <N>- default 100.-o, --output-file <path>- write results to file (.csv,.tsv,.json,.dax).--trace,--cold,--plan,--runs <N>- performance tracing and benchmarking.--no-validate- skip pre-execution DAX semantic validation.
te query -q "EVALUATE TOPN(5, 'Sales')" -s my-ws -d my-model
te query --file query.dax --output-format json
script
Execute one or more C# scripts against a semantic model. The CLI uses the same scripting host as Tabular Editor 3 Desktop, so a script that runs in TE3 runs unchanged here.
te script accepts:
-S, --script <file>-.cs/.csxfile (repeatable).-e, --expression <code>- inline C# (use-for stdin).--save/--save-to/--serialization.--dry-run,--timeout <seconds>.
te script --script fix.cs --save
te script -e "Info(Model.Tables.Count)"
echo "Info(Model.Name);" | te script -e -
Important
Two behavioral details to know if you're porting an older script:
- No interactive selection in CLI scripts. The TE3 Desktop helpers
SelectMeasure(),SelectTable(),SelectColumn(),SelectObject(), andSelectObjects()throwNotSupportedExceptionwhen called fromte script- the CLI has no UI to pop up. Pre-resolve the object(s) outside the script and pass them in, or wrap the call intry/catchif the script is shared with TE3. - Default
usingdirectives match TE3 Desktop. Scripts that useDataTable,File,StringBuilder, orRegexmust include the correspondingusing System.Data;/using System.IO;/using System.Text;/using System.Text.RegularExpressions;directive explicitly.
Note
Preprocessor symbols for cross-host scripts. Scripts compiled by te script have the symbol TECLI defined. TE3 Desktop scripts have TE3 defined instead, plus version-bracketed symbols like TE3_3_10_OR_GREATER ... TE3_3_X_OR_GREATER for the current TE3 minor version. TE2 defines neither symbol. Use these to write portable scripts:
#if TECLI
// CLI-only code - no UI calls
Info($"Running under the CLI on {Environment.OSVersion.Platform}");
#elif TE3
// TE3 Desktop-only code - UI APIs available
ShowMessage("Hello from TE3");
#else
// TE2 (legacy) - neither TECLI nor TE3 is defined
Info("Hello from TE2");
#endif
#if TE3_3_15_OR_GREATER
// Gated on a specific TE3 minor version
#endif
See C# Scripts for the broader cross-version scripting story.
macro
Manage and run macros from a macros JSON file (typically MacroActions.json). The macros file is resolved in this order: --macros <path> → TE_MACROS_PATH env var → macros in CLI config → ./MacroActions.json.
Subcommands:
| Subcommand | Purpose |
|---|---|
list |
List macros. |
run <name-or-id> |
Run a macro. |
add <name> |
Add a macro. |
set <name-or-id> |
Update macro properties. |
rm <name-or-id> |
Remove a macro. |
sort |
Sort and re-assign IDs. |
init |
Create an empty macros file at the resolved path. |
macro init
Create an empty macros file ({"Actions":[]}) at the configured path. Use this once when the resolved macros file does not yet exist.
te macro init accepts:
--force- overwrite an existing file. Required if the target exists.--macros <path>- target file path. Can appear before or after theinitsubcommand.
te macro init
te macro init --macros ./project-macros.json
te macro init --force
macro run
Run a macro. Macros that emit tables via dataTable.Output() render formatted output in the terminal, so DAX-style query macros work the same in te macro run as they do in TE3.
te macro run accepts:
--on <path>- set the macro's selection context to a single named object (a table, measure, column, …). Equivalent to right-clicking that object in TE3 and invoking the macro from the context menu.--save/--save-to- persist any changes the macro makes.
te macro run "Hide all measures"
te macro run "Format DAX" --on Sales/Revenue --save
te macro run "Format DAX" --on "'Net Sales'[Sales Amount]" --save # DAX form works in --on too
Deployment and refresh
deploy
Deploy a semantic model to Power BI, Fabric, or Azure Analysis Services.
te deploy accepts:
-s, --server/-d, --database- target workspace and model.--deploy-full- overwrite + connections + partitions + shared expressions + roles + role members.--deploy-connections--deploy-partitions--skip-refresh-policy--deploy-roles--deploy-role-members--deploy-shared-expressions--create-only--xmla <file>- generate XMLA/TMSL script instead of deploying (-for stdout).--skip-bpa- bypass the BPA gate entirely.--fix-bpa- auto-fix BPA violations where rules define a fix expression.--bpa-rules <path>- repeatable; overridebpa.rulesfrom your CLI config for this single deploy. Built-in rules still apply unlessbpa.builtInRulesisfalse.--force- skip interactive confirmation (required for CI).--ci <fmt>-vstsorgithub.--profile <name>- one-shot use of a saved Authentication and Connections profile.
te deploy ./model -s my-workspace -d my-model --force --ci github
te deploy ./model --xmla script.tmsl # Generate TMSL only
te deploy ./model --profile staging --force
Important
te deploy runs the Best Practice Analyzer as a gate before executing. In interactive mode, a summary + confirmation prompt is shown with n as the safe default. In CI, pass --force to skip the prompt. See Custom Configuration for BPA gate configuration.
refresh
Trigger a data refresh on a deployed model.
te refresh accepts:
--type <type>-full,dataonly,automatic,calculate,clearvalues,defragment,add(default:automatic).--table <name>- refresh specific table(s); repeatable.--partition <Table.Partition>- refresh specific partition(s).--apply-refresh-policy- apply the incremental refresh policy to determine which partitions are refreshed.--effective-date <yyyy-MM-dd>- set the effective date used by the refresh policy.--max-parallelism <N>- set the maximum number of partitions to refresh in parallel.--dry-run- output the TMSL script without executing.--no-progress,--trace [path].
te refresh --type full # Full refresh
te refresh --table Sales --type full # Single table
te refresh --type full --dry-run > refresh.tmsl # Emit TMSL only
incremental-refresh
Manage incremental refresh policies on tables.
te incremental-refresh show <table>
Additional subcommands (set, remove, apply) are documented via te incremental-refresh --help.
Testing
test run
Run a suite of DAX assertion tests against a deployed model.
te test run accepts:
--suite <path>- test-suite directory (default:.te-tests/).--tag <tag>- only tests with this tag.--fail-on <severity>-error(default) orwarning.--ci <fmt>,--trx <path>- CI annotations and TRX output.
te test run --ci github --trx results.trx
te test run --tag revenue
test init / spec / use / list / snapshot / compare
Additional subcommands scaffold tests, print the assertion spec format, switch the active suite, list suites, capture snapshots, and compare models. See te test --help for details.
te test init --example # Scaffold an example suite
te test spec # Print the full assertion format reference
te test init --from-model --model ./my-model # Generate stubs from your measures
Connection and authentication
connect
Set (or display) the active connection for the current terminal session. See Authentication and Connections.
te connect # Show current active connection
te connect my-workspace my-model # Remote
te connect ./model # Local
te connect --local # Power BI Desktop (Windows)
te connect --profile prod # Activate a saved profile
te connect --clear # Clear the active connection (and any workspace mirror)
Workspace mode (-w / --workspace)
Pair a primary source with a secondary target so every subsequent --save mirrors the model between the two. Useful for keeping a local working copy of a remote workspace, or pushing local edits to a workspace as you save.
te connect <ws> <model> -w ./src- primary is remote;./srcreceives an initial TMDL export and mirrors every save.te connect ./src -w <ws> <model>- primary is local; an initial deploy pushes the model to the workspace, and subsequent saves re-deploy automatically.--workspace-format <bim|tmdl>- choose the on-disk format when mirroring to a folder/file (e.g.,-w ./model.biminfers BIM).--force- required when the target already exists (non-empty folder, existing database). Without it,te connectshows an interactivey/nprompt withnas the safe default.
Once active, te set --save, te rm --save, te script --save, etc. all dual-save transparently. Save order is always local first, then remote so the on-disk copy reflects the latest user change even if the server push fails. Clear the mirror with te connect --clear.
te connect Finance "Revenue Model" -w ./revenue-model # Mirror remote → local TMDL
te connect ./revenue-model -w Finance "Revenue Model" # Mirror local → remote
auth login / status / logout
Manage cached authentication. See Authentication and Connections.
profile list / show / set / remove
Manage named connection profiles. See Authentication and Connections.
Configuration
config show / paths / init / set
View and manage CLI configuration and TE3 path overrides. See Custom Configuration.
te config show # Display all settings
te config paths # Resolved TE3 file paths
te config init # Create default config
te config set autoFormat true
license
te license is reserved for the GA release and is not available in this preview build. The command is still wired up to the parser - so existing scripts that invoke it won't blow up at parse time - but every subcommand exits with status 1 and a "not available in this preview build" message. See the Preview notice on the overview page for the broader licensing outlook.
migrate
Reference guide showing how legacy Tabular Editor 2 CLI flags map to the new CLI. Useful as a live lookup while porting a TE2-based pipeline. See Migrating from the TE2 Command Line for the full migration guide.
te migrate # Full flag mapping table
te migrate -A # Look up a single TE2 flag
te migrate --output-format json # Machine-readable mapping
Shell
interactive
Start a guided REPL session with a model-aware prompt. See Interactive Mode.
te interactive # Connect later
te interactive ./model # Start with a local model
te interactive -s MyWorkspace -d MyModel # Start with a remote model
Quoting and DAX-style references work the same as outside the session - see the Object paths section above and Interactive Mode for details on bracket-aware argv splitting inside the REPL.
completion
Generate a shell completion script. See Installation and Setup.
te completion bash
te completion zsh
te completion pwsh
Exit codes
| Exit | Meaning |
|---|---|
0 |
Success. |
1 |
Generic failure (invalid arguments, command failed, validation errors, auth failure, BPA gate failed at severity ≥ error). |
2 |
Non-zero diff (te diff) - models differ. |
For fine-grained control in CI pipelines, combine exit codes with --ci <vsts/github> annotations and --trx results files - see CI/CD Integration.
Related pages
- Tabular Editor CLI (Limited Public Preview) - overview and framing.
- Installation and Setup - install and set up the CLI.
- Authentication and Connections - authenticate and manage connections.
- Custom Configuration - configuration file, BPA gate, post-mutation behavior.
- Migrating from the TE2 Command Line - TE2 → TE3 flag mapping.