Been here before? Know the deal? Jump to the revision history to see what’s in the latest update.
… or go straight to the Downloads.

The name’s a bit of a mouthful, but “Convert-RibbonSbcConfigToWord.ps1” takes the backup file from your Ribbon/Sonus SBC/UX 1000 or 2000 gateway and creates a new Word document, with all of the important(?) configuration information captured in tables.

It started life as a way to save the tedium of screen-scraping lots of fixed frames for my as-built documents, but it quickly became apparent that it would also make a useful tool for the offline review of a gateway’s config (although it ain’t no “UxBuilder”).

Convert your backups from this:

… to this:

"Before" TransformationTable-Word-v2


  • Decodes gateway versions up to 9.0.1 & the SWe Lite
  • Converts and saves the config to a new Word document, and optionally makes a PDF of it too
  • Doesn’t need any Lync PowerShell modules – it’s fine on your Win 7 – Win 10 machine (which needs to have Word installed)
  • Tested on Word 2010, 2013 & 2016
  • Reasonably well debugged throughout (although time will tell of course!)
  • Use the “RedactIP” switch to strip all IP addresses from the resulting file
  • It’s easy enough to turn off an unwanted section if you’re only interested in a specific subset of the functionality, or are adapting to suit your environment
  • A “-SkipWrite” switch skips the relatively slow process of writing to Word. I added this for debugging and have left it in the released version to help anyone refining or enhancing the script
  • The script is code-signed, so no longer requires you to drop your ExecutionPolicy to “Unrestricted”. This also means you can be confident the code’s not changed since it left here
  • Uses your existing Word document template for the formatting of the table headings and table of contents – or nominate a different one from the commandline



  • It’s not the fastest to run! Stuffing values into Word is a relatively slow process. With v2 and all options enabled allow up to 10 minutes for your average gateway. I’ve stolen Scott Hanselman’s “Progress Bars in PowerShell” to help the watched pot boil
  • Each update captures even more of the gateway’s config than before, however it still doesn’t capture EVERYTHING. There’s an enormous amount in there, and it’s growing with each release! If you find I’ve not captured a particularly valuable element of the config, feel free to revise it to suit your needs – and send me the new bits to incorporate, please. If you’re not feeling up to it, send me a sample config file and some screen-grabs of the bit you’d like to see added
  • There are MANY hash tables throughout. (This is where an integer is stored in the config file, but it’s decoded to text on-screen). I’ve put a lot of effort into capturing these, but there are going to be examples where I’ve missed one. Please send me screen-grabs and sample config files and I’ll update the script.
  • I’m largely letting Word control the width of the table columns, and you’ll find many instances where it’s done a poor job. You’ll need to edit every document the script produces to resolve this


  1. I’ve published the script here as “Convert-RibbonSbcConfigToWord-<version>.txt” as a way of capturing the version number, but to also get around programs like Outlook that aren’t too happy being used as a delivery means for “ps1” files. So please rename it to Convert-RibbonSbcConfigToWord.ps1
  2. Backup your gateway. Export the config file. Older versions (pre 2.2.1) will save to an archive called “backup.tar.gz”, while newer versions save as “SBC_Config_<hostname>_<version>_<date>.tar”
  3. Older backups you’ll need to unzip twice to recover the “symphonyconfig.xml” document we need, whilst newer ones only need one unzip to reveal their goodness>> If you have 7-zip installed you no longer need to unzip “SBC_Config_<hostname>_<version>_<date>.tar” – just feed the .tar file as the “-inputfile”
  4. Open a PowerShell window
  5. Now feed the backup into the script! Either place the config file in the same path as the script, give the full path in the command line, or (as of v2.7) a relative path:
    PS H:\> Convert-RibbonSbcConfigToWord.ps1 -InputFile "symphonyconfig.xml" -OutputFile "CustomerSBC-config.docx"

    If you don’t specify an InputFile, the script goes looking for “symphonyconfig.xml” in its directory. If you don’t specify an OutputFile, it will re-use the name of the InputFile and save as “.docx”, overwriting any existing file of the same name in that directory. If you add the “-MakePdf” switch, it will save the same output filename as a .pdf as well

You can even batch it:

PS H:\> Get-Item "d:\path\*.tar" | foreach {.\Convert-RibbonSbcConfigToWord.ps1 -InputFile $_.Fullname -MakePdf -SkipUpdateCheck}



If the script won’t start, odds are you’ve run foul of a protective mechanism: the “Execution Policy”. Here’s how to Get the current value and Set it to “AllSigned”.

PS H:\> Get-ExecutionPolicy
PS H:\> Set-ExecutionPolicy AllSigned
Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at Do you want to change the execution policy?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y
PS H:\>

Note that the first time you run this script you’ll have to agree to trust my code-signing cert:

PS H:\> .\Convert-RibbonSbcConfigToWord.ps1 -Inputfile symphonyconfig.xml -Verbose -MakePDF
Do you want to run software from this untrusted publisher?
File H:\\Convert-RibbonSbcConfigToWord.ps1 is published by CN=Greig Sheridan, O=Greig Sheridan, L=Petersham North, S=New South Wales, C=AU and is not trusted on your system. Only run scripts from trusted publishers.

[V] Never run  [D] Do not run  [R] Run once  [A] Always run  [?] Help (default is "D"): a

The other one you might encounter is more easily fixed. If you get this error, just do like the last line says and re-run with “.\” at the start:

Convert-RibbonSbcConfigToWord.ps1 : The term 'Convert-RibbonSbcConfigToWord.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Suggestion [3,General]: The command Convert-RibbonSbcConfigToWord.ps1 was not found, but does exist in the current location. Windows PowerShell does not load commands from the current location by default. If you trust this command, instead type ".\Convert-RibbonSbcConfigToWord.ps1". See "get-help about_Command_Precedence" for more details.

PowerShell ISE

Some users have reported problems when running the script from a PowerShell ISE window. If that’s you, try it in a normal (but elevated) PowerShell window.

What’s Under the Hood

At just over almostover 5,000 more than 5,000 7,000 8,000 10,000 lines of code this script’s not compact, but structurally it is really quite simple. There are two primary components: one that reads the XML and extracts the required values; and the second is a pair of very similar functions (“WriteSection” & “WriteSectionVertically”) that creates a suitable table and dumps the values therein.

The main body of the script simply wends its way sequentially through the XML file, plucking out all of the sections of interest with essentially the same string manipulation repeating over and over again. (I had a go at it, but the unique content of each section prevented me from proceduralising this).

# ---- FXS Cards ----------
if ($ -eq "FXSCards")
$FXSCards = $NodeHardwareGroup.GetElementsByTagName("ID")
$FXSCardColumnTitles = @("Card", "Port", "Enabled", "Port Name", "Port Alias", "Port Description", "Rx Gain", "Tx Gain", "Analog Line Profile")
if ($FXSCards.Count -ne 0)
ForEach ($FXSCard in $FXSCards)
if ($FXSCard.IE.classname -eq $null) { continue } # Empty / deleted entry
if ($FXSCard.IE.classname -eq "LINE_CARD_CONFIG_IE")
$FXSCardPorts = $FXSCard.GetElementsByTagName("ID")
ForEach ($FXSCardPort in $FXSCardPorts)
if  ($FXSCardPort.IE.classname -eq "FXS_PORT_PROFILE_CONFIG_ENTRY_IE")
$FXSCardObject = @($FXSCard.value, $EnabledLookup.Get_Item($FXSCardPort.IE.Enabled) <EDIT>))
$FXSCardCollection += , $FXSCardObject
$NodeHardwareData += , ("FXS Cards", $FXSCardColumnTitles, $FXSCardCollection)

… and so on.

As each section is read, the required parameters are extracted & formatted into an array. If there are multiple objects of the same type, these are also processed and an array of arrays is prepared in readiness for Word. If the section has a “Sequence” value (the ordering of entries in a Transformation Table is a prime example), this is decoded and the array entries re-ordered to represent the active sequence. Once the sequence is correct, the final array is passed to the appropriate WriteSection.

The WriteSection functions open and inspect the passed array, decoding it back into multiple constituent arrays representing column titles (“horizontal” tables only) and each table’s row. The title of the section is written to the document in the Heading1 style. If there are sub-headings (sub-tables or groups within the section), these are written as Heading2 and Heading3. We then loop through the array, writing each string therein as a new row.


The ENTIRE revision history is now in a separate post here.

Revision History

v9.0.4 15th July 2021

  • Added new bit in 9.0.4:
    • Added Global Security Options / Test a Call

v9.0.3 * Not released

  • No new functionality, no bugs unearthed.

v9.0.2 28th January 2021

  • Changed Network Monitoring / Link monitors from h-table to v-table and updated to accommodate new values in 9.0.2
  • Added Protocols / IPSec / Tunnel Table
  • Changed some references to ‘<n/a>’ and ‘<Not Captured>’ to ‘<Not Available>’ to reduce ambiguity & increase consistency
  • Now stamps ‘<Not Available>’ into System / Node-Level Settings if the SweLite ID in nodeinfo.txt is blank
  • Fixed bugs:
    • Fixed bug introduced in 9.0.1 where the lower half of each SIP Server table was skipped. (Bad test of SIP Recorders)
    • Suppressed display of ‘Send STUN Packets’ in Media / Media System Configuration for the SweLite

v9.0.1 7th November 2020

  • Consolidated creation of $SgTableLookup to new combined section in the ‘first run’ loop, as SigGps now recursively reference themselves for Call Recording
  • Removed redundant Sig Gp type (e.g. ‘(SIP)’) from the start of each SigGp heading
  • Updated Security / TLS Profiles to now show only one instance of Certificate, now under ‘Common Attributes’
  • Added new bits in 9.0.0 (SweLite) / 9.0.0 (1k/2k):
    • ‘SIP Recorder’ (type) in SIP Server Tables
    • ‘SIP Recording’ section in SIP
    • ‘SIP Recording’ in SIP Sig Gps
    • ‘E911 Notification Manager’ in Emergency Services
    • Removed Forking from the licences table (as from v9 it’s now licenced by default – but still displaying in the 1k/2k version of the table)
  • Fixed bugs / new bits missed previously:
    • Added ‘Drain’ to $EnabledLookup & replaced ‘Enabled’ value with ‘customAdminState’ in Sig Gps where the latter is present
    • SIP SigGp was reporting the default $SipGp.IE.Description instead of $SIPgroupDescription. (Only apparent if $SipGp.IE.Description was blank)
    • Fixed bug where Security / TLS Profiles was showing a blank instead of the SBC certificate name

v8.1.5 16th August 2020

  • Added display of SILK licences to the SweLite’s System / Licensing / Current Licenses
  • Now reports ‘License Expiration’ value from nodeinfo.txt for 1k/2k. (Was previously suppressed. I don’t know why).
  • Updated label on SweLite’s License ‘Virtual DSP Sessions’ to ‘Enhanced Media Sessions with Transcoding’
  • Updated label on SweLite’s License ‘Proxy RTP <-> SRTP Sessions’ to ‘Enhanced Media Sessions without Transcoding’
  • Removed test to suppress System / Node Level Settings / Country Level Information if SweLite: it’s visible there now
  • SweLite: Removed the ‘License Expiration’ line from the bottom of the licences table
  • Changed license display: if not licenced, replace any ‘0’ value with ‘Not Licensed’
  • Added new bits in 8.1.0 (SweLite) / 8.1.5 (1k/2k):
    • “Teams Local Media optimization” in SIP Sig Gps
    • Primary & Secondary Source to System / Node Level Settings / Domain Name Service
  • Fixed bugs:
    • Updated input “$Fullname” to remove array declaration (Tks Mike.)
    • Some SBCs previously reported two blank lines between feature licences and the expiry, etc footer. Now back to just one.
    • SIP SigGp: Supported Audio Mode of “Proxy with local SRTP” & Proxy Local SRTP Crypto Profile ID should not show on a 1k/2k. Corrected.

6th June 2020

Updated the download link to point to GitHub.

v8.1.0B 18th March 2020

  • Fixed bug where TT’s were no longer arranged alphabetically – broken with the new layout introduced in v8.0.0. (Tks Mike.)

v8.1.0 14th March 2020

  • Restructured to support batch processing direct from the pipeline. Added new batch example:
    gci *.tar | .\Convert-RibbonSbcConfigToWord.ps1 -SkipUpdateCheck -MakePDF
  • Added new bits in 8.1.0:
    • “Country Code” in System / Node Level Settings
    • “Bad Actors” table under Settings / Security
    • “Explicit Acknowledgement of Pre-Login Info” in Security / Users / Global Security Options
    • “Certificate” in Security / TLS Profiles
    • “SBC Supplementary Certificates” in Security / SBC Certificates
    • “SILK” in System / Licensing / Current Licenses
    • “DC Enabled” in Auth and Directory Services / Acive Directory / Domain Controllers
  • Fixed bugs:
    • “Lockout duration” was always showing under Security / Users / Global Security Options, even if Number of Failed Logins was set to “No lockout”
    • Was not correctly handling “SupportsShouldProcess”. As resolving this will add a confirm prompt for each iteration (potentially breaking existing workflow), I’ve opted to disable it
    • Under System / Node-Level Settings, ‘Power LED’ was misspelt
  • Updated label on SIP Sig Sp ‘Outbound Proxy’ to now show as ‘Outbound Proxy IP/FQDN’

v8.0.3 * Not released.

  • Added display of settings when Security / Users / Global Security Options / Enhanced Password Security = Yes

v8.0.2 * Not released.

  • No new functionality, no bugs unearthed.



You’ll find a code-signed version of the script on GitHub. You’re welcome to pinch, adapt or improve upon the code with my blessing. If you encounter any problems with it please create an issue on the repo.

Help me improve the script

PLEASE let me know if you encounter any problems. All I ask is a copy of the symphonyconfig.xml file (de-identified as you wish) – or preferably a .TAR backup file – and a screen-grab from the browser to show me what it’s meant to look like on-screen.


There are many great posts out there where people have achieved awesome things with PowerShell and Word, and I’ve relied heavily on their experiences and generosity. I’ve pasted these links into the bottom of the script as well.
Save as PDF:



  1. Hi,
    Really nice job! I just change the script a little bit because I need a different color for the first row of tables. It would have been nicer if you choose only one variable for all the first rows but it was still easy to modify.

    Here is the part I added:
    # Transformation RGB -> WdColor
    # wdColor = (red + 0x100 * green + 0x10000 * blue)
    # light orange (255,204,153)
    $MyColor = (255 + 0x100 * 204 + 0x10000 * 153)

    # Replace Colors by one common for all first rows
    $wdColorFirstRow = $MyColor

    And I replace variable after “.BackgroundPatternColor” by $wdColorFirstRow, to allow change the color in just one place.

    Many thanks for your script!!!

  2. Hi Greg
    I have used your great script several times, and the outcome is great:) But now I have an issue when I run the script from a SB2K rel. 5.0.1. It runs the script, but fails at last with this error:
    Aborted with fatal error: You cannot call a method on a null-valued expression.
    WARNING: Failed to save DOC and/or create PDF
    Have tried several times, with same result

    Do You have time to give it a shot :)

    Best regards

    • Hi David,

      If you can send me the backup file I’d love to see why it’s crashing. If you’re concerned for the privacy of the data, I only need the XML, and you can obfuscate the IPs, hostnames & any other identifying details before sending it through.

  3. Hi

    Thanks for the script, however I receive the following errors when trying to run it:

    At C:\Tools\Convert-RibbonSbcConfigToWord.ps1:8 char:18
    + ~
    Missing file specification after redirection operator.
    At C:\Tools\Convert-RibbonSbcConfigToWord.ps1:170 char:21
    + Sign up
    + ~
    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
    quotation marks (“&”) to pass it as part of a string.
    At C:\Tools\Convert-RibbonSbcConfigToWord.ps1:197 char:189
    + … ata-ga-click=”(Logged out) Header, go to Features”>Features <span cla …
    + ~
    The '→Mobile <span cla …
    + ~
    The '→Actions <span cla …
    + ~
    The '→Codespaces <span cla …
    + ~
    The '→</s …
    + ~
    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
    quotation marks ("&") to pass it as part of a string.
    Not all parse errors were reported. Correct the reported errors and try again.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingFileSpecification

  4. same issue here.

    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
    quotation marks (“&”) to pass it as part of a string.
    At C:\Users\solem\Downloads\Convert SBC to Word\Convert-RibbonSbcConfigToWord.ps1:221 char:189
    + … ata-ga-click=”(Logged out) Header, go to Features”>Features <span cla …
    + ~
    The '→Mobile <span cla …
    + ~
    The '→Actions <span cla …

    • It looks like you both have a corrupted version of the script.

      There are a couple of ways to download it cleanly:

      • Go to this link, click the Raw button (in the grey bar at the top of the code), then ^A to select all and paste the text into a file. (Back-arrow on your browser or just close the tab at this point).
      • Go to this link and download the “Source code (zip)” under “Assets” at the bottom, then unzip the script.

      Let me know if you’re still having problems with it.

  5. Hi Greig

    I’ve hit an error running the current version (which has worked before):

    fatal error @ line 1736:
    Cannot convert value “9.0.1 v260” to type “System.Int32”. Error: “Input string was not in a correct format.”

    But it only happens in PowerShell v7. So I’m OK to use the ‘usual’ version but something you might want to look at.



Leave a Reply

Your email address will not be published. Required fields are marked *

... and please just confirm for me that you're not a bot first: Time limit is exhausted. Please reload the CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.