GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • About SSH
  • Security
  • Screenshots
  • Customers
  • Specifications
  • Install SSH Server
  • Change port number
  • Install SSH Client
  • Connect first time
  • Windows accounts
  • Virtual accounts
  • Configure SFTP / SCP
  • Configure Git access
  • Open to internet access

This view

  • Original page
  • New address

GeezerVison is showing bitvise.com — Scriptable configuration with BssCfg and PowerShell | Bitvise

Bitvise logo
ProductsDownloadPurchaseContactMy Licenses
Home
  • About SSH
  • Security
  • Screenshots
  • Customers
  • Specifications
Getting started
  • Install SSH Server
  • Change port number
  • Install SSH Client
  • Connect first time
  • Windows accounts
  • Virtual accounts
  • Configure SFTP / SCP
  • Configure Git access
  • Open to internet access
  • Public key: Bitvise
  • Harden SSH Server
SSH Server
  • Version history
  • Pricing
  • License
  • Download
    • WRC
  • Notifications
  • Help
    • Users' Guide
      • Installing
      • Upgrading
      • Starting & logs
      • Connecting
      • Config for SFTP
      • FTPS compatibility
      • Securing
      • Host keys
      • Backup
      • Opening
      • Groups, accounts
      • Architecture
      • Windows domains
      • AD permissions
      • Network shares
      • Logon type
      • Public keys
      • Tunneling
      • Sync & clusters
      • Environment
      • Tasks, notifications
      • Scripted config
      • Log filtering
      • Log parsing
      • Advanced
      • Utilities
    • Printable docs
    • Usage FAQ
    • Public keys in SSH
    • Upgrading DSA
    • Internet explained
SSH Client
  • Version history
  • License
  • Download
  • Notifications
  • Portable
  • The 'log' utility
  • Help
    • Internet explained
    • Public keys in SSH
    • Upgrading DSA
    • Port forwarding guide
    • SSH web browsing
    • Git with sexec
    • Authentication agents
    • X11 forwarding
    • Tunnel Remote Desktop
    • FTP bridge
    • Tunnel VNC
    • SSH client as service
    • Unattended use
FlowSsh library
  • Version history
  • Notifications
  • Documentation
Download
  • SSH Server
  • SSH Client
  • WRC
  • Verify installers
  • Uninstalling
Purchase
  • Support and upgrades
  • Large scale
  • Reseller list
  • Reseller policy
Company
  • About us
  • Work at Bitvise
  • Contact

Scriptable configuration with BssCfg and PowerShell

Bitvise SSH Server comes with a textual configuration utility, BssCfg, which is useful for administering SSH servers in large-scale installations. It also comes with a configuration COM object, BssCfgManip, which can be used to configure the SSH Server from any language that supports COM, but is especially intended for use with PowerShell.

Using BssCfg and PowerShell, it is possible to administer the SSH Server remotely from client machines where it is not possible to use Bitvise SSH Client and its Remote Control Panel feature. PowerShell scripts that modify SSH Server settings can be run on the server by a client through an SSH terminal shell or using exec requests.

Note: Everything that can be configured through BssCfg and PowerShell can also be configured through the graphical SSH Server Control Panel. Users who don't need scriptable configuration do not need to learn BssCfg or PowerShell. Such users should simply use the graphical settings, accessed through the Bitvise SSH Server Control Panel.

Main changes from versions 8.xx

Using BssCfg

The BssCfg utility resides in the SSH Server installation directory and can be run from a Windows Command Prompt or PowerShell. It can be run either locally or remotely using an SSH session. If run without parameters, it will show available commands and options.

BssCfg must be run by a user with administrative permissions, in an elevated Command Prompt or PowerShell window.

Configuring the SSH Server with PowerShell

To instantiate the SSH Server's configuration COM object in PowerShell, use:

$cfg = new-object -com "Bitvise.BssCfg"

Note:

  • Like the BssCfg utility, the BssCfgManip COM object must be instantiated by a user with administrative permissions, in an elevated PowerShell window.

  • If more than one SSH Server version is installed, more than one BssCfgManip COM object version will exist concurrently. In this case, instantiating "Bitvise.BssCfg" will access the newest installed version. To discover the name of the object for a previous version, enumerate $cfg.instances.entries and check the member cfgObjName.

Once the object is instantiated, you can view its properties and methods:

$cfg | Get-Member

Statically-typed languages (C#, .NET)

We suggest using BssCfg with a dynamic language, such as PowerShell or VBScript. PowerShell is slower than statically-typed languages, but your scripts will require fewer changes when updating to future SSH Server versions.

To use BssCfg in a static .NET language, such as C#, add a reference to BssCfgManip.exe, which is found in the SSH Server installation directory. If you are using Visual Studio, you can use Add Reference > Browse > navigate to the SSH Server installation directory > BssCfgManip.exe. This will add BssCfg967Lib to your project.

Using BssCfg in a static language will bind tightly to a specific version of BssCfg interfaces. We prefer to maintain stable interface versions in minor releases, but any new setting or capability requires new interface versions. To update to future releases with new interface versions, you will need to update and rebuild your application. Even if you don't require new features, you will want to upgrade for security and reliability fixes.

If you bind statically to a specific BssCfg interface version, disable automatic updates and test compatibility before updating, even across minor versions.

Dynamic languages, such as PowerShell, do not bind tightly to interfaces, and require less maintenance when updating to newer SSH Server versions.

Reference

Every object in the hierarchy features integrated help. You can display it as follows:

$cfg.Help() $cfg.instances.Help() $cfg.instances.entries[0].Help() $cfg.instanceSettings.Help() $cfg.settings.Help() $cfg.keypairs.Help() $cfg.keypairs.entries[0].Help()

You can find built-in help at all levels in the settings hierarchy. For example:

$cfg.settings.access.Help() $cfg.settings.access.virtAccounts.Help() $cfg.settings.access.virtAccounts.new.Help() $cfg.settings.access.virtAccounts.new.auth.Help() $cfg.settings.access.virtAccounts.new.auth.keys.Help()

The same help text has also been compiled, and can be viewed as HTML:


BssCfg967 Reference

alternative link

Stop on errors

If your script encounters an error when calling a method such as settings.Lock, it is important the script stops instead of continuing as if no error happened. The reason locking functions must be called is because they can fail: aspects of SSH Server settings can be briefly locked by another process, and it's not safe to try to alter settings in this case.

To make sure your script stops if it encounters any errors, make one of the first commands:

$ErrorActionPreference = "Stop"

Alternately, your script can handle any execution errors in a Try/Catch block.

Selecting the SSH Server instance

It is possible to install multiple concurrent SSH Server instances on the same computer. There can be no more than one default, unnamed instance ("Bitvise SSH Server"). Other instances will have names ("Bitvise SSH Server - InstanceName").

If more than one instance is installed, it must be selected using $cfg.SetInstance. Examples:

# Alternatives to select the default (unnamed) instance $cfg.SetInstance("") $cfg.SetInstance("Bitvise SSH Server") # Alternatives to select the instance named "InstanceName" $cfg.SetInstance("InstanceName") $cfg.SetInstance("Bitvise SSH Server - InstanceName")

Either the short name (the empty string, or "InstanceName") or the long name (prefixed with "Bitvise SSH Server") may be provided.

If only one SSH Server instance is installed, instance selection is not required. The BssCfgManip COM object will automatically use the only installed instance.

Instances can be enumerated using $cfg.instances:

foreach ($instance in $cfg.instances.entries) { Write-Host "Instance: '$($instance.name)', version: $($instance.version)" }

Locking and loading settings

When the BssCfgManip COM object is first instantiated, neither settings nor keypairs are locked or loaded. To modify settings, you must lock and load them as follows:

$cfg.settings.Lock() try { $cfg.settings.Load() # Manipulate settings # ... $cfg.settings.Save() } finally { $cfg.settings.Unlock() }

Similarly, to modify keypairs - lock and load them as follows:

$cfg.keypairs.Lock() try { $cfg.keypairs.Load() # Manipulate keypairs # ... # $true to perform automatic backup; $false to not $cfg.keypairs.Save($true) } finally { $cfg.keypairs.Unlock() }

Master/follower and update settings are stored separately, and must be locked and loaded as follows:

$cfg.instanceSettings.Lock() try { $cfg.instanceSettings.Load() # Manipulate master/follower and update settings # ... $cfg.instanceSettings.Save() } finally { $cfg.instanceSettings.Unlock() }

If you are loading settings or keypairs only to view them; but not change them; it is not necessary to lock them.

Navigating settings

To access server settings, use the property $cfg.settings:

# Load server settings and display the textual log file directory $cfg.settings.Load() Write-Host "Log file directory: $($cfg.settings.server.logging.logFileDir)"

To access master/follower and update settings, use $cfg.instanceSettings:

# Load instance type settings and print the master server's address $cfg.instanceSettings.Load() Write-Host "Master server's address: $($cfg.instanceSettings.follower.host)"

Enumerations

All enumeration values are accessible by name via the BssCfgManip COM object. For example, the following code can be used to set the setting pwCacheAutoSave:

$cfg.settings.access.pwCacheAutoSave = $cfg.enums.pwCacheAutoSave.allAccounts

To list all available values for the pwCacheAutoSave enumeration, use:

$cfg.enums.pwCacheAutoSave

Lists

Every list is represented by a list object with an enumerable .entries property. For example, the list of virtual accounts can be accessed through virtAccounts and virtAccounts.entries. The list object (without .entries) allows manipulation of the list (add, erase, move items). The .entries property (virtAccounts.entries) provides easy, enumerable access to the items.

List object - discard all virtual accounts:

$cfg.settings.access.virtAccounts.Clear()

The .entries property - enumerate virtual accounts:

foreach ($account in $cfg.settings.access.virtAccounts.entries) { Write-Host $account.virtAccount }

Adding new accounts and groups

Accounts and groups are stored by the SSH Server in lists. Some of the fields in each list entry are the entry's sort key; when you use the help property, these fields are displayed with a ">" prefix. Other fields in each list entry may have a unique constraint; such fields will be marked with a "!" prefix in the result of help. For example, virtual accounts are sorted according to the value of their virtAccount field (">" prefix). On the other hand, values of the groupType, winDomain and group properties in Windows group settings entries must be unique ("!" prefix).

New account and group entries are added in two steps:

  1. The entry is initialized with the new settings it will contain. In this step, it is accessed using the new property of the list object. For example:

    $cfg.settings.access.winAccounts.new.winAccountType = $cfg.enums.winAccountType.domainAccount $cfg.settings.access.winAccounts.new.winDomain = "DomainName" $cfg.settings.access.winAccounts.new.winAccount = "User" $cfg.settings.access.winAccounts.new.loginAllowed = $cfg.enums.DefaultYesNo.yes $cfg.settings.access.winAccounts.new.xfer.mountPoints.Clear() $cfg.settings.access.winAccounts.new.xfer.mountPoints.new.allowUnlimitedAccess = $false $cfg.settings.access.winAccounts.new.xfer.mountPoints.new.realRootPath = "C:\Sftp\User" $cfg.settings.access.winAccounts.new.xfer.mountPoints.NewCommit() ...

  2. When the initial data for the new list entry is configured, it is committed into the list:

    $cfg.settings.access.winAccounts.NewCommit()

This process applies not only to account and group settings entries, but to all settings items stored as lists. In the above example, there is already a second nested example, where a mount point is added to xfer.mountPoints.

Searching and removing list entries

Accounts and groups can be found in lists, and removed from them, by enumerating the lists:

for ($i = 0; $i -lt $cfg.settings.access.winAccounts.count; ) { if ($cfg.settings.access.winAccounts.GetItem($i).winAccount -ieq "User") { $cfg.settings.access.winAccounts.Erase($i) } else { $i++ } }

The above will remove any and all Windows account settings entries whose Windows account name matches "User". For example, it will match and remove a domain account "Domain\User", as well as a local account "User".

Faster search and removal

Accessing COM objects using PowerShell is slow, so list enumeration can take a long time. For faster access, the SSH Server supports the methods FirstWhere, AllWhere, and EraseAll:

  • The functions FirstWhere return the first list entry which matches the provided expression.

  • The functions AllWhere return an array of list entries which match the provided expression.

  • The functions EraseAll remove all list entries which match the provided expression.

Each function comes in 10 versions: for example, FirstWhere and FirstWhere1 to FirstWhere9. The unsuffixed version, FirstWhere, accepts an expression with no variables. The remaining versions are named according to the number of variables accepted by the expression. All expression variables are specified using ? as placeholder. The values must be passed as separate parameters to avoid a security problem comparable to SQL injection.

Examples:

# Erase all Windows account settings entries where Windows account name matches "User" $cfg.settings.access.winAccounts.EraseAll1("winAccount eq ?", "User") # Enumerate virtual accounts without public keys configured foreach ($acct in $cfg.settings.access.virtAccounts.AllWhere("not any auth.keys")) { Write-Host $acct.virtAccount } # Export public keys configured for each virtual account # Also works if changed to enumerate virtAccounts.entries instead of AllWhere # AllWhere is faster if there are many virtual accounts and few have public keys $format = $cfg.enums.PublicKeyFormat.openSsh foreach ($acct in $cfg.settings.access.virtAccounts.AllWhere("any auth.keys")) { foreach ($pubkey in $acct.auth.keys.entries) { $keystr = $pubkey.ExportToBase64String($format) Write-Host "$($acct.virtAccount): $keystr" } }

Expressions passed to FirstWhere, AllWhere and EraseAll functions use the SSH Server's scriptable expression syntax:

Scriptable expression syntax

Scriptable expression syntax

[...] means the inside of square brackets is optional [...]* means zero or more repetitions of an optional part "..." means the quoted text appears literally ... | ... means one of the options { ... } means the inside of curly brackets appears together expression := exprElement | { ["not"] ["("] expression [combiningOp expression]* [")"] } combiningOp := "and" | "or" exprElement := ["not"] { anyExpr | basicExpr | compositeExpr } anyExpr := "any" memberName basicExpr := memberName basicOp value basicOp := "eq" | "ne" | "ge" | "gt" | "le" | "lt" | "startsWith" | "endsWith" compositeExpr := memberName ["not"] compositeOp "(" expression ")" compositeOp := "contains" memberName := path to the member variable, e.g. variable.name value := decimal number, double-quoted string, double-quoted time, or double-quoted date-time

Boolean operators

The SSH Server supports the boolean operators and, or and not. These are used as follows:

(expression) and (expression) (expression) or (expression) not (expression)

Parentheses are optional, but recommended for clarity. The following also works:

expression and expression expression or expression not expression

Comparison operators

The SSH Server supports comparison operators, all of which take the form:

variable.name basicOp value

The value can be a decimal integer; a string in single or double quotes; a boolean literal (true, false); or a date/time.

Comparison operators:

  • eq: true if the variable equals the value.
  • ne: true if the variable does not equal the value.
  • ge: true if the variable is greater than or equal to the value.
  • gt: true if the variable is greater than the value.
  • le: true if the variable is less than or equal to the value.
  • lt: true if the variable is less than the value.
  • startsWith: true if the variable starts with a specified string prefix.
  • endsWith: true if the variable ends with a specified string suffix.
  • contains: true if the variable contains a specified substring.

Operations on strings are case-insensitive using NTFS-like rules. Strings that contain spaces must be quoted. If a string is single-quoted, special characters are not escaped, and the single quote cannot appear in the string. If a string is double-quoted, special characters (", `) must be escaped using the grave accent (`).

Date/time values can be specified in any of the following ISO 8601 or ISO-like formats:

"HH:MM" 13:00
"YYYY-MM-DD HH:MM" "2020-01-01 13:00"
"YYYY-MM-DDTHH:MM:SS" "2020-01-01T13:00:30"
"YYYY-MM-DD HH:MM +/-ZONE" "2020-01-01 13:00 +1000"
"YYYY-MM-DDTHH:MM:SS+/-ZONE" "2020-01-01T13:00:30-2000"

If a time zone is not specified, local time is assumed.

"any" and "contains"

The any operator tests if a variable is defined:

any variable.name not any variable.name

The contains operator tests if a structure or list contains any member that matches an expression:

variable.name contains (expression) variable.name not contains (expression)

When using the contains operator in this way, parentheses around the expression are required.

Blocking IP addresses

In order to block a large number of IP addresses, you can use PowerShell, or "BssCfg settings importText", to run settings instructions such as these:

$cfg.settings.access.clientAddresses.Clear() $cfg.settings.access.clientAddresses.new.addressRule.addressType = $cfg.enums.AddressVer6Type.ipv4 $cfg.settings.access.clientAddresses.new.addressRule.ipv4 = "10.2.3.4" $cfg.settings.access.clientAddresses.new.instr.allowConnect = $false $cfg.settings.access.clientAddresses.NewCommit() $cfg.settings.access.clientAddresses.new.addressRule.addressType = $cfg.enums.AddressVer6Type.anyIP $cfg.settings.access.clientAddresses.new.instr.allowConnect = $true $cfg.settings.access.clientAddresses.NewCommit()

These instructions will:

  1. Clear the list of rules in Advanced settings > Access control > Client address rules.
  2. Add a rule to block connections from the single IPv4 address 10.2.3.4.
  3. Add a final rule to allow connections from other IP address.

Faster import

The BssCfg command-line utility implements a number of commands to access all aspects of the SSH Server's configuration. Among them are the commands BssCfg settings exportText and importText.

The command settings exportText is roughly equivalent to the following in PowerShell:

$cfg = new-object -com "Bitvise.BssCfg" $cfg.settings.Load() $cfg.settings.Dump()

The result of settings exportText is executable directly as a PowerShell script, and will set SSH Server settings to what they were at the time of export. However, the settings in this format can also be imported using BssCfg settings importText.

The command settings importText imports SSH Server settings in the textual format exported by exportText. The syntax supported by importText is very limited, and does not support most PowerShell language features. The main feature of importText is that it is much faster than direct execution of the same script in PowerShell.

The same fast-import functionality is also available using the COM object. For example:

$textSettings = $cfg.LoadText("C:\Path\To\Settings.txt") $cfg.settings.Import($textSettings)

Or:

$textSettings = $cfg.LoadText("C:\Path\To\InstanceSettings.txt") $cfg.instanceSettings.Import($textSettings)

Example scripts

The following example scripts have been renamed to .txt from their original extensions:

  • PowerShell: Roll over to a new SSH host key algorithm in two stages: first generate a new host key and export the public key; subsequently employ it.

  • PowerShell: Import and employ a new FTPS certificate from a .pfx or .p12 file containing a new certificate and private key.

  • PowerShell: Import a public key into a virtual account settings entry.

  • PowerShell: Loop through virtual account entries, displaying the virtual filesystem mount points defined by each virtual account settings entry.

  • PowerShell: Loop through Windows group settings entries, searching for Windows file share entries that use accounts whose passwords have changed, and update such file share entries with new passwords.

  • PowerShell: Create a virtual account, assign it a password and public key for authentication, configure it with virtual filesystem mount points.

  • PowerShell: Change a virtual account password for an existing virtual account.

  • PowerShell: Create a new mount point for an existing virtual account, with non-default mount point permissions.

  • PowerShell: Read a file with IP addresses and add them to Client address rules.

  • PowerShell: Create a virtual account with server-configured port forwarding rules in the client-to-server and server-to-client direction.

  • PowerShell: Locate any DSA keys, both among host keypairs used for server authentication, and public keys imported for client authentication in account and group settings entries.

  • PowerShell: Rename a virtual group and update virtual accounts that reference it.

  • PowerShell: Disable virtual accounts that have not logged in for a number of days.

  • PowerShell: Disable automatic checks for updates.

  • PowerShell: Disable weak encryption algorithms – those using 3DES and CBC mode – for SSH connections.

  • PowerShell: Reset file sharing settings for all mount points defined in Windows and virtual group or account settings entries.

  • PowerShell: Query SSH Server activation information.

  • VBScript: Load, Update and Apply Settings.

  • VBScript: Export Public Key in OpenSSH known_hosts Format.

  • VBScript: Loop through Windows account entries, resetting their mount points so that each account has a single mount point with a real root path set to the value of the "Initial terminal shell directory" for the account.

  • C#: List virtual accounts, remove a virtual account, or create a virtual account.

You can find the following scripts in your SSH Server installation directory:

  • VirtAccountExporter.ps1: A PowerShell script that exports virtual account information into a CSV text file.

  • VirtAccountImporter.ps1: A PowerShell script that imports new virtual accounts from a CSV text file.

These scripts can be used as-is, or modified according to your needs.

Main changes from versions 8.xx

All examples assume the following:

$ErrorActionPreference = "Stop"

Creating the configuration COM object:

# 8.xx: $cfg = new-object -com "BssCfg815.BssCfg815" # 9.xx: $cfg = new-object -com "Bitvise.BssCfg"

Locking and loading settings:

# 8.xx: $cfg.settings.Lock() try { $result = $cfg.settings.Load() if ($result.failure) { Write-Error $result.Describe() } ... } finally { $cfg.settings.Unlock() } # 9.xx: $cfg.settings.Lock() try { $cfg.settings.Load() ... } finally { $cfg.settings.Unlock() }

Changed names and locations of certain items:

# 8.xx: $algId = 6 # $cfg.enums.hostKeyAlgId.ed25519 $cfg.settings.session.sessionTimeout = 120 ... # 9.xx: $algId = 6 # $cfg.enums.KeypairAlgId.ed25519 $cfg.settings.connections.connectionTimeout = 120 ...

Need help?

If you run into any problems or need help with scripted configuration, feel free to contact us. Your questions will help us augment this guide so that solutions to problems can be more readily available.

Older versions

Scriptable configuration in Bitvise SSH Server versions 8.xx

Scriptable configuration in Bitvise SSH Server versions 7.xx

SSH Server Guide

Installing

Upgrading

Starting and monitoring

Connecting the first time

Configuring for SFTP, SCP, FTPS

Compatibility with FTPS clients

Securing the SSH Server

Host keys

Opening to the internet

Configuration backup

Groups and accounts

Security architecture

Windows domains

Active Directory permissions

Accessing network shares

Network/interactive logon

Public key authentication

Tunneling restrictions

Master/follower synchronization and clusters

Environment variables

Tasks, triggers, conditions

Scriptable configuration

Scriptable log filtering

Log files and MS Log Parser

Advanced config and use

Resources and utilities

About SSH

What is SSH?

Screenshots

Security

Resources

Getting Started

SSH Server Users' Guide

SSH Server Usage FAQ

Configuring SFTP and SCP

Securing the SSH server

Public keys in SSH

Port forwarding guide

Web browsing over SSH

X11 forwarding

Tunnel Remote Desktop

Tunnel WinVNC

How the internet works

Bitvise logo
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.