Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a745923
Added documentation for new Tabular Editor CLI in Limited Public Prev…
gronnerup Apr 20, 2026
60a727c
Delete .claude/settings.local.json
gronnerup Apr 21, 2026
8ab7a67
Added link to the GitHub repo for issues and discussions. Updated git…
gronnerup Apr 22, 2026
9daf2bf
Merge branch 'user-pg/te-cli-limitedPuPr-docs' of https://github.com/…
gronnerup Apr 22, 2026
e32234f
Include file for preview notice
mlonsk Apr 23, 2026
bcd0add
Updates based on Jeroen's comments
mlonsk Apr 23, 2026
c097f53
Update config titel
mlonsk Apr 23, 2026
4f26bbe
Update docs for CLI to comply with latest changes in commands, flags,…
gronnerup May 6, 2026
63a9386
cli docs refinement (#318)
otykier May 12, 2026
a6c1900
Update te-cli docs to reflect TE3 PR 3201 (CLI - Remove TE3 dependenc…
MariaJoseFF May 13, 2026
7094115
Added limitations page and polished text on all cli doc pages
gronnerup May 20, 2026
d1fb165
Merge branch 'user-pg/te-cli-limitedPuPr-docs' of https://github.com/…
gronnerup May 20, 2026
b877973
Adjusted cicd and install docs. Emphasize CLI limited preview limitat…
gronnerup May 20, 2026
3cf7742
docs(cli): refresh BPA rule limitations after resolver wiring
gronnerup May 20, 2026
6e41cc0
docs(cli): rename --output to --output-format, --format to --serializ…
otykier May 26, 2026
e4488a0
Update cli docs with correct link and verified all commands, subcomma…
gronnerup May 26, 2026
89ffece
Update incorrect download link
gronnerup May 26, 2026
ceb31ce
Added connect example to different org.
gronnerup May 27, 2026
61941a5
Update CLI Configs to reflect latest config options also adding addit…
gronnerup May 27, 2026
66742bf
Added framing on the use of Python
gronnerup May 27, 2026
578da45
Update intro, cicd and interactive based on review feedback
gronnerup May 27, 2026
962d1c5
Merge remote-tracking branch 'origin/main' into user-pg/te-cli-limite…
gronnerup May 27, 2026
d4c9e02
Stop tracking generated docfx.json
gronnerup May 27, 2026
c888ad3
Promote platform-table caveat to IMPORTANT callout
gronnerup May 27, 2026
a36c109
Moved TE CLI above old CLI in ToC and added warning on overview page …
gronnerup May 27, 2026
5b2b3dc
Address review feedback on auth, path quoting, and CLI scripting
gronnerup May 27, 2026
060105e
Rephase risks in pipelines during preview
gronnerup May 27, 2026
d4ec093
Removed section on DaxFormatter limitations
gronnerup May 27, 2026
8da134d
Added images for preview notice and ls command
gronnerup May 27, 2026
dc2708e
Apply review feedback on auth docs
gronnerup May 28, 2026
2cf8378
Apply review feedback on overview and install docs
gronnerup May 28, 2026
a6e6d9f
Apply review feedback on command reference
gronnerup May 28, 2026
405deca
Apply review feedback across cli docs
gronnerup May 28, 2026
566bb5d
Apply review feedback on config page
gronnerup May 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/metadata/languages.json


###############
# folder #
###############
Expand All @@ -21,6 +20,9 @@ artifacts/
target/
/_site/

# Generated by gen_redirects.py at build time from docfx-template.json
/docfx.json

# Localized content
/localizedContent/en/
/localizedContent/*/docfx.json
Expand All @@ -31,6 +33,7 @@ target/

.vscode/
.vs/
.claude/

###############
# temp file #
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions content/features/Command-line-Options.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
---
uid: command-line-options
title: Command Line
title: Command Line (Tabular Editor 2)
author: Daniel Otykier
updated: 2021-08-26
applies_to:
Expand All @@ -10,7 +10,10 @@ applies_to:
- product: Tabular Editor 3
none: true
---
# Command Line
# Command Line (Tabular Editor 2)

> [!TIP]
> Looking for the new cross-platform CLI? See @te-cli for the Tabular Editor CLI (Limited Public Preview), a successor that runs on Windows, macOS, and Linux.

Tabular Editor can be executed from the command-line to perform various tasks, which may be useful in Automated Build and Deployment scenarios, etc.

Expand Down
25 changes: 18 additions & 7 deletions content/features/csharp-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
uid: csharp-scripts
title: C# Scripts
author: Daniel Otykier
updated: 2026-03-19
updated: 2026-05-27
applies_to:
products:
- product: Tabular Editor 2
Expand All @@ -15,6 +15,8 @@ applies_to:
full: true
- edition: Enterprise
full: true
- product: Tabular Editor CLI
full: true
---
# C# Scripts

Expand Down Expand Up @@ -366,18 +368,27 @@ Info($"Configured model for {environment} environment");
<a name="compatibility"></a>
## Compatibility

The scripting APIs for Tabular Editor 2 and Tabular Editor 3 are mostly compatible, however, there are cases where you want to conditionally compile code depending on which version you're using. For this, you can use preprocessor directives, which were introduced in Tabular Editor 3.10.0.
The scripting APIs for Tabular Editor 2, Tabular Editor 3 (Desktop), and the Tabular Editor CLI are mostly compatible, but there are cases where you want to conditionally compile code depending on which host is running. The CLI host defines a `TECLI` preprocessor symbol; TE3 Desktop defines `TE3` (and version-bracketed symbols like `TE3_3_15_OR_GREATER` for the active minor); TE2 defines neither. Preprocessor directives were introduced in Tabular Editor 3.10.0. Use them to write portable scripts:

```csharp
#if TE3
// This code will only be compiled when the script is running in TE3 (version 3.10.0 or newer).
Info("Hello from TE3!");
#if TECLI
// CLI host - no UI APIs available
Info($"Running under the CLI on {Environment.OSVersion.Platform}");
#elif TE3
// TE3 Desktop - UI APIs are available
ShowMessage("Hello from TE3");
#else
// This code will be compiled in all other cases.
Info("Hello from TE2!");
// 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
```

One CLI-specific caveat: the TE3-Desktop UI helpers `SelectMeasure()`, `SelectTable()`, `SelectColumn()`, `SelectObject()`, and `SelectObjects()` throw `NotSupportedException` under `te script` since the CLI has no UI to pop up. Wrap such calls in `#if TE3` (or `try/catch`) when sharing scripts across hosts.

If you need to know the exact version of Tabular Editor at script runtime, you can inspect the assembly version:

```csharp
Expand Down
2 changes: 2 additions & 0 deletions content/features/te-cli/includes/te-cli-preview-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
> [!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.
225 changes: 225 additions & 0 deletions content/features/te-cli/te-cli-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
---
uid: te-cli-auth
title: Authentication and Connections
author: Peer Grønnerup
updated: 2026-05-06
applies_to:
products:
- product: Tabular Editor 2
none: true
- product: Tabular Editor 3
none: true
- product: Tabular Editor CLI
Comment thread
gronnerup marked this conversation as resolved.
full: true
---
# Authentication and Connections

[!INCLUDE [te-cli-preview-notice](includes/te-cli-preview-notice.md)]

The Tabular Editor CLI authenticates to Power BI Service, Microsoft Fabric, and Azure Analysis Services using the same Power BI Desktop client ID that Tabular Editor 3 uses. Tokens are cached locally so you authenticate once and re-run commands silently until the refresh token expires (typically 90 days).
Comment thread
gronnerup marked this conversation as resolved.

## Authentication methods

The CLI supports the full Azure Identity credential chain:

| Method | When to use | `--auth` value |
| -- | -- | -- |
| Interactive browser | Local development - opens the system browser | `interactive` (default) |
| Service principal (client secret) | Automation, CI/CD, headless / SSH / WSL | `spn` (with `-u / -p / -t`) or `env` |
| Service principal (certificate) | Automation with certificate-based auth | `spn` (with `-u / -t / --certificate`) |
| Environment variables | `AZURE_CLIENT_ID` / `AZURE_CLIENT_SECRET` / `AZURE_TENANT_ID` | `env` |
| Managed identity | Azure VMs, Azure Container Apps, Azure Functions | `managed-identity` |

> [!NOTE]
> `--auth` is a **global** option, available on every `te` command - not just `te auth login`. Pass it to [`te deploy`](xref:te-cli-commands#deploy), [`te refresh`](xref:te-cli-commands#refresh), [`te query`](xref:te-cli-commands#query), [`te connect`](xref:te-cli-commands#connect), or any other command that connects to a remote endpoint, to override the default chain for that invocation. The default (`auto`) tries environment credentials first, then falls back to the cached or interactive browser login.

For headless, SSH, WSL, or devcontainer scenarios, use a service principal - `te auth login -u <id> -p <secret> -t <tenant>` (or `--certificate`). The login is cached, so subsequent commands acquire tokens silently with `--auth auto`.

## `te auth login`

Authenticate and cache the result for subsequent commands:

```bash
Comment thread
gronnerup marked this conversation as resolved.
# Browser-based interactive login (default)
te auth login

# Service principal with client secret
te auth login -u "$AZURE_CLIENT_ID" -p "$AZURE_CLIENT_SECRET" -t "$AZURE_TENANT_ID"

# Service principal - read secret from stdin
echo "$AZURE_CLIENT_SECRET" | te auth login -u "$AZURE_CLIENT_ID" -p - -t "$AZURE_TENANT_ID"

# Service principal with certificate
te auth login -u "$AZURE_CLIENT_ID" -t "$AZURE_TENANT_ID" --certificate ./sp.pfx --certificate-password "$CERT_PASSWORD"

# Managed identity (Azure-hosted)
te auth login --identity
```

After a successful service-principal login the CLI **caches the credentials** so every subsequent `te` command can acquire tokens silently - no need to re-pass `-u / -p / -t` or set the `AZURE_CLIENT_*` environment variables. Pass `--save=false` for a one-shot login that doesn't update the cache, or run `te auth logout` to clear it.

> [!WARNING]
> Passing secrets directly on the command line exposes them to process listings and shell history. Prefer the `AZURE_CLIENT_SECRET` environment variable, or pipe the secret via stdin with `-p -`.

## `te auth status`

Display the current authentication state without opening a browser:

```bash
Comment thread
gronnerup marked this conversation as resolved.
te auth status
te auth status --output-format json
```

This returns an exit code of `0` when a valid session exists, `1` when not logged in or expired.

## `te auth logout`

Clear all cached credentials:

```bash
te auth logout
```

## Credential storage

The CLI stores access/refresh tokens and service-principal records in the **OS-native secure store** by default. A `0600` file fallback is selected automatically only when the OS keystore is unavailable (e.g., headless Linux without libsecret/D-Bus).

| Platform | Backend | Storage location |
| -- | -- | -- |
| Windows | DPAPI | Per-user, managed by MSAL |
| Linux | libsecret (system keyring) | Per-user, managed by MSAL |
| macOS | Keychain | Service `com.tabulareditor.cli.*`, account `te-msal-cache.bin` |
| Any (fallback) | `0600` file | `~/.te-cli/te-msal-cache.bin` and per-key `.bin` blobs |

Interactive browser and service-principal flows share the same cache; MSAL's account model distinguishes them - there are no separate `auth-record*.json` sidecar files. Run any command with `--debug` to see which backend was selected at startup.

`te auth logout` clears every cached record (both the MSAL token cache and any SPN blobs) regardless of which backend is in use.

## `te connect` - set the active connection

`te connect` persists an active connection for the current terminal session. Subsequent commands that take `-s` / `-d` can omit them:

```bash
Comment thread
gronnerup marked this conversation as resolved.
# Remote workspace
te connect my-workspace my-model

# Local TMDL folder, .bim file, or .SemanticModel container
te connect ./my-model

# Connect to a running Power BI Desktop instance (Windows only)
te connect --local

# Show the active connection
te connect

# Clear the active connection (and any workspace mirror)
te connect --clear
```

Active-connection state is per-terminal-session: opening a new terminal starts fresh.

### Workspace mode (`-w` / `--workspace`)

`te connect -w <target>` pairs a primary source with a secondary mirror so every subsequent `--save` writes to both. Use it to keep a local working copy of a remote model in sync, or to push local edits to a workspace as you save:

```bash
Comment thread
gronnerup marked this conversation as resolved.
# Mirror remote workspace ↔ local TMDL folder
te connect Finance "Revenue Model" -w ./revenue-model

# Mirror local source ↔ remote workspace (initial deploy + auto-redeploy on save)
te connect ./revenue-model -w Finance "Revenue Model"
```

Save order is always **local first, then remote**, so the on-disk copy reflects the latest user change even if the server push fails. See @te-cli-commands#workspace-mode-w--workspace for `--workspace-format`, overwrite semantics, and clearing the mirror.

## Connecting to different clouds

The CLI detects the correct scope from the server URL for:

- Power BI Service and Fabric (commercial, US Gov, China, Germany clouds)
- Azure Analysis Services (`asazure://...`)
- Local SSAS (`localhost`, named instances - Windows only)

Pass an XMLA endpoint, workspace name, or `powerbi://` URL as `--server`:

```bash
Comment thread
gronnerup marked this conversation as resolved.
te connect "powerbi://api.powerbi.com/v1.0/myorg/Finance" "Revenue Model"
Comment thread
gronnerup marked this conversation as resolved.
te connect "powerbi://api.powerbi.com/v1.0/SpaceParts/Finance" "Revenue Model"
te connect "asazure://westeurope.asazure.windows.net/myaas" "MyModel"
te connect localhost "AdventureWorks"
```

## Connection profiles

For repeated use of the same connection - especially when you deploy to multiple environments - save named profiles:

```bash
Comment thread
gronnerup marked this conversation as resolved.
# Save remote and local profiles
te profile set prod -s my-workspace -d my-model --description "Production"
te profile set dev --model ./model --description "Local dev TMDL"

# List and inspect
te profile list
te profile show prod

# Use a profile as the active connection
te connect --profile prod

# One-shot use without changing the active connection
te deploy ./model --profile staging --force
```

Profiles can also carry behavioral overrides that take effect whenever the profile is active:

```bash
Comment thread
gronnerup marked this conversation as resolved.
# In dev, disable the BPA gate on deploy and loosen validation
te profile set dev --bpa-on-deploy false --validate-on-mutation false

# In prod, force auto-format before any mutation
te profile set prod --auto-format true
```

See @te-cli-config for the full list of overridable behaviors.

## Non-interactive authentication

For CI/CD pipelines, agents, or any unattended context, avoid interactive flows by combining:

- The `--non-interactive` global flag (fails fast instead of prompting).
- One of the non-interactive auth methods: `env`, `managed-identity`, or explicit service principal credentials.

Environment-based example for a pipeline:

```bash
export AZURE_CLIENT_ID="your-app-id"
export AZURE_CLIENT_SECRET="your-client-secret"
export AZURE_TENANT_ID="your-tenant-id"

te deploy ./model -s my-workspace -d my-model \
--auth env \
--non-interactive \
--force \
--ci github
```

See @te-cli-cicd for complete GitHub Actions and Azure DevOps Pipelines examples.

## Authentication environment variables

The CLI honors the standard Azure.Identity environment variables when you use `--auth env` (and as part of the `auto` chain):

| Variable | Purpose |
| -- | -- |
| `AZURE_CLIENT_ID` | Service principal application ID. |
| `AZURE_CLIENT_SECRET` | Service principal client secret. Used together with `AZURE_CLIENT_ID` and `AZURE_TENANT_ID`. |
| `AZURE_TENANT_ID` | Service principal tenant (directory) ID. |
| `AZURE_CLIENT_CERTIFICATE_PATH` | Path to a PEM or PKCS12 certificate file for certificate-based service principal auth. Used together with `AZURE_CLIENT_ID` and `AZURE_TENANT_ID`. |
| `AZURE_AUTHORITY_HOST` | Override the authority host for sovereign clouds (e.g., `login.microsoftonline.us`, `login.partner.microsoftonline.cn`, `login.microsoftonline.de`). Defaults to the commercial cloud. |

For CLI-specific environment variables (config paths, debug logging, TE2 compatibility), see @te-cli-config.

## Next steps

- @te-cli-commands - what you can do once connected.
- @te-cli-config - configuration and profile behavior.
- @te-cli-cicd - pipeline examples using service principals and managed identity.
Loading
Loading