First off, all credit for this post goes to my colleague Chris Cook. He provided all of the powershell scripting behind the tool.
UPDATED: Added download of file HERE
I have found it very difficult to easily document a voice configuration within Lync. That is when I approached my scripting buddy Chris. He developed this script to extract the export from the Lync Control Panel Voice Configuration:
When exporting the configuration, it saves as a *.vcfg file. Using Chris’ handy powershell cmdlet, we can extract the contents of the *.vcfg file into an Excel spreadsheet with different tabs for each area: Dial Plan, Voice Policy, Route, PSTN Usage, and Trunk Configuration.
Copy the following powershell script as a .ps1 file and save in the same location as the exported *.vcfg file.
Download LyncVCFGConverter.ps1 here
1 | ################################################## |
1 | # |
1 | # LyncVCFGConverter.ps1 |
1 | # Format Exported .vcfg file from Lync to Excel |
1 | # |
1 | # Author: Chris Cook |
1 | # |
1 | # Use at your own risk! |
1 | # |
1 | ################################################## |
1 |
1 |
1 | cls |
1 | #Collect VCFG Filename from Command Line Arguments |
1 | $VCFGFileName = $args[0] |
1 | Write-Host "Importing XML Config..." |
1 | $VCFGXML = [xml](get-content $VCFGFileName) |
1 | Write-Host "Done" |
1 |
1 | #Get current working directory and convert it to a string. |
1 | $CurrentDirectory = Get-Location |
1 | $CurrentDirectory = $CurrentDirectory.ToString() |
1 |
1 | #Set the file name for the Excel Spreadsheet we're working with. |
1 | #Drop the VCFG extension and add " - Voice Config.XLSX" to the end. |
1 | Write-Host "Starting Excel..." |
1 | $ExcelFileName = $VCFGFileName.substring(0,$VCFGFileName.Length - 5) + " - Voice Config.XLSX" |
1 |
1 | #Create the Excel Instance we will be working with. |
1 | $ExcelApp = New-Object -comobject Excel.Application |
1 |
1 | #Create a new Workbook and add 2 extra sheets for 5 total. |
1 | Write-Host "Configuring Worksheets..." |
1 | $Workbook = $ExcelApp.Workbooks.Add() |
1 | $Worksheets = $WorkBook.Worksheets.Add() |
1 | $Worksheets = $WorkBook.Worksheets.Add() |
1 |
1 | #Name the sheets in the Workbook and assign variables to them. |
1 | $LocationProfilesSheet = $Workbook.Worksheets.Item(1) |
1 | $LocationProfilesSheet.Name = "Location Profiles" |
1 | $PSTNUsagesSheet = $Workbook.Worksheets.Item(2) |
1 | $PSTNUsagesSheet.Name = "PSTN Usages" |
1 | $PSTNRoutesSheet = $Workbook.Worksheets.Item(3) |
1 | $PSTNRoutesSheet.Name = "PSTN Routes" |
1 | $VoicePolicySheet = $Workbook.Worksheets.Item(4) |
1 | $VoicePolicySheet.Name = "Voice Policies" |
1 | $TrunkSheet = $Workbook.Worksheets.Item(5) |
1 | $TrunkSheet.Name = "Trunk Configuration" |
1 | Write-Host "Done" |
1 |
1 | #Configure layout for Location Profile Sheet |
1 | Write-Host "**Building Location Profile Sheet**" |
1 | $LocationProfilesSheet.Cells.Item(1,1) = "Dial Plan" |
1 | $LocationProfilesSheet.Cells.Item(1,2) = "Scope" |
1 | $LocationProfilesSheet.Cells.Item(1,3) = "Dial Plan Description" |
1 | $LocationProfilesSheet.Cells.Item(1,4) = "Rule" |
1 | $LocationProfilesSheet.Cells.Item(1,5) = "Rule Description" |
1 | $LocationProfilesSheet.Cells.Item(1,6) = "Pattern" |
1 | $LocationProfilesSheet.Cells.Item(1,7) = "Translation" |
1 | $LocationProfilesSheet.Cells.Item(1,8) = "Dialin Conferencing Region" |
1 |
1 | $CurrentRow = 2 |
1 |
1 | #Import XML data into Excel fields. |
1 | $LocationProfiles = @($VCFGXML.Datasource.LocationProfiles.Datasource) |
1 | ForEach ($DialPlan in $LocationProfiles){ |
1 | Write-Host "Found Dial Plan: " $DialPlan.DialPlanName |
1 | ForEach ($Rule in $DialPlan.Rules.Datasource){ |
1 | Write-Host "Importing Rule: " $Rule.Name |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,1) = $DialPlan.Name |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,2) = $DialPlan.Scope |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,3) = $DialPlan.Description |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,4) = $Rule.Name |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,5) = $Rule.Description |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,6) = $Rule.Pattern |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,7) = $Rule.Translation |
1 | $LocationProfilesSheet.Cells.Item($CurrentRow,8) = $DialPlan.DialinConferencingRegion |
1 | $CurrentRow = $CurrentRow + 1 |
1 | } |
1 | } |
1 | Write-Host "**Done with Location Profile Sheet**" |
1 |
1 | #Configure layout for PSTN Usages Sheet |
1 | Write-Host "**Building PSTN Usages Sheet**" |
1 | $PSTNUsagesSheet.Cells.Item(1,1) = "Name" |
1 | $PSTNUsagesSheet.Cells.Item(1,2) = "Identity" |
1 | $PSTNUsagesSheet.Cells.Item(1,3) = "Scope" |
1 | $CurrentRow = 2 |
1 |
1 | #Import XML data into Excel fields. |
1 | $PSTNUsages = @($VCFGXML.Datasource.PSTNUsages.Datasource) |
1 | ForEach ($Usages in $PSTNUsages){ |
1 | ForEach ($Usage in $Usages.Usages.Datasource){ |
1 | Write-Host "Importing Usage: " $Usage.Name |
1 | $PSTNUsagesSheet.Cells.Item($CurrentRow,1) = $Usage.Name |
1 | $PSTNUsagesSheet.Cells.Item($CurrentRow,2) = $Usages.Identity |
1 | $PSTNUsagesSheet.Cells.Item($CurrentRow,3) = $Usages.Scope |
1 | $CurrentRow = $CurrentRow + 1 |
1 | } |
1 | } |
1 | Write-Host "**Done with PSTN Usages Sheet**" |
1 |
1 | #Configure layout for PSTN Route Settings Sheet |
1 | Write-Host "**Building PSTN Route Settings Sheet**" |
1 | $PSTNRoutesSheet.Cells.Item(1,1) = "Route Name" |
1 | $PSTNRoutesSheet.Cells.Item(1,2) = "Usage" |
1 | $PSTNRoutesSheet.Cells.Item(1,3) = "Route Description" |
1 | $PSTNRoutesSheet.Cells.Item(1,4) = "Number Pattern" |
1 | $PSTNRoutesSheet.Cells.Item(1,5) = "Supress Caller ID" |
1 | $PSTNRoutesSheet.Cells.Item(1,6) = "PSTN Gateway" |
1 | $CurrentRow = 2 |
1 |
1 | #Import XML data into Excel fields. |
1 | $RouteSettings = @($VCFGXML.Datasource.PSTNRouteSettings.Datasource) |
1 | ForEach ($RouteGroup in $RouteSettings){ |
1 | ForEach ($Route in $RouteGroup.Routes.Datasource){ |
1 | Write-Host "Importing Route: " $Route.Name |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,1) = $Route.Name |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,3) = $Route.Description |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,4) = $Route.NumberPattern |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,5) = $Route.SuppressCallerId |
1 | ForEach ($Usage in $Route.Usages.Datasource){ |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,2) = $Usage.Name |
1 | } |
1 | ForEach ($Gateway in $Route.Gateways.Datasource){ |
1 | $PSTNRoutesSheet.Cells.Item($CurrentRow,6) = $Gateway.ServiceId |
1 | } |
1 | $CurrentRow = $CurrentRow + 1 |
1 | } |
1 | } |
1 | Write-Host "**Done with PSTN Route Settings Sheet**" |
1 |
1 | #Configure layout for Voice Policies Sheet |
1 | Write-Host "**Building Voice Policies Sheet**" |
1 | $VoicePolicySheet.Cells.Item(1,1) = "Voice Policy Name" |
1 | $VoicePolicySheet.Cells.Item(1,2) = "Description" |
1 | $VoicePolicySheet.Cells.Item(1,3) = "Scope" |
1 | $VoicePolicySheet.Cells.Item(1,4) = "Usage" |
1 | $VoicePolicySheet.Cells.Item(1,5) = "Allow Simultaneous Ring" |
1 | $VoicePolicySheet.Cells.Item(1,6) = "Allow Call Forwarding" |
1 | $VoicePolicySheet.Cells.Item(1,7) = "Allow PSTN Rerouting" |
1 | $VoicePolicySheet.Cells.Item(1,8) = "Enable Delegation" |
1 | $VoicePolicySheet.Cells.Item(1,9) = "Enable Team Call" |
1 | $VoicePolicySheet.Cells.Item(1,10) = "Enable Call Transfer" |
1 | $VoicePolicySheet.Cells.Item(1,11) = "Enable Call Park" |
1 | $VoicePolicySheet.Cells.Item(1,12) = "Enable Malicious Call tracing" |
1 | $VoicePolicySheet.Cells.Item(1,13) = "Enable Bandwidth Policy Override" |
1 | $CurrentRow = 2 |
1 |
1 | #Import XML data into Excel fields. |
1 | $VoicePolicies = @($VCFGXML.Datasource.VoicePolicies.Datasource) |
1 | ForEach ($Policy in $VoicePolicies){ |
1 | Write-Host "Importing Policies for: " $Policy.Name |
1 | ForEach ($Usage in $Policy.Usages.Datasource){ |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,1) = $Policy.Name |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,2) = $Policy.Description |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,3) = $Policy.Scope |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,4) = $Usage.Name |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,5) = $Policy.AllowSimulRing |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,6) = $Policy.AllowCallForwarding |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,7) = $Policy.AllowPSTNReRouting |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,8) = $Policy.EnableDelegation |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,9) = $Policy.EnableTeamCall |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,10) = $Policy.EnableCallTransfer |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,11) = $Policy.EnableCallPark |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,12) = $Policy.EnableMaliciousCallTracing |
1 | $VoicePolicySheet.Cells.Item($CurrentRow,13) = $Policy.EnableBWPolicyOverride |
1 | $CurrentRow = $CurrentRow + 1 |
1 | } |
1 | } |
1 | Write-Host "**Done with Voice Policies Sheet**" |
1 |
1 | #Configure layout for Trunks Sheet |
1 | Write-Host "**Building Trunk Sheet**" |
1 | $TrunkSheet.Cells.Item(1,1) = "Trunk Name" |
1 | $TrunkSheet.Cells.Item(1,2) = "Trunk Identity" |
1 | $TrunkSheet.Cells.Item(1,3) = "Scope" |
1 | $TrunkSheet.Cells.Item(1,4) = "Rule" |
1 | $TrunkSheet.Cells.Item(1,5) = "Rule Description" |
1 | $TrunkSheet.Cells.Item(1,6) = "Concentrated Topology" |
1 | $TrunkSheet.Cells.Item(1,7) = "Enable Bypass" |
1 | $TrunkSheet.Cells.Item(1,8) = "Enable Refer Support" |
1 | $TrunkSheet.Cells.Item(1,9) = "SRTP Mode" |
1 | $TrunkSheet.Cells.Item(1,10) = "Max. Early Dialogs" |
1 | $TrunkSheet.Cells.Item(1,11) = "Pattern" |
1 | $TrunkSheet.Cells.Item(1,12) = "Translation" |
1 | $CurrentRow = 2 |
1 |
1 | #Import XML data into Excel fields. |
1 | $TrunkGroup = @($VCFGXML.Datasource.Trunks.Datasource) |
1 | ForEach ($Trunk in $TrunkGroup){ |
1 | Write-Host "Found Trunk: " $Trunk.Name |
1 | ForEach ($Rule in $Trunk.Rules.Datasource){ |
1 | Write-Host "Importing Rule: " $Rule.Name |
1 | $TrunkSheet.Cells.Item($CurrentRow,1) = $Trunk.Name |
1 | $TrunkSheet.Cells.Item($CurrentRow,2) = $Trunk.Identity |
1 | $TrunkSheet.Cells.Item($CurrentRow,3) = $Trunk.Scope |
1 | $TrunkSheet.Cells.Item($CurrentRow,4) = $Rule.Name |
1 | $TrunkSheet.Cells.Item($CurrentRow,5) = $Rule.Description |
1 | $TrunkSheet.Cells.Item($CurrentRow,6) = $Trunk.ConcentratedTopology |
1 | $TrunkSheet.Cells.Item($CurrentRow,7) = $Trunk.EnableBypass |
1 | $TrunkSheet.Cells.Item($CurrentRow,8) = $Trunk.EnableReferSupport |
1 | $TrunkSheet.Cells.Item($CurrentRow,9) = $Trunk.SRTPMode |
1 | $TrunkSheet.Cells.Item($CurrentRow,10) = $Trunk.MaxEarlyDialogs |
1 | $TrunkSheet.Cells.Item($CurrentRow,11) = $Rule.Pattern |
1 | $TrunkSheet.Cells.Item($CurrentRow,12) = $Rule.Translation |
1 | $CurrentRow = $CurrentRow + 1 |
1 | } |
1 | } |
1 | Write-Host "**Done with Voice Policies Sheet**" |
1 |
1 |
1 |
1 |
1 |
1 | #Make Excel visible to the user. |
1 | $ExcelApp.Visible = $True |
1 | $Workbook.SaveAs($CurrentDirectory + "\" + $ExcelFileName) |
1 |
1 | #$ExcelApp.Quit() |
Now open up a powershell command window and navigate to the directory with the .ps1 file and .vcfg file and run the following command:
.\LyncVCFGConverter.ps1 CustomerA_Lync.vcfg
The script will extract the data and create an Excel spreadsheet. The progress is shown as the script is running:
Once the script is complete, the Excel spreadsheet will be saved and launched. You will notice that the spreadsheet is divided into different tabs:
Here are some examples from some of the other tabs…
Voice Policies:
Trunk Configuration:
Hopefully this will help you out on documenting your Lync Voice configurations! Again, thanks to Chris Cook for the heavy lifting on the powershell scripts.