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.
Note: Everything that can be configured through BssCfg and PowerShell can also be configured through the graphical Bitvise 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.
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 "BssCfg726.BssCfg726"
- Like the BssCfg utility, the BssCfgManip COM object must be instantiated by a user with administrative permissions, in an elevated PowerShell window.
- The exact name of the BssCfgManip COM object is changed in SSH Server versions that contain changes to the configuration format. To find the name of the COM object for your installation, check the file BssCfgManip.idl in the SSH Server installation directory.
Once the object is instantiated, you can view its properties and methods:
$cfg | Get-Member
Stop on errors
If your script encounters an error when calling a method such as LockServerSettings, 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.
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:
# Manipulate settings
Similarly, to modify keypairs - lock and load them as follows:
# Manipulate keypairs
Master/slave settings are stored separately, and must be locked and loaded as follows:
# Manipulate master/slave settings
If you are loading settings or keypairs only to view them; but not change them; it is not necessary to lock them.
To access server settings, use the property $cfg.settings:
# Load server settings and display the textual log file directory
Write-Host "Log file directory: $($cfg.settings.server.logging.logFileDir)"
To access master/slave instance type settings, use $cfg.instance:
# Load instance type settings and print the master server's address
Write-Host "Master server's address: $($cfg.instance.slave.host)"
Under $cfg.settings and $cfg.instance, every object in the hierarchy features integrated help. You can display it as follows:
You can find built-in help at all levels in the settings hierarchy. For example:
The same help text has also been compiled, and can be viewed as HTML:
The following example scripts have been renamed to .txt from their original extensions:
- 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: 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.
- 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 or remove 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.
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.PwCacheAutoSave.allAccounts
To list all available values for the PwCacheAutoSave enumeration, use:
Dual list properties
Every list is represented in its parent object by two properties through which it can be accessed. For example, the list of virtual accounts can be accessed through virtAccounts and virtAccountsEx. The extended list property (ending in Ex) allows manipulation of the list (add, erase, move items). The simple property (virtAccounts) provides easy, enumerable access to the items.
Simple list property - enumerate virtual accounts:
Foreach ($account in $cfg.settings.access.virtAccounts)
Extended list property - discard all virtual accounts:
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 placed on them; 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. On the other hand, values of the groupType, winDomain and group properties of Windows groups must be unique.
New account and group entries are added in two steps:
The entry is initialized with the new settings it will contain. In this step, it is accessed using the new property of the extended list. For example:
$cfg.settings.access.winAccountsEx.new.winDomain = "DomainName"
$cfg.settings.access.winAccountsEx.new.winAccount = "User"
$cfg.settings.access.winAccountsEx.new.loginAllowed = $cfg.DefaultYesNo.yes
$cfg.settings.access.winAccountsEx.new.xfer.mountPointsEx.new.realRootPath = "C:\Sftp\User"
When the initial data for the new list entry is configured, it is committed into the list:
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.mountPointsEx.
Removing list entries
Accounts and groups can be removed from their lists as follows:
For ($i = 0; $i -lt $cfg.settings.access.winAccountsEx.count; )
If ($cfg.settings.access.winAccountsEx.GetItem($i).winAccount -ieq "User")
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".
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.clientAddressesEx.new.addressRule.addressType = $cfg.AddressVer6Type.ipv4
$cfg.settings.access.clientAddressesEx.new.addressRule.ipv4 = "10.2.3.4"
$cfg.settings.access.clientAddressesEx.new.addressRule.sigBitsIpv4 = 32
$cfg.settings.access.clientAddressesEx.new.instr.allowConnect = $false
$cfg.settings.access.clientAddressesEx.new.addressRule.addressType = $cfg.AddressVer6Type.anyIP
$cfg.settings.access.clientAddressesEx.new.instr.allowConnect = $true
These instructions will:
- Clear the list of rules in Advanced settings > Access control > Client address rules.
- Add a rule to block connections from the IPv4 address 10.2.3.4, identified with all 32 bits.
- Add a final rule to allow connections from other IP address.
Faster import using BssCfg
BssCfg 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 "BssCfg726.BssCfg726"
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 settings as a script in PowerShell.
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 answers to your questions, as well as solutions to any problems, will be readily available.