Installation
Install and upgrade in one line, the installer step by step, unattended installs, HTTPS and troubleshooting.
Made by ON IT AS. Not a Visma product, and not affiliated with or endorsed by Visma.
Install or upgrade in one line
From PowerShell as administrator:
irm https://graphql.on-it.no/install.ps1 | iex
It picks the build for the Visma Business client on the machine, downloads it, checks the
SHA-256 and that the executable and install.ps1 are signed by ON IT AS, and then:
- New install: extracts it to
C:\vbus-graphqland runsinstall.ps1, which asks for the rest. - Upgrade (a service runs
VismaBusinessGraphQL.exe, whatever its name): stops the service, moves the old files tobackup\<version>-<time>next to the executable, puts the new ones in place and starts the service again.appsettings.json,.jwt-secret,license.json,Pluginsandterms-accepted.jsonare kept. If the new version does not answer/healthwithin five minutes, the old one is put back and started. The three newest backups are kept. If the license terms have changed, it asks you to accept them again.
A server that runs without a service, or a C:bus-graphql that has one but no service,
stops the script with what to do; it never installs a second copy beside an existing one.
With parameters (-InstallDir, -ServiceName when several services run the server,
-AcceptTerms, -Force to reinstall the same version):
& ([scriptblock]::Create((irm https://graphql.on-it.no/install.ps1))) -InstallDir D:\vbus-graphql
To read the script before running it: irm https://graphql.on-it.no/install.ps1 > get.ps1.
It is installer/get.ps1 in this repository.
Install from the ZIP
- Download the zip that matches your Visma Business client version from the Releases page. If you are unsure which one, run any of them - the installer reads the installed version from the registry and tells you if you picked the wrong build.
- Extract it somewhere permanent, e.g.
C:\vbus-graphql. - Open PowerShell as administrator in that folder and run:
.\install.ps1
It will ask for the SQL Server instance, the firm database and the Visma Business web service credentials, then do everything else.
What it does
| Step | |
|---|---|
| 1 | Checks the executable is present and that you are elevated, and asks you to accept the license terms (LISENSVILKAR.md, in Norwegian; it stops if the file is missing). The acceptance is recorded in terms-accepted.json next to the executable: terms version and SHA-256, time, Windows user and machine |
| 2 | Compares the bundled Visma client against the one installed on this machine |
| 3 | Builds the connection string, connects, and confirms the database really is a Visma Business firm database |
| 4 | Reads the companies Visma Business has from its register (Catalog → system database → Frm) and checks each one’s database exists |
| 5 | Lists the data model extensions (DMEs): those copied into Plugins next to the server, or else Visma Business’s own (found through the registry) |
| 6 | Probes the Visma Business GenericService endpoint |
| 7 | Checks the license id with ON IT’s license service, if one is given (without one, the server registers itself - see docs/licensing.md) |
| 8 | Finds and checks the HTTPS certificate, if HTTPS is wanted (see HTTPS) |
| 9 | Writes appsettings.json (backing up any existing one) |
| 10 | Generates a 256-bit JWT signing key if .jwt-secret does not already exist |
| 11 | Registers the Windows service, sets it to start automatically and to restart on failure |
| 12 | Waits for the schema to build and downloads the SDL to prove it works; with HTTPS, checks the certificate the server actually serves |
| 13 | Prints a 24 hour admin bearer token and a curl command to try it |
Re-running is safe. It updates the configuration and restarts the service, and it
never regenerates .jwt-secret - doing so would invalidate every token already
issued to clients.
Unattended install
.\install.ps1 `
-SqlServer 'SQLSRV\VISMA' `
-Database 'F0001' `
-SqlUser 'vbus' `
-SqlPassword 's3cret' `
-BusinessUri 'http://vismasrv:2001/GenericService/Anonymous' `
-BusinessUser 'admin' `
-BusinessPassword 'anothersecret' `
-Port 5000 `
-TokenFirm 'ANY' `
-AcceptTerms `
-Unattended
Omit -SqlUser/-SqlPassword to use Windows authentication - the service account
then needs access to the firm database.
Other options
| Option | |
|---|---|
-AcceptTerms |
Accept the license terms in LISENSVILKAR.md on behalf of the customer. Required with -Unattended; otherwise the installer asks. |
-SkipServiceInstall |
Validate connectivity and write the config without touching the service manager. Does not need elevation. |
-Uninstall |
Stop and remove the service. Files and configuration are left alone. |
-ServiceName |
Defaults to vbusgraphqlserver. |
-Port |
The HTTP port. Defaults to 5000. |
-HttpsPort |
Also listen over HTTPS on this port (default 5001 when a certificate is given). See HTTPS. |
-CertificateSubject |
The HTTPS certificate from the machine’s store (LocalMachine\My), by subject. |
-CertificatePath / -CertificatePassword |
The HTTPS certificate from a .pfx file instead. |
-HttpsOnly |
No HTTP endpoint, HTTPS only. |
-LicenseId / -LicenseServiceUrl |
Rarely needed: the server registers itself. See docs/licensing.md. |
-TokenFirm |
The frm claim of the printed test token: a firm database, a comma separated list (F0001,F0002) or ANY. Defaults to -Database. |
-CatalogDatabase |
Visma Business’s catalogue, which leads to the company register: a database name on the same SQL Server (default Catalog) or a full connection string. |
-DatabasePrefix |
Prefix of the firm database names, for installations named like ZF0001. Default none. |
-PluginsXml |
Rarely needed. DME files copied into Plugins next to the server are used, else Visma Business on this machine (registry). Give a Plugins.xml (e.g. a share) to override, or none for the core model only. See Data model extensions. |
Data model extensions
Visma Business’s data model extensions (DMEs) are served like the core model. When Visma Business runs on this machine nothing needs doing: the server finds its Plugins.xml through the registry.
When it runs on another machine, copy the DME files - or Visma’s whole Plugins folder - into
a Plugins folder next to the server, and (re)run the installer or restart the service:
C:\VismaBusinessGraphQL\
VismaBusinessGraphQL.exe
Plugins\
OLE_DME.xml
The installer lists what it finds, and the server checks each table and column against every
company database at startup, leaving out what the database does not have yet (see the log). After
the customer adds or changes a DME, copy it again and restart. Details:
docs/data-model-extensions.md.
HTTPS
By default the server listens on plain HTTP and HTTPS is put in front of it - usually a
Cloudflare tunnel (see the main README). To have the server itself serve HTTPS, give it a
certificate; it then listens on both, or on HTTPS only with -HttpsOnly.
From the machine’s certificate store (recommended):
.\install.ps1 -HttpsPort 5001 -CertificateSubject graphql.customer.no
The installer checks the certificate the way Kestrel (the server’s web server) will: it must be
in LocalMachine\My with its private key, valid today, meant for Server Authentication, and
issued by a CA this machine trusts. If several match, the newest wins - so renewing is just
importing the new certificate with the same subject and restarting the service; nothing in the
configuration changes. It warns when the certificate expires within 30 days.
From a .pfx file - also for a self-signed certificate, which the store route refuses:
.\install.ps1 -HttpsPort 5001 -CertificatePath C:\certs\graphql.pfx -CertificatePassword 'pfx-password'
The password is stored in appsettings.json; prefer the store where you can.
A re-run of the installer without these options keeps the HTTPS endpoint the installation already has. At the end it connects over TLS and reports which certificate the server actually serves, so a certificate Kestrel could not load shows up there and not first at a customer.
What it writes - and what you can write by hand in appsettings.json instead:
"Kestrel": {
"Endpoints": {
"Http": { "Url": "http://0.0.0.0:5000" },
"Https": {
"Url": "https://0.0.0.0:5001",
"Certificate": { "Subject": "graphql.customer.no", "Store": "My", "Location": "LocalMachine", "AllowInvalid": false }
}
}
}
For a file the certificate is { "Path": "C:\\certs\\graphql.pfx", "Password": "..." }, or
{ "Path": "cert.pem", "KeyPath": "key.pem" } for PEM. Restart the service after editing.
Remember the firewall: open the HTTPS port if callers are on other machines.
After installing
- GraphQL IDE:
http://localhost:<port>/graphql - Schema:
http://localhost:<port>/graphql?sdl - Restart:
Restart-Service vbusgraphqlserver - Logs: the
logfolder next to the executable
Tokens
Requests are authenticated with a JWT signed using .jwt-secret (base64). Mint one at
jwt.io - tick secret base64 encoded - with:
{
"sub": "someone",
"aud": "vbus",
"frm": "F0001",
"roles": ["admin"],
"exp": 1900000000
}
audmust bevbusfrmis the firm database - or a comma separated list of them, orANY, letting the caller choose withuseCompany(no:)(seedocs/multi-firm-tokens.md) - and is how one server serves several firmsrolescontrols access.admingrants everything; otherwise use per-table roles such asproduct(all operations) orproduct_read,product_create,product_update,product_delete. Every field in the schema lists the roles it requires in its description.
With frm set to a list or ANY, every query or mutation names its company:
{ useCompany(no: 1) { product(first: 3) { nodes { productNo } } } }
Troubleshooting
“No usable certificate with subject …” - the installer lists every certificate with
that subject and why it cannot be used: no private key (import the .pfx, not the .cer),
expired, not for Server Authentication, or its chain does not verify (self-signed, or the CA is
not trusted on this machine). Use a certificate from a trusted CA - e.g. Let’s Encrypt with
win-acme - or a .pfx file with -CertificatePath.
“HTTPS on port … did not answer” - Kestrel could not load the certificate when the service
started; the log folder says why. Common: the service runs as an account that cannot read the
private key (certlm.msc → the certificate → All Tasks → Manage Private Keys).
“Could not read the company register” - the catalogue database is not called
Catalog, or lives on another server. Pass -CatalogDatabase. Single-firm tokens work
regardless.
“Company … is registered but database … does not exist” - the firm databases
have a prefix (ZF0001); pass -DatabasePrefix.
“Cannot connect to …” - check the instance name, that TCP/IP is enabled in SQL
Server Configuration Manager, and that the credentials can reach the firm database.
With Windows authentication, remember the service runs as LocalSystem unless you
change it.
“does not look like a Visma Business firm database” - the database is missing the
core Prod/Actor/Ord tables. Check you named the firm database (F0001), not
master or a system database.
“The service stopped on its own” - look in the log folder next to the executable
and in Event Viewer > Windows Logs > Application.
Version mismatch warning - the bundled Visma client differs from the installed one. Queries read straight from SQL Server and will work regardless, but mutations, reports and processing go through the Visma web service and should use a matching build.
First start is slow - the server builds a GraphQL schema covering the whole Visma model (~2600 types). That takes a few seconds and then it is warm.