GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||
GeezerVison is showing bitvise.com — Scriptable configuration with BssCfg and PowerShell | Bitvise SSH Server
Company
Scriptable configuration with BssCfg and PowerShellBitvise 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.xxUsing BssCfgThe 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 PowerShellTo instantiate the SSH Server's configuration COM object in PowerShell, use: $cfg = new-object -com "Bitvise.BssCfg" Note:
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. ReferenceEvery 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: Stop on errorsIf 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 instanceIt 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 settingsWhen 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 settingsTo 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)" EnumerationsAll 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 ListsEvery 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 groupsAccounts 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:
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 entriesAccounts 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 removalAccessing 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:
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 syntaxScriptable 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 operatorsThe 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 operatorsThe 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:
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:
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 addressesIn 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:
Faster importThe 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 scriptsThe following example scripts have been renamed to .txt from their original extensions:
You can find the following scripts in your SSH Server installation directory:
These scripts can be used as-is, or modified according to your needs. Main changes from versions 8.xxAll 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 versionsScriptable configuration in Bitvise SSH Server versions 8.xx Scriptable configuration in Bitvise SSH Server versions 7.xx SSH Server GuideConfiguring for SFTP, SCP, FTPS Compatibility with FTPS clients Master/follower synchronization and clusters About SSHResources | ||||||||||
| 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. |