Repository navigation
Releases: pschaer/PBIRelay
Release list
v1.0.1 - a sharper icon and three logging fixes
A maintenance release. It sharpens the taskbar icon, fixes three defects in how the
application logs, and adds one switch for turning log detail up. Serving, the endpoint and
the configuration you already have are all untouched.
Fixed
-
The taskbar and tray icons looked smeared, with the leftmost chart bar running into
its neighbour. The artwork was never the problem: the app built its icon from a single
256×256 image, so Windows had no other size to choose from and shrank that one picture
down to 24 pixels for the taskbar and 16 for the tray. At that reduction the one-pixel
gaps between the bars disappear.The icon file has always carried properly drawn small sizes — they simply were not being
used. Now each place the icon appears asks for the size it actually draws at. The icon
itself is unchanged; it is the same design, finally rendered at the resolution it was
drawn for. -
A crash opened a second logger. The global exception handler constructed its own
LoggerServicerather than using the one the application already owned — a second lock
object writing the samelog.txt, at the one moment you most want the file to be
trustworthy. It now shares the single instance, and only falls back to a new one if the
crash happens before that instance exists. -
Turning up the log detail forced query results into it. One setting,
LogPayloads,
did two jobs: it decided whether SOAP payloads were written and it was the only way to
raise the log from Info to Debug. So "show me which requests are arriving" and "write
every query and its results to disk" could not be asked for separately — and the second
is not something to leave on.
Added
-
VerboseLogging— the missing half of that split. It raiseslog.txtto Debug
detail, which is where per-request routing lines live, without writing payloads:"HttpBridge": { "VerboseLogging": true }
Off by default. Like
LogPayloads, it is a configuration-file setting with no control in
the UI, and it takes effect at startup.LogPayloadsstill raises the level on its own,
so nothing you had configured behaves differently.
Removed
LogConnectionInfoandLogConnectionClosed— logging helpers that described the
forwarding proxy retired back in v0.8, with no callers since — andSetMinimumLogLevel,
an unused duplicate of the setter the endpoint coordinator actually uses. Internal only;
no configuration key and no UI element disappears with them.
Upgrading from v1.0.0
Install the MSI over the top. Nothing to migrate — same configuration folder, same
endpoint, same connection strings, same aliases. An existing config.json loads unchanged;
the new VerboseLogging key is simply absent, which reads as off.
If the taskbar icon still looks the way it did, Windows is showing you a cached copy rather
than the new one — it caches icons aggressively. Signing out and back in clears it.
Install
- Installer (recommended): download
PBIRelay-v1.0.1-win-x64.msi, run it, and launch
from the Start Menu or the Power BI Desktop External Tools ribbon. - Portable ZIP: download and extract
PBIRelay-v1.0.1-win-x64.zip, then run
PBIRelay.exe.
The installer and executable are not code-signed; Windows SmartScreen warns on first run
(More info → Run anyway). The limits on what this tool claims are unchanged from v1.0.0 —
see KNOWN_LIMITATIONS.md and the
v1.0.0 notes. Full detail in CHANGELOG.md.
v1.0.0 — PBIRelay
PBIRelay v1.0.0
Two things happened: the tool got a name that describes what it does, and it earned a 1.0.
There are no new features in this release. That is the point. v1.0 adds no scope over
v0.9.0 — scope earned the version numbers up to here, and use earned this one.
The name
This project was called PBI Port Wrapper. It forwarded a TCP port, and the name said so.
Port forwarding was retired in v0.8: there is no forwarded port any more, and no fixed port
per model — models are served by name on one endpoint. The name had been describing a
transport that no longer existed for two releases.
It is now PBIRelay, which is what it actually does: it relays XMLA to the Power BI
Desktop engine and translates nothing on the way.
What that means for you:
- Configuration moves to
%APPDATA%\PBIRelay\. Nothing migrates it — copyconfig.json
across by hand, once. Absolute paths inside it still point at the old folder; a
certificate path is the likely one, and the endpoint will name the exact file it cannot
find if you miss it. - The install directory, Start Menu entry and External Tools ribbon entry are renamed. The
MSI keeps its UpgradeCode, so it upgrades your existing install rather than sitting
beside it. - Release assets are now
PBIRelay-v1.0.0-win-x64.*. Everything v0.9.0 and earlier keeps
the old name, because those artifacts install a product that calls itself that. - The repository is now
pschaer/PBIRelay. The old URL redirects.
Why 1.0 now
v0.9.0 shipped HTTPS, read-only-by-default and the access log. What it had not done was
prove any of it outside a test.
The one that mattered was certificate renewal. The endpoint picks its certificate per
connection and re-reads the source at most every five minutes, so a certificate replaced in
place goes live without a restart. That is the centrepiece of the HTTPS design — and until
this week it had never once done its job for real.
It has now:
[2026-08-16 00:08:19] HTTPS using CN=*.example.net ... valid until 2026-10-18.
[2026-08-16 00:13:26] Certificate renewed: now CN=*.example.net, valid until 2026-11-13.
No restart, no configuration change, no downtime. And the replaced file still carried its
old modification time, so the renewal never announced itself — which proved something
the planned test would not have: the reload does not watch timestamps. It re-reads on a
timer and compares thumbprints. A design that had watched modification time would have
missed this exact swap.
That is what changed between 0.9.0 and 1.0.0. Not scope — evidence.
Where the confidence stops
A 1.0 is a claim about trust, so it should say where the trust runs out.
- Only the PEM-pair certificate route has met reality. The Windows certificate store and
PFX routes have unit tests and offline rendering behind them, and no real use. - There is no first-run experience. Deliberately deferred: the app assumes someone who
already knows what it does. - The MSI and executable are unsigned. SmartScreen warns on first run — More info → Run
anyway. - Power BI Desktop must stay open, and it is unusable for editing while a model is
served. That is load-bearing rather than incidental. - This is not a replacement for the Power BI Service, Report Server or a Fabric
capacity. Check your own Power BI licensing before serving models to anyone but yourself.
See KNOWN_LIMITATIONS.md.
Upgrading from v0.9.0
- Install the MSI. It replaces PBI Port Wrapper rather than installing alongside it —
worth confirming in Settings → Apps that only one entry remains. - Copy
%APPDATA%\PBIPortWrapper\config.jsonto%APPDATA%\PBIRelay\. - Repoint any absolute paths inside it that still name the old folder.
- Re-add the External Tools entry if you use it — it is now
pbirelay.pbitool.json.
Nothing else changed. Same endpoint, same port, same connection strings, same aliases.
v0.9.0
PBI Port Wrapper v0.9.0
This project is now called PBIRelay. It was renamed after this release; v0.9.0 and everything before it shipped as PBI Port Wrapper, and the assets below keep that name because that is what they install. See v1.0.0 onward for PBIRelay.
v0.8 made the endpoint reachable. This release makes it defensible: it can be
encrypted, it refuses to change your models unless you say so, and it tells you
who has been using them.
HTTPS
Off by default, because an endpoint that stopped answering after an upgrade would be a
worse failure than one that is not yet encrypted.
The app consumes a certificate and never creates one. Serving TLS is the easy half —
being trusted is the hard one, and a certificate this app generated would be trusted by
nobody, so every client machine would need it installed by hand. That cost is exactly
what makes self-hosted TLS not worth doing. One from a CA your clients already trust
needs no client-side work at all.
XMLA endpoint… → Encrypt connections (HTTPS), then pick where the certificate comes
from:
| Source | For |
|---|---|
PEM pair — fullchain.pem + privkey.pem |
What Let's Encrypt clients and reverse proxies such as Nginx Proxy Manager hand out. Recommended |
| Windows certificate store | A certificate already installed here, by thumbprint |
| PFX file | Carrying its private key, and not password-protected |
The dialog says what your settings resolve to — subject and expiry — and will not switch
encryption on until they resolve, rather than letting the endpoint fail to start later.
Prefer the PEM pair if your certificate renews automatically. A renewed certificate is
a different certificate with a different thumbprint, so the other two routes need a
re-import or a re-conversion every sixty days. Two files replaced in place need neither:
the certificate is chosen per connection and its source re-read every few minutes, so a
renewal is live without a restart and without anything to remember.
There is deliberately nowhere to configure a certificate password. That would be a stored
credential in clear text, in the feature whose entire point is confidentiality.
Read-only by default
Every model is now served read-only: commands that would change it — Alter, Delete,
Backup, TMSL scripts — are refused with a fault naming the command, and never reach the
engine. Queries are unaffected.
Clear Read-only for a model you actually write to. It is per model, so one can be
writable while the rest are not.
Who is using my models
Every request is recorded in access.csv, next to the log: timestamp, caller, client,
model, what was asked, how it went, how long it took. Tray → XMLA endpoint →
Access log opens it in Excel, as a copy, so reading it does not stop it recording.
On by default and safe to leave on — it records that a query ran, never the query or
its results.
One less manual step
Remote access used to need a netsh http add urlacl reservation as well as a firewall
rule, and skipping it produced this design's sharpest failure: the endpoint reported
itself as running, and every remote client simply could not connect.
That is gone. The endpoint no longer runs on http.sys, so it binds every address as an
ordinary user. The firewall rule is now the only manual step. Any reservation you
added for an earlier version is harmless and can be removed with
netsh http delete urlacl url=http://+:55555/.
Also
- An endpoint that fails to start now says so, instead of leaving the reason in a log
nobody had cause to open. - Windows sign-in (Negotiate) has been removed. It needed a domain; on a workgroup the
handshake never completed, so clients hung instead of reporting an error. A stored
configuration asking for it resolves to password sign-in — never to no authentication. - Connection strings,
.odcfiles and copied URLs carry the right scheme automatically.
Upgrading
Nothing to do. Existing configuration is read unchanged, and HTTPS stays off until you
turn it on.
If you serve models to clients that write back, note that read-only is now the default
— clear it for those models after upgrading.
Known limitations
Unchanged from v0.8, except that encryption is now available rather than absent. On the
default plain-HTTP setting the endpoint is authenticated, not confidential. See
KNOWN_LIMITATIONS.md.
v0.8.0
PBI Port Wrapper v0.8.0
The release where a model stops being addressed by a port and starts being
addressed by its name.
Every served model now answers on one HTTP XMLA endpoint, at its own path:
Provider=MSOLAP;Data Source=http://your-pc:55555/Sales;Initial Catalog=Sales
One address, one firewall rule, one authentication setting — for every model. And
for the first time, from another machine, as another Windows user.
Why this replaces port forwarding
Power BI Desktop's engine (msmdsrv.exe) runs as the logged-in user and accepts
only that user, over local TCP. Forwarding a port faithfully forwards that
restriction: a colleague on another machine was never getting in, and a forwarded
port still left the database named as a per-session GUID.
The endpoint changes the shape of the problem. The wrapper is a first-class client
of the engine — it is the owner — so it authenticates callers itself and relays
their XMLA requests through. Serving already renames the database to your alias at
the source, so the name a client asks for is the name the engine actually has, and
nothing has to be rewritten in flight.
Port forwarding is therefore gone, not deprecated. So are per-model ports,
network toggles, and the Set Port UI. The alias replaced all of it.
Added
- XMLA-over-HTTP endpoint — every served model on one
port, each at its own path. One path is one server holding one engine, which is
what lets several open models work at the same time: an XMLA session belongs to
a server, so a shared address would land every session on whichever engine
answered first. - Remote and cross-user access — the gap that port forwarding could not
close. Verified end to end with Excel on a second machine. - Authentication modes — Password sign-in (default) checks the
caller against a real Windows account on the host, so it works on a workgroup;
Windows sign-in for domains; No authentication for isolated networks. - Endpoint settings in the tray and the dashboard — enable, port,
hostname override, authentication, live status and restart. Both surfaces write
the same config, so they cannot disagree. - Copy endpoint URL per served model, and
.odcfiles carrying it.
Changed
- The grid speaks aliases — Fixed Port became an editable Alias
column, Network is gone, and the Action cell is a direct Serve / Stop
button. - Two states: Off and Serve — Forward is gone as a state, an
action, and an on-detection policy. config.jsoncalls the model listModelsrather thanPortMappings, and
the per-model port and network fields are gone. Existing config files load
unchanged — aliases and on-detection policies are preserved.
Fixed
- HTTP Basic accepted any password.
HttpListenerdecodes the
credential header but does not verify it — which was misread as validation for
three releases in a row. Measured: a nonexistent user with an invented password
was admitted exactly like a real one. Passwords are now verified against Windows
directly, and nothing is stored. - Serving no longer binds or validates a port, so it cannot fail — or roll back a
completed rename — because some unrelated port was busy. - Endpoint status no longer says "LAN" when it means every interface.
⚠️ Before you expose it
-
There is no TLS. Password sign-in sends credentials base64-encoded — encoding,
not encryption — and queries and results travel in the clear. Use it on a trusted
LAN, never port-forward it from a router, and prefer a dedicated local Windows
account for remote callers. HTTPS is planned. -
Remote access needs two one-time administrative steps, or the endpoint quietly
serveslocalhostonly:netsh http add urlacl url=http://+:55555/ user=Everyone New-NetFirewallRule -DisplayName "PBI Port Wrapper XMLA" -Direction Inbound -LocalPort 55555 -Protocol TCP -Action Allow
The tray notices the localhost fallback and offers to copy the first command.
Upgrading
Install over the previous version; your config.json is read as-is and rewritten
in the new shape on the next save. Aliases and on-detection policies carry over.
Anything that connected through a forwarded port needs to be repointed at the
model's URL — tray → the model → Copy endpoint URL. Saved .odc files from
v0.7.x point at the old port and should be regenerated.
Install
- Installer (recommended): download
PBIPortWrapper.msi, run it, and launch
from the Start Menu or the Power BI Desktop External Tools ribbon. - Portable ZIP: download and extract
PBIPortWrapper-v0.8.0-win-x64.zip, then
runPBIPortWrapper.exe.
The installer and executable are not code-signed; Windows SmartScreen / Defender
warns on first run (More info → Run anyway). Full details in
CHANGELOG.md.
v0.7.1
PBI Port Wrapper v0.7.1
A small follow-up to v0.7.0 that adds the deferred Excel hand-off and fixes the
window-title version.
Added
- Save .odc… (#86) — a served model can be handed to Excel as an Office Data
Connection file. From the tray, a model with a stable alias gets a Save .odc…
action; double-clicking the saved file opens an Excel PivotTable connected to
the model — no connection string ever typed or seen. Because the alias and port are
stable across Desktop restarts, a saved.odckeeps resolving. Copy connection
string stays for DAX Studio / Tabular Editor / advanced users.
Fixed
- Window title showed "v0.5" (#113) — the title was hardcoded and never bumped
across releases. It now derives from the assembly version, so it tracks the release
automatically.
Install
- Installer (recommended): download
PBIPortWrapper.msi, run it, and launch
from the Start Menu or the Power BI Desktop External Tools ribbon. - Portable ZIP: download and extract
PBIPortWrapper-v0.7.1-win-x64.zip, then
runPBIPortWrapper.exe.
The installer and executable are not code-signed; Windows SmartScreen / Defender
warns on first run (More info → Run anyway). Full details in
CHANGELOG.md.
v0.7.0
PBI Port Wrapper v0.7.0 — Tray-first workflow
This release reworks the day-to-day workflow around the system tray and a single
Off / Forward / Serve model per Power BI Desktop instance, so keeping several
models reachable for Excel and other tools is near zero-touch.
- Off / Forward / Serve (#47) — one per-model control. Forward gives the model
a stable port; Serve additionally renames its database to a stable alias so the
connection string survives Desktop restarts. - Auto-serve on detection — each model has an On-detection policy
(Do nothing / Forward / Serve / Serve after grace period). "Serve after grace
period" shows a countdown toast with an edit instead escape before it serves. - Tray as the primary surface — the tray menu drives everything per model:
Off/Forward/Serve, the On-detection policy, an Allow network access toggle,
copy connection string, plus ready / new-model toasts. - Auto-start with Windows (#87) — opt-in checkbox; adds an
HKCU\…\Runentry,
launches silent to the tray, and self-heals the Run key if the exe is moved. - Grid ↔ tray convergence (#88) — the grid is now a diagnostics/admin surface
that projects the same state as the tray. It gained the On-detection dropdown and
Network toggle (both sync with the tray both ways), and the separate Action and
Serve columns became a single Action menu.
Fixed
- Exit while serving now restores the database name (#100) — a consolidated
serve lifecycle (one state machine + a single coordinator owning detection and
exit) fixes the exit-while-serving DB-rename-back regression, a grace-period
re-serve loop, and a startup UI freeze. - Detection under an elevated engine (#94/#95) — model names resolve by Analysis
Services port, so detection works even when the Desktop engine runs elevated.
Known limitation
The installer and executable are not code-signed, so Windows SmartScreen /
Defender warns on first run — click More info → Run anyway. See
KNOWN_LIMITATIONS.md §3 (#35).
.odc one-click Excel export (#86) is deferred to a follow-up release.
Install
- Installer (recommended): download
PBIPortWrapper.msi, run it, and launch
from the Start Menu or the Power BI Desktop External Tools ribbon. - Portable ZIP: download and extract
PBIPortWrapper-v0.7.0-win-x64.zip, then
runPBIPortWrapper.exe.
Full details in CHANGELOG.md.
v0.6.0 — Windows installer
PBI Port Wrapper v0.6.0 — Windows installer
This release adds a real Windows installer alongside the portable ZIP, so getting
PBI Port Wrapper set up as a Power BI Desktop External Tool no longer means copying
files by hand.
- MSI installer (#33) —
PBIPortWrapper.msiinstalls the app to Program Files,
replacing the download-extract-run flow. The portable ZIP is still published for
anyone who prefers it. - Start Menu integration (#34) — a PBI Port Wrapper entry launches the app.
- External Tool auto-registration (#5) — the installer registers the app as a
Power BI Desktop External Tool, so it shows up on the External Tools ribbon
after a Desktop restart, with no manualpbitool.jsoncopying. - Silent / unattended install (#36) — standard
msiexec /qnsupport for
scripted and Group Policy / SCCM / Intune deployment. - Installer documentation (#38) — build, install, silent-install, and
troubleshooting guide in docs/installer.md.
Known limitation
The installer and executable are not code-signed, so Windows SmartScreen /
Defender warns on first run — click More info → Run anyway. See
KNOWN_LIMITATIONS.md §3 (#35).
Install
- Installer (recommended): download
PBIPortWrapper.msi, run it, and launch
from the Start Menu or the Power BI Desktop External Tools ribbon. - Portable ZIP: download and extract
PBIPortWrapper-v0.6.0-win-x64.zip, then
runPBIPortWrapper.exe.
Full details in CHANGELOG.md.
PBI Port Wrapper v0.5.1
PBI Port Wrapper v0.5.1 — hardening patch
Two user-facing fixes on top of the v0.5.0 serve-sessions release:
- Single-instance guard (#64) — launching a second wrapper now fronts the
existing window and exits, instead of two processes silently sharing
config/log and competing for the same fixed ports. A crashed wrapper never
blocks the next start, so crash recovery keeps working. - Unsaved ("Untitled") models (#9) — configuration is now blocked with a
visible Unsaved status until the .pbix is saved. Previously, Set Port
looked like it worked but the rule was silently dropped or orphaned once the
model got its real name.
Full details in CHANGELOG.md.
v0.5.0 - Serve sessions with stable database names
PBI Port Wrapper v0.5.0 — Serve sessions with stable database names
External tools (Excel, DAX Studio, Tabular Editor, scripts) can now connect to
Power BI Desktop models with a stable connection string — fixed port and
fixed database name — that survives Desktop restarts:
Provider=MSOLAP;Data Source=localhost:55555;Initial Catalog=YourAlias
Highlights
- Serve sessions: give a model a stable alias, click Serve, and the
wrapper renames the workspace database to the alias and forwards the fixed
port. Click Stop Serving and Desktop is restored exactly as it was.
Saved Excel workbooks reconnect across Desktop sessions (validated E2E). - Crash recovery: if the wrapper dies mid-serve, the next start detects the
renamed database (matched by immutable database ID) and offers to resume
serving or restore the original name. Both paths live-validated. - Unsaved-changes preflight: serving warns before touching a model that may
have unsaved changes (UIA undo-heuristic probe; asks the user when unsure). - Safer alias editing: the raw "Rename DB" danger button is gone; aliases
are validated and only applied by serve sessions.
Fixes
- Config lost-update race between grid and details panel (#62)
- Manual Stop no longer bounces back while Auto-connect is enabled (#63)
Known limitations
- Power BI Desktop shows "Cannot load model" errors while serving — expected;
do not troubleshoot in Desktop, just Stop Serving to restore it. - No single-instance guard yet (#64): run one wrapper at a time.
- The unsaved-changes probe is conservative and may ask for confirmation even
right after a save.
Full details in CHANGELOG.md.
PBI Port Wrapper v0.3.0
Major Upgrade: Codebase Refactoring, System Tray & Professional Polish! 🚀
What is PBI Port Wrapper?
A TCP port forwarding proxy that provides stable port access to Power BI Desktop, solving the dynamic port problem for Excel and external tools like DAX Studio and Tabular Editor.
✨ New in v0.3.0
- System Tray Integration - Minimize to the system tray for unobtrusive background operation.
- Instant Detection - New FileSystemWatcher implementation detects Power BI instances instantly (no more polling delays!).
- Professional UI - Polished interface with a new application logo and improved layout.
- Copy Connection String - One-click button to copy the connection string for immediate use.
- External Tool Support - Register as a Power BI External Tool for easy launch from the ribbon.
- Structured Logging - Comprehensive, rotating logs for better diagnostics and troubleshooting.
🚀 Features
- Stable Port Forwarding - Fixed port numbers that don't change.
- Automatic Detection - Finds running Power BI Desktop instances automatically.
- Local Connections - Full Windows Authentication support.
- Remote Connections - Network access with explicit credentials.
- Activity Logging - Real-time connection monitoring and file logging.
- Simple UI - Easy-to-use interface with minimal configuration.
📥 Installation
- Download
PBIPortWrapper-v0.3.0-win-x64.zipbelow. - Extract the ZIP file.
- Run
PBIPortWrapper.exe. - No additional software required - .NET runtime is included!
⚡ Quick Start
- Start Power BI Desktop and open a model.
- Launch PBI Port Wrapper.
- The application will automatically detect running instances.
- Assign a fixed port (or use the default) for your instance.
- Toggle the Start switch to start port forwarding.
- Connect from your tool using
localhost:<FixedPort>.
📖 Documentation
See README.md for complete documentation, including:
- How to connect from Excel (local and remote)
- How to connect from DAX Studio and Tabular Editor
- Firewall configuration for network access
- Configuration options
⚠️ Known Limitations
- Database name changes when Power BI Desktop restarts - requires reconnection.
- No automatic reconnection if Power BI crashes.
- "Auto" mode restart behavior: If you manually stop a proxy while "Auto" is enabled, it may restart on the next poll. Workaround: Disable "Auto" before stopping.
📄 License
MIT License - see LICENSE.txt
Questions? Issues? Open an issue on GitHub or start a discussion!