<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Mahmoud Badran</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mahmoud_badran/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:05:41 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Retain Meetings, Contacts (Buddylist) and Forwarding information post Cutover Migration to Skype for Business Online</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/retain-meetings-contacts-buddylist-and-forwarding-information-post-cutover-migration-to-skype-for-business-online</link>
      <pubDate>Thu, 28 Jun 2018 18:14:51 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=805</guid>
      <description><![CDATA[In a Cutover Migration from Skype for Business on-premises or Lync 2013 the following data are...]]></description>
      <content:encoded><![CDATA[In a Cutover Migration from Skype for Business on-premises or Lync 2013 the following data are Expected to be lost:
<ul>
 	<li><del>Contacts cannot be exported, so users will have to repopulate their contact lists manually in Skype for Business Online.</del></li>
 	<li><del>Forwarding and Simultaneous ringing will be lost</del></li>
 	<li><del>Invitation for the existent meetings (Sent from on-premises Lync/Skype for Business) will need to be resent.</del></li>
</ul>
As per the blog https://blogs.technet.microsoft.com/fasttracktips/2017/08/24/skype-online-cutover-migration/

Well that is not the case anymore ; in this blog we will address all three points mentioned above.
<h1><strong>Meetings Will be Migrated!:</strong></h1>
First The Meetings WILL be Migrated and updated by the MMS service; as long as you have all the MMS requirements met as per this article

https://docs.microsoft.com/en-us/skypeforbusiness/audio-conferencing-in-office-365/setting-up-the-meeting-migration-service-mms

&nbsp;
<h1>Contacts (Buddy list) and Forwarding Information:</h1>
I re-wrote a script that was provided before  (Note Credits in Script)  that will Export these information from the UserData to a CSV and HTML file so you can re-add your Buddylist or Forwardings manually.

You will have to export all User data by the following :

# Lync 2010 export using dbimpexp.exe in command line

Dbimpexp.exe /hrxmlfile:c:\temp\userdata.xml /restype:user /sqlserver:SQLserver\instance

# Lync 2013 export using powershell

Export-CsUserData -LegacyFormat -PoolFqdn pool.fqdn -FileName c:\temp\userdata.xml

<em>The Script will use the Path of the Filename specified as the Output Directory</em>

then Use the Following script :
<pre>#--------------------------------------------------------------------------------------------------------------
# Copyright © 2018 Microsoft Corporation. All rights reserved.
#
# THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
# FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR 
# RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
# ======================================================================= 
## Description: Script Excract Buddylist and Forwarding information from the Lync/Skype Userdata
## Mahmoud Badran
## mbadran@microsoft.com
## Credits
#AdamToth- [O365] Exporting Buddy List https://answers.microsoft.com/en-us/profile/cb5754e4-4b8a-49ee-beaf-aab3ba5b59b6 
#Boe Prox - Function to Convert HTML https://gallery.technet.microsoft.com/scriptcenter/Convert-OutoutForCSV-6e552fc6 


param( [string] $ContentFilename = $(Read-Host -prompt "Please enter a file name"))

$ContentFolder = (Get-Item -Path $ContentFilename -Verbose).DirectoryName



[void] [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.IO.Compression.ZipFile]::ExtractToDirectory($ContentFilename, $ContentFolder)

"Unzip Done..."

[xml]$contact = Get-Content "$ContentFolder\userdata.xml"
$outputfile = $ContentFolder + "\Lync_SfB_Info.csv" 
$output = $contact.HomedResources.homedresource
$resultsarray =@()
$fwdinfo =@()
$tegt=@()

Function Convert-OutputForCSV {
 
 #Requires -Version 3.0
 [cmdletbinding()]
 Param (
 [parameter(ValueFromPipeline)]
 [psobject]$InputObject,
 [parameter()]
 [ValidateSet('Stack','Comma')]
 [string]$OutputPropertyType = 'Stack'
 )
 Begin {
 $PSBoundParameters.GetEnumerator() | ForEach {
 Write-Verbose "$($_)"
 }
 $FirstRun = $True
 }
 Process {
 If ($FirstRun) {
 $OutputOrder = $InputObject.psobject.properties.name
 Write-Verbose "Output Order:`n $($OutputOrder -join ', ' )"
 $FirstRun = $False
 #Get properties to process
 $Properties = Get-Member -InputObject $InputObject -MemberType *Property
 #Get properties that hold a collection
 $Properties_Collection = @(($Properties | Where-Object {
 $_.Definition -match "Collection|\[\]"
 }).Name)
 #Get properties that do not hold a collection
 $Properties_NoCollection = @(($Properties | Where-Object {
 $_.Definition -notmatch "Collection|\[\]"
 }).Name)
 Write-Verbose "Properties Found that have collections:`n $(($Properties_Collection) -join ', ')"
 Write-Verbose "Properties Found that have no collections:`n $(($Properties_NoCollection) -join ', ')"
 }
 
 $InputObject | ForEach {
 $Line = $_
 $stringBuilder = New-Object Text.StringBuilder
 $Null = $stringBuilder.AppendLine("[pscustomobject] @{")

$OutputOrder | ForEach {
 If ($OutputPropertyType -eq 'Stack') {
 $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$(($line.$($_) | Out-String).Trim())`"")
 } ElseIf ($OutputPropertyType -eq "Comma") {
 $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$($line.$($_) -join ', ')`"") 
 }
 }
 $Null = $stringBuilder.AppendLine("}")
 
 Invoke-Expression $stringBuilder.ToString()
 }
 }
 End {}
}

foreach ($user in $output)
{
$contactlist = “”
$contactObject = new-object PSObject
$sipaddress=$user.userathost
$user_contacts=$user.contacts.contact
$fwdinfo = $user.Containers.container.publication.data.routing.preamble.list 
$tegt= $user.Containers.container.publication.data.routing.preamble.list.target

foreach($buddy in $user_contacts)
{$contactlist = $contactlist + $buddy.buddy+”, ”}
$contactObject | add-member -membertype NoteProperty -name “SIP Address” -Value $sipaddress
$contactObject | add-member -membertype NoteProperty -name “Contacts” -Value $contactlist
$contactObject | add-member -membertype NoteProperty -name “FWD” -Value $fwdinfo
$contactObject | add-member -membertype NoteProperty -name “Target” -Value $tegt 
$resultsarray += $contactObject



}

$resultsarray| Convert-OutputForCSV |Export-csv $outputfile -notypeinformation

$outputfileml = $ContentFolder + "\Lync_SfB_Info.html"
$htmlformat = '&lt;title&gt;Table&lt;/title&gt;'
$htmlformat += '&lt;style type="text/css"&gt;'
$htmlformat += 'BODY{background-color:#663300;color:#FFCC00;font-family:Arial Narrow,sans-serif;font-size:17px;}'
$htmlformat += 'TABLE{border-width: 3px;border-style: solid;border-color: white;border-collapse: collapse;width: 100%;}'
$htmlformat += 'TH{border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:#663333;}'
$htmlformat += 'TD{border-width: 1px;padding: 8px;border-style: solid;border-color: black;background-color:#660033;}'
$htmlformat += '&lt;/style&gt;'
$bodyformat = '&lt;h1&gt;Lync/Skype for Business User Contacts and Forwarding Info&lt;/h1&gt;'
$resultsarray| Convert-OutputForCSV| ConvertTo-Html -Head $htmlformat -Body $bodyformat | Out-File $outputfileml</pre>
&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>CQD Online Templates for Troubleshooting</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/cqd-online-templates-for-troubleshooting</link>
      <pubDate>Wed, 07 Mar 2018 15:32:07 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=605</guid>
      <description><![CDATA[Probably you have seen many posts on how to create custom CQD reports; but in this post it will be...]]></description>
      <content:encoded><![CDATA[Probably you have seen many posts on how to create custom CQD reports; but in this post it will be more detailed on identifying issues by CQD.

First i would like to explain that CQD is not a tool to troubleshoot user issues; but rather a compass to  show you where the problem might lie.

i have attached the reports that you can import in your CQD portal and they are ready for consumption.
<div id="query-title" class="query-title">
<h1 class="query-title-text"><strong>All Modality Conferences</strong></h1>
<div class="move-button">
<div><span>This specific report displays the total number of Conference streams in relation to poor % per workload in Conferences. </span></div>
<div><a href="https://msdnshared.blob.core.windows.net/media/2018/03/0.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/0.jpg" alt="" width="186" height="424" class="alignnone wp-image-635" /></a></div>
<h2>All Modality Conferences with Dial in</h2>
<a href="https://msdnshared.blob.core.windows.net/media/2018/03/13.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/13.jpg" alt="" width="180" height="471" class="alignnone wp-image-615" /></a>
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">All Modality Conferences with Dial Out</span><span> </span></h2>
<a href="https://msdnshared.blob.core.windows.net/media/2018/03/22.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/22.jpg" alt="" width="173" height="425" class="alignnone wp-image-625" /></a>

</div>
<h2><strong><a href="https://msdnshared.blob.core.windows.net/media/2018/03/All-Modality-Conferences.zip">Download : All-Modality-Conferences</a></strong></h2>
</div>
<h1>Dropped Audio Streams</h1>
This report investigates the dropped streams based on the transport type

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/32.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/32.jpg" alt="" width="180" height="347" class="alignnone wp-image-655" /></a>
<h1>Weekly Dropped Count</h1>
Weekly Dropped rate; so you can narrow down when exactly the issue happened

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/42.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/42.jpg" alt="" width="146" height="273" class="alignnone wp-image-665" /></a>
<h2>Second Subnet Dropped</h2>
Second Subnet with Most Dropped calls

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/52.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/52.jpg" alt="" width="217" height="396" class="alignnone wp-image-675" /></a>
<h2><strong><a href="https://msdnshared.blob.core.windows.net/media/2018/03/Dropped-Audio-Streams_.zip">Download Dropped-Audio-Streams_Report</a></strong></h2>
&nbsp;
<h1>Total Failed Media and Ports report</h1>
Reasons of Failure DPI or Blocked firewall - with Detailed TCP vs UDP Ports

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/62.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/62.jpg" alt="" width="208" height="350" class="alignnone wp-image-695" /></a>
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">Audio TCP vs UDP<span> </span></span><span> Rate</span></h2>
The more TCP you see vs UDP that shows there is an issue; as the first preferred ports are UDP and it may be blocked

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/7.jpg"></a><a href="https://msdnshared.blob.core.windows.net/media/2018/03/71.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/71.jpg" alt="" width="200" height="284" class="alignnone wp-image-715" /></a><a href="https://msdnshared.blob.core.windows.net/media/2018/03/7.jpg"></a>
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">Video TCP vs UDP<span> </span></span><span> </span></h2>
The more TCP you see vs UDP that shows there is an issue; as the first preferred ports are UDP and it may be blocked

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/8.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/8.jpg" alt="" width="200" height="289" class="alignnone wp-image-725" /></a>
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">VBSS TCP vs UDP<span> </span></span><span> </span></h2>
The more TCP you see vs UDP that shows there is an issue; as the first preferred ports are UDP and it may be blocked

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/9.jpg" alt="" width="205" height="288" class="alignnone wp-image-735" /></a>
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">AppShare Connectivity</span><span> </span></h2>
App share should connect DIRECT on high TCP ports, if that is blocked it fails back to the RELAY port which can be high port TCP or port 443.

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/10.jpg" alt="" width="200" height="264" class="alignnone wp-image-745" /></a>
<h2><strong><a href="https://msdnshared.blob.core.windows.net/media/2018/03/Total-Failed-Media-and-Ports-report_.zip">Download Total-Failed-Media-and-Ports-report_</a></strong></h2>
&nbsp;
<div id="query-title" class="query-title">
<h1 class="query-title-text">Wired PSTN</h1>
<p class="query-title-text">Calls made outbound to PSTN from Wired clients <span style="font-size: 16px"> </span></p>
<a href="https://msdnshared.blob.core.windows.net/media/2018/03/111.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/111.jpg" alt="" width="198" height="458" class="alignnone wp-image-765" /></a>
<div id="query-title" class="query-title">
<h2 class="query-title-text"><span class="rovingTab" role="menuitem" title="No sub-reports available. To create a sub-report, click &quot;Add Sub-Report&quot; above the chart or table.">Users Outbound/Inbound calls to PSTN</span><span> </span></h2>
</div>
<div class="query-description"><span>Calls to and from PSTN to all and from all Clients</span></div>
<div><a href="https://msdnshared.blob.core.windows.net/media/2018/03/121.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/121.jpg" alt="" width="199" height="552" class="alignnone wp-image-775" /></a></div>
</div>
<h2><strong><a href="https://msdnshared.blob.core.windows.net/media/2018/03/Wired-PSTN.zip">Download Wired-PSTN</a></strong></h2>]]></content:encoded>
    </item>
    <item>
      <title>Skype for Business Rate My Call with Power BI Analysis</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/skype-for-business-rate-my-call-with-power-bi-analysis</link>
      <pubDate>Sat, 04 Nov 2017 02:57:11 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=425</guid>
      <description><![CDATA[When you are running a Skype for Business Online environment, CQD allows you to gain insights into...]]></description>
      <content:encoded><![CDATA[When you are running a Skype for Business Online environment, CQD allows you to gain insights into the quality of calls via metrics and absolute network measurements from calls meta data.

The context and the actual user experience is collected through the Rate My Call, the RMC data is not currently included in any existing monitoring report, but it has a separate monitoring report. Data is collected in SQL tables that can be accessed by running SQL queries (work on reports in progress).

While we are waiting for the Rate My call Reports from Microsoft there is a way to produce our customized reports by the tools available now from Power BI and in this post we will create these reports by Power BI and use the Cognitive Analysis from Azure to analyze the user sentiment.

&nbsp;

<strong><span style="color: #800000">This Report shows User Sentiment from RMC data and analyzed with Azure Cognitive services in Power BI</span></strong>

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/21.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/21.jpg" alt="" width="2483" height="1483" class="alignnone size-full wp-image-575" /></a>

<span style="color: #800000"><strong>This Report shows the Percentage of Subnets (resolved from Tenant Building Data) where users had complained by rating.</strong></span>

*Since VPN subnet in CQD shows as 1 IP per subnet its impossible to group them as one Region, in this post we will reverse-resolve them based on the Building data we have, so VPN IPs shows in their respective subnet name.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/221.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/221.jpg" alt="" width="2479" height="1491" class="alignnone size-full wp-image-595" /></a>

Requirements:

1- RMC is enabled and Users are giving feedback

2- <span>Dump from the RMC Database (Explained below)</span>

3- Power BI <span>Desktop and </span>Active account

4 - * (Optional) A Microsoft Azure account. Start a free trial or sign in.

5-<span>* (Optional)</span> A access key for Text Analytics. Sign up, then get your key.
<ul>
 	<li>* Only required for the Text Analytics report you can still skip those and use the other reports.</li>
</ul>
The Reports that we are going to Produce are the following:

1- Reports on who rated the least Stars

<span>2- Reports on who rated with most </span>feed backs

3- Correlation between feedbacks, Stars and subnets.

4- you can be creative with any report from the data given from the RMC.

&nbsp;

So lets begin with the RMC Data Dump, Thanks to Jason Shave who wrote this blog on how to extract the RMC data through his script (https://www.powershellgallery.com/packages/CxdCallData/1.1.6.1 )

This Script will dump all your RMC data in CSV files, i found the best way to utilize this script is to do an "initial Seeding/Dump" since the beginning of Rate My Call policy being applied to the users, that will take very long depending on your data, but in my case a 7,000 Users over 3 months took about 14Hrs to complete;

but then  to avoid that going forward you can edit the downloaded module to automatically fill in your credentials and run it as a schedule task every week and get the last 7 days data only which can be less than a few hrs every week,

When you install the CxdCallData it will deploy the files in the folder C:\Program Files\WindowsPowerShell\Modules\CxdCallData\1.1.6.0 you can then  edit the line

<span style="color: #339966">$global:credential = Get-Credential -Message "Authenticate to Skype for Business Online"</span>

to :

<span style="color: #0000ff">$O365_pass = cat 'C:\mypasswordfolder\Office365_securepass.txt' | convertto-securestring</span>
<span style="color: #0000ff"> $global:credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "USERNAME@TENANT.onmicrosoft.com",$O365_pass</span>

so after that i created a script to create the list of users based on their RMC policy and collect them in a CSV file and later call that module and pass that file; and my script is then added to the task scheduler to run every 7 days

<span style="color: #0000ff">Import-Module LyncOnlineConnector</span>
<span style="color: #0000ff">$O365_pass = cat 'C:\Folder Path\Office365_securepass.txt' | convertto-securestring</span>
<span style="color: #0000ff">$myO365cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "<span>USERNAME@TENANT.onmicrosoft.com</span>",$O365_pass</span>
<span style="color: #0000ff">$filename="C:\Folder Path\"+(Get-Date -format d).Replace("/","-")+"users.csv"</span>
<span style="color: #0000ff">$CSSession = New-CsOnlineSession -Credential $myo365cred</span>
<span style="color: #0000ff">Import-PSSession $CSSession -AllowClobber </span>
<span style="color: #0000ff">Get-CsOnlineUser | ? {$_.Clientpolicy -match "RateMyCallPolicy"} | select-object UserPrincipalName | Export-Csv $filename</span>
<span style="color: #0000ff">Remove-PSSession $CSSession</span>

<span style="color: #0000ff">Get-CxdCallData -ReportSavePath c:\SfB\Reports -NumberOfDaysToSearch 7 -CsvFileWithUsers $filename</span>

Below is the Export of the Task Scheduler in XML

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/1.jpg" alt="" width="1656" height="1588" class="alignnone size-full wp-image-435" /></a>

now as you see it collects all reports to <span>c:\SfB\Reports; you can only copy the SFB-UserFeedback-YYYY-MM-DD HH-MM-SS.CSV files to a folder lets call it c:\SfB\Reports\RMC</span>

now we will need to aggregate all the data in one file; so what we will do is using Excel queries run the following :

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/2.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/2.png" alt="" width="330" height="511" class="alignnone wp-image-455" />  </a><a href="https://msdnshared.blob.core.windows.net/media/2017/11/3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/3.jpg" alt="" width="609" height="347" class="alignnone wp-image-465" /></a><a href="https://msdnshared.blob.core.windows.net/media/2017/11/2.png"></a>

In the Advanced editor paste the following Query

<span style="color: #0000ff"><em>let</em></span>
<span style="color: #0000ff"><em>Source = Folder.Files("C:\FOLDER PATH\Report\RMC"),</em></span>
<span style="color: #0000ff"><em>#"Changed Type" = Table.TransformColumnTypes(Source,{{"Content", type binary}}),</em></span>
<span style="color: #0000ff"><em>Content = #"Changed Type"[Content],</em></span>
<span style="color: #0000ff"><em>#"Converted to Table" = Table.FromList(Content, Splitter.SplitByNothing(), null, null, ExtraValues.Error)</em></span>
<span style="color: #0000ff"><em>in</em></span>
<span style="color: #0000ff"><em> #"Converted to Table"</em></span>

Then do the following steps:

Select the last step from the Applied steps and expand the drop down button.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/6.jpg" alt="" width="340" height="680" class="alignnone wp-image-485" /></a>

Click on OK

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/7.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/7.jpg" alt="" width="740" height="376" class="alignnone wp-image-495" /></a>

Select the DiagID Column and then from Home&gt;Remove Rows&gt;Remove Duplicates

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/8.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/8.jpg" alt="" width="690" height="284" class="alignnone wp-image-496" /></a>

Rename The query to <strong>RMC</strong> and then Close and Load

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/9.jpg" alt="" width="273" height="531" class="alignnone wp-image-505" /></a>

Now you will get a Concatenated Excel Sheet of all the RMC User feedback reports in CSV from the Specified folder; make sure you only have those reports and nothing else in the folder, you can keep adding the reports there and Refresh the Excel sheet query to aggregate all files and build the new records.

After we had all results aggregated we will need to add some information that will help us build our reports with relation to our Network.

first we will add the functions that can calculate subnets in the Excel sheet, start by pressing ALT+F11

then Insert new Module as Shown here:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/10.jpg" alt="" width="369" height="410" class="alignnone wp-image-515" /></a>

Then paste the following functions
<pre><em><span style="color: #0000ff">' Copyright 2010-2017 Thomas Rohmer-Kretz</span></em>

<em><span style="color: #0000ff">' This program is free software: you can redistribute it and/or modify</span></em>
<em><span style="color: #0000ff">' it under the terms of the GNU General Public License as published by</span></em>
<em><span style="color: #0000ff">' the Free Software Foundation, either version 3 of the License, or</span></em>
<em><span style="color: #0000ff">' (at your option) any later version.</span></em>

<em><span style="color: #0000ff">' This program is distributed in the hope that it will be useful,</span></em>
<em><span style="color: #0000ff">' but WITHOUT ANY WARRANTY; without even the implied warranty of</span></em>
<em><span style="color: #0000ff">' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span></em>
<em><span style="color: #0000ff">' GNU General Public License for more details.</span></em>

<em><span style="color: #0000ff">' You should have received a copy of the GNU General Public License</span></em>
<em><span style="color: #0000ff">' along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span></em>

<em><span style="color: #0000ff">' http://trk.free.fr/ipcalc/</span></em>

<em><span style="color: #0000ff">' Visual Basic for Excel</span></em>

<em><span style="color: #0000ff">'==============================================</span></em>
<em><span style="color: #0000ff">' IP v4</span></em>
<em><span style="color: #0000ff">'==============================================</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpIsValid</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Returns true if an ip address is formated exactly as it should be:</span></em>
<em><span style="color: #0000ff">' no space, no extra zero, no incorrect value</span></em>
<em><span style="color: #0000ff">Function IpIsValid(ByVal ip As String) As Boolean</span></em>
<em><span style="color: #0000ff"> IpIsValid = (IpBinToStr(IpStrToBin(ip)) = ip)</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpStrToBin</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Converts a text IP address to binary</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpStrToBin("1.2.3.4") returns 16909060</span></em>
<em><span style="color: #0000ff">Function IpStrToBin(ByVal ip As String) As Double</span></em>
<em><span style="color: #0000ff"> Dim pos As Integer</span></em>
<em><span style="color: #0000ff"> ip = ip + "."</span></em>
<em><span style="color: #0000ff"> IpStrToBin = 0</span></em>
<em><span style="color: #0000ff"> While ip &lt;&gt; ""</span></em>
<em><span style="color: #0000ff"> pos = InStr(ip, ".")</span></em>
<em><span style="color: #0000ff"> IpStrToBin = IpStrToBin * 256 + Val(Left(ip, pos - 1))</span></em>
<em><span style="color: #0000ff"> ip = Mid(ip, pos + 1)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpBinToStr</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Converts a binary IP address to text</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpBinToStr(16909060) returns "1.2.3.4"</span></em>
<em><span style="color: #0000ff">Function IpBinToStr(ByVal ip As Double) As String</span></em>
<em><span style="color: #0000ff"> Dim divEnt As Double</span></em>
<em><span style="color: #0000ff"> Dim i As Integer</span></em>
<em><span style="color: #0000ff"> i = 0</span></em>
<em><span style="color: #0000ff"> IpBinToStr = ""</span></em>
<em><span style="color: #0000ff"> While i &lt; 4</span></em>
<em><span style="color: #0000ff"> If IpBinToStr &lt;&gt; "" Then IpBinToStr = "." + IpBinToStr</span></em>
<em><span style="color: #0000ff"> divEnt = Int(ip / 256)</span></em>
<em><span style="color: #0000ff"> IpBinToStr = Format(ip - (divEnt * 256)) + IpBinToStr</span></em>
<em><span style="color: #0000ff"> ip = divEnt</span></em>
<em><span style="color: #0000ff"> i = i + 1</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetToBin</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Converts a subnet to binary</span></em>
<em><span style="color: #0000ff">' This function is similar to IpStrToBin but ignores the host part of the address</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSubnetToBin("1.2.3.4/24") returns 16909056</span></em>
<em><span style="color: #0000ff">' IpSubnetToBin("1.2.3.0/24") returns 16909056</span></em>
<em><span style="color: #0000ff">Function IpSubnetToBin(ByVal ip As String) As Double</span></em>
<em><span style="color: #0000ff"> Dim l As Integer</span></em>
<em><span style="color: #0000ff"> Dim pos As Integer</span></em>
<em><span style="color: #0000ff"> Dim v As Integer</span></em>
<em><span style="color: #0000ff"> l = IpSubnetParse(ip)</span></em>
<em><span style="color: #0000ff"> ip = ip + "."</span></em>
<em><span style="color: #0000ff"> IpSubnetToBin = 0</span></em>
<em><span style="color: #0000ff"> While ip &lt;&gt; ""</span></em>
<em><span style="color: #0000ff"> pos = InStr(ip, ".")</span></em>
<em><span style="color: #0000ff"> v = Val(Left(ip, pos - 1))</span></em>
<em><span style="color: #0000ff"> If (l &lt;= 0) Then</span></em>
<em><span style="color: #0000ff"> v = 0</span></em>
<em><span style="color: #0000ff"> ElseIf (l &lt; 8) Then</span></em>
<em><span style="color: #0000ff"> v = v And ((2 ^ l - 1) * 2 ^ (8 - l))</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> IpSubnetToBin = IpSubnetToBin * 256 + v</span></em>
<em><span style="color: #0000ff"> ip = Mid(ip, pos + 1)</span></em>
<em><span style="color: #0000ff"> l = l - 8</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpAdd</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpAdd("192.168.1.1"; 4) returns "192.168.1.5"</span></em>
<em><span style="color: #0000ff">' IpAdd("192.168.1.1"; 256) returns "192.168.2.1"</span></em>
<em><span style="color: #0000ff">Function IpAdd(ByVal ip As String, offset As Double) As String</span></em>
<em><span style="color: #0000ff"> IpAdd = IpBinToStr(IpStrToBin(ip) + offset)</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpAnd</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' bitwise AND</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpAnd("192.168.1.1"; "255.255.255.0") returns "192.168.1.0"</span></em>
<em><span style="color: #0000ff">Function IpAnd(ByVal ip1 As String, ByVal ip2 As String) As String</span></em>
<em><span style="color: #0000ff"> ' compute bitwise AND from right to left</span></em>
<em><span style="color: #0000ff"> Dim result As String</span></em>
<em><span style="color: #0000ff"> While ((ip1 &lt;&gt; "") And (ip2 &lt;&gt; ""))</span></em>
<em><span style="color: #0000ff"> Call IpBuild(IpParse(ip1) And IpParse(ip2), result)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpAnd = result</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpOr</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' bitwise OR</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpOr("192.168.1.1"; "0.0.0.255") returns "192.168.1.255"</span></em>
<em><span style="color: #0000ff">Function IpOr(ByVal ip1 As String, ByVal ip2 As String) As String</span></em>
<em><span style="color: #0000ff"> ' compute bitwise OR from right to left</span></em>
<em><span style="color: #0000ff"> Dim result As String</span></em>
<em><span style="color: #0000ff"> While ((ip1 &lt;&gt; "") And (ip2 &lt;&gt; ""))</span></em>
<em><span style="color: #0000ff"> Call IpBuild(IpParse(ip1) Or IpParse(ip2), result)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpOr = result</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpXor</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' bitwise XOR</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpXor("192.168.1.1"; "0.0.0.255") returns "192.168.1.254"</span></em>
<em><span style="color: #0000ff">Function IpXor(ByVal ip1 As String, ByVal ip2 As String) As String</span></em>
<em><span style="color: #0000ff"> ' compute bitwise XOR from right to left</span></em>
<em><span style="color: #0000ff"> Dim result As String</span></em>
<em><span style="color: #0000ff"> While ((ip1 &lt;&gt; "") And (ip2 &lt;&gt; ""))</span></em>
<em><span style="color: #0000ff"> Call IpBuild(IpParse(ip1) Xor IpParse(ip2), result)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpXor = result</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpAdd2</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' another implementation of IpAdd which not use the binary representation</span></em>
<em><span style="color: #0000ff">Function IpAdd2(ByVal ip As String, offset As Double) As String</span></em>
<em><span style="color: #0000ff"> Dim result As String</span></em>
<em><span style="color: #0000ff"> While (ip &lt;&gt; "")</span></em>
<em><span style="color: #0000ff"> offset = IpBuild(IpParse(ip) + offset, result)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpAdd2 = result</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpComp</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Compares the first 'n' bits of ip1 and ip2</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpComp("10.0.0.0", "10.1.0.0", 9) returns TRUE</span></em>
<em><span style="color: #0000ff">' IpComp("10.0.0.0", "10.1.0.0", 16) returns FALSE</span></em>
<em><span style="color: #0000ff">Function IpComp(ByVal ip1 As String, ByVal ip2 As String, ByVal n As Integer) As Boolean</span></em>
<em><span style="color: #0000ff"> Dim pos1 As Integer</span></em>
<em><span style="color: #0000ff"> Dim pos2 As Integer</span></em>
<em><span style="color: #0000ff"> Dim mask As Integer</span></em>
<em><span style="color: #0000ff"> ip1 = ip1 + "."</span></em>
<em><span style="color: #0000ff"> ip2 = ip2 + "."</span></em>
<em><span style="color: #0000ff"> While (n &gt; 0) And (ip1 &lt;&gt; "") And (ip2 &lt;&gt; "")</span></em>
<em><span style="color: #0000ff"> pos1 = InStr(ip1, ".")</span></em>
<em><span style="color: #0000ff"> pos2 = InStr(ip2, ".")</span></em>
<em><span style="color: #0000ff"> If n &gt;= 8 Then</span></em>
<em><span style="color: #0000ff"> If pos1 &lt;&gt; pos2 Then</span></em>
<em><span style="color: #0000ff"> IpComp = False</span></em>
<em><span style="color: #0000ff"> Exit Function</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> If Left(ip1, pos1) &lt;&gt; Left(ip2, pos2) Then</span></em>
<em><span style="color: #0000ff"> IpComp = False</span></em>
<em><span style="color: #0000ff"> Exit Function</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> mask = (2 ^ n - 1) * 2 ^ (8 - n)</span></em>
<em><span style="color: #0000ff"> IpComp = ((Val(Left(ip1, pos1 - 1)) And mask) = (Val(Left(ip2, pos2 - 1)) And mask))</span></em>
<em><span style="color: #0000ff"> Exit Function</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> n = n - 8</span></em>
<em><span style="color: #0000ff"> ip1 = Mid(ip1, pos1 + 1)</span></em>
<em><span style="color: #0000ff"> ip2 = Mid(ip2, pos2 + 1)</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpComp = True</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpGetByte</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' get one byte from an ip address given its position</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpGetByte("192.168.1.1"; 1) returns 192</span></em>
<em><span style="color: #0000ff">Function IpGetByte(ByVal ip As String, pos As Integer) As Integer</span></em>
<em><span style="color: #0000ff"> pos = 4 - pos</span></em>
<em><span style="color: #0000ff"> For i = 0 To pos</span></em>
<em><span style="color: #0000ff"> IpGetByte = IpParse(ip)</span></em>
<em><span style="color: #0000ff"> Next</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSetByte</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' set one byte in an ip address given its position and value</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSetByte("192.168.1.1"; 4; 20) returns "192.168.1.20"</span></em>
<em><span style="color: #0000ff">Function IpSetByte(ByVal ip As String, pos As Integer, newvalue As Integer) As String</span></em>
<em><span style="color: #0000ff"> Dim result As String</span></em>
<em><span style="color: #0000ff"> Dim byteval As Double</span></em>
<em><span style="color: #0000ff"> i = 4</span></em>
<em><span style="color: #0000ff"> While (ip &lt;&gt; "")</span></em>
<em><span style="color: #0000ff"> byteval = IpParse(ip)</span></em>
<em><span style="color: #0000ff"> If (i = pos) Then byteval = newvalue</span></em>
<em><span style="color: #0000ff"> Call IpBuild(byteval, result)</span></em>
<em><span style="color: #0000ff"> i = i - 1</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> IpSetByte = result</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpMask</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns an IP netmask from a subnet</span></em>
<em><span style="color: #0000ff">' both notations are accepted</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpMask("192.168.1.1/24") returns "255.255.255.0"</span></em>
<em><span style="color: #0000ff">' IpMask("192.168.1.1 255.255.255.0") returns "255.255.255.0"</span></em>
<em><span style="color: #0000ff">Function IpMask(ByVal ip As String) As String</span></em>
<em><span style="color: #0000ff"> IpMask = IpBinToStr(IpMaskBin(ip))</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpWildMask</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns an IP Wildcard (inverse) mask from a subnet</span></em>
<em><span style="color: #0000ff">' both notations are accepted</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpWildMask("192.168.1.1/24") returns "0.0.0.255"</span></em>
<em><span style="color: #0000ff">' IpWildMask("192.168.1.1 255.255.255.0") returns "0.0.0.255"</span></em>
<em><span style="color: #0000ff">Function IpWildMask(ByVal ip As String) As String</span></em>
<em><span style="color: #0000ff"> IpWildMask = IpBinToStr(((2 ^ 32) - 1) - IpMaskBin(ip))</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpInvertMask</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns an IP Wildcard (inverse) mask from a subnet mask</span></em>
<em><span style="color: #0000ff">' or a subnet mask from a wildcard mask</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpInvertMask("255.255.255.0") returns "0.0.0.255"</span></em>
<em><span style="color: #0000ff">' IpInvertMask("0.0.0.255") returns "255.255.255.0"</span></em>
<em><span style="color: #0000ff">Function IpInvertMask(ByVal mask As String) As String</span></em>
<em><span style="color: #0000ff"> IpInvertMask = IpBinToStr(((2 ^ 32) - 1) - IpStrToBin(mask))</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpMaskLen</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns prefix length from a mask given by a string notation (xx.xx.xx.xx)</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpMaskLen("255.255.255.0") returns 24 which is the number of bits of the subnetwork prefix</span></em>
<em><span style="color: #0000ff">Function IpMaskLen(ByVal ipmaskstr As String) As Integer</span></em>
<em><span style="color: #0000ff"> Dim notMask As Double</span></em>
<em><span style="color: #0000ff"> notMask = 2 ^ 32 - 1 - IpStrToBin(ipmaskstr)</span></em>
<em><span style="color: #0000ff"> zeroBits = 0</span></em>
<em><span style="color: #0000ff"> Do While notMask &lt;&gt; 0</span></em>
<em><span style="color: #0000ff"> notMask = Int(notMask / 2)</span></em>
<em><span style="color: #0000ff"> zeroBits = zeroBits + 1</span></em>
<em><span style="color: #0000ff"> Loop</span></em>
<em><span style="color: #0000ff"> IpMaskLen = 32 - zeroBits</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpWithoutMask</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' removes the netmask notation at the end of the IP</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpWithoutMask("192.168.1.1/24") returns "192.168.1.1"</span></em>
<em><span style="color: #0000ff">' IpWithoutMask("192.168.1.1 255.255.255.0") returns "192.168.1.1"</span></em>
<em><span style="color: #0000ff">Function IpWithoutMask(ByVal ip As String) As String</span></em>
<em><span style="color: #0000ff"> Dim p As Integer</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, "/")</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, " ")</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> IpWithoutMask = ip</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpWithoutMask = Left(ip, p - 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetLen</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' get the mask len from a subnet</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSubnetLen("192.168.1.1/24") returns 24</span></em>
<em><span style="color: #0000ff">' IpSubnetLen("192.168.1.1 255.255.255.0") returns 24</span></em>
<em><span style="color: #0000ff">Function IpSubnetLen(ByVal ip As String) As Integer</span></em>
<em><span style="color: #0000ff"> Dim p As Integer</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, "/")</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, " ")</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> IpSubnetLen = 32</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetLen = IpMaskLen(Mid(ip, p + 1))</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetLen = Val(Mid(ip, p + 1))</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetParse</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Get the mask len from a subnet and remove the mask from the address</span></em>
<em><span style="color: #0000ff">' The ip parameter is modified and the subnet mask is removed</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSubnetLen("192.168.1.1/24") returns 24 and ip is changed to "192.168.1.1"</span></em>
<em><span style="color: #0000ff">' IpSubnetLen("192.168.1.1 255.255.255.0") returns 24 and ip is changed to "192.168.1.1"</span></em>
<em><span style="color: #0000ff">Function IpSubnetParse(ByRef ip As String) As Integer</span></em>
<em><span style="color: #0000ff"> Dim p As Integer</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, "/")</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> p = InStr(ip, " ")</span></em>
<em><span style="color: #0000ff"> If (p = 0) Then</span></em>
<em><span style="color: #0000ff"> IpSubnetParse = 32</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetParse = IpMaskLen(Mid(ip, p + 1))</span></em>
<em><span style="color: #0000ff"> ip = Left(ip, p - 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetParse = Val(Mid(ip, p + 1))</span></em>
<em><span style="color: #0000ff"> ip = Left(ip, p - 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetSize</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns the number of addresses in a subnet</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSubnetSize("192.168.1.32/29") returns 8</span></em>
<em><span style="color: #0000ff">' IpSubnetSize("192.168.1.0 255.255.255.0") returns 256</span></em>
<em><span style="color: #0000ff">Function IpSubnetSize(ByVal subnet As String) As Double</span></em>
<em><span style="color: #0000ff"> IpSubnetSize = 2 ^ (32 - IpSubnetLen(subnet))</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpClearHostBits</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' set to zero the bits in the host part of an address</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpClearHostBits("192.168.1.1/24") returns "192.168.1.0/24"</span></em>
<em><span style="color: #0000ff">' IpClearHostBits("192.168.1.193 255.255.255.128") returns "192.168.1.128 255.255.255.128"</span></em>
<em><span style="color: #0000ff">Function IpClearHostBits(ByVal net As String) As String</span></em>
<em><span style="color: #0000ff"> Dim ip As String</span></em>
<em><span style="color: #0000ff"> ip = IpWithoutMask(net)</span></em>
<em><span style="color: #0000ff"> IpClearHostBits = IpAnd(ip, IpMask(net)) + Mid(net, Len(ip) + 1)</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpIsInSubnet</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Returns TRUE if "ip" is in "subnet"</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpIsInSubnet("192.168.1.35"; "192.168.1.32/29") returns TRUE</span></em>
<em><span style="color: #0000ff">' IpIsInSubnet("192.168.1.35"; "192.168.1.32 255.255.255.248") returns TRUE</span></em>
<em><span style="color: #0000ff">' IpIsInSubnet("192.168.1.41"; "192.168.1.32/29") returns FALSE</span></em>
<em><span style="color: #0000ff">Function IpIsInSubnet(ByVal ip As String, ByVal subnet As String) As Boolean</span></em>
<em><span style="color: #0000ff"> Dim l As Integer</span></em>
<em><span style="color: #0000ff"> l = IpSubnetParse(subnet)</span></em>
<em><span style="color: #0000ff"> IpIsInSubnet = IpComp(ip, subnet, l)</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetMatch</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Tries to match an IP address or a subnet against a list of subnets in the</span></em>
<em><span style="color: #0000ff">' left-most column of table_array and returns the row number</span></em>
<em><span style="color: #0000ff">' 'ip' is the value to search for in the subnets in the first column of</span></em>
<em><span style="color: #0000ff">' the table_array</span></em>
<em><span style="color: #0000ff">' 'table_array' is one or more columns of data</span></em>
<em><span style="color: #0000ff">' 'fast' indicates the search mode : BestMatch or Fast mode</span></em>
<em><span style="color: #0000ff">' fast = 0 (default value)</span></em>
<em><span style="color: #0000ff">' This will work on any subnet list. If the search value matches more</span></em>
<em><span style="color: #0000ff">' than one subnet, the smallest subnet will be returned (best match)</span></em>
<em><span style="color: #0000ff">' fast = 1</span></em>
<em><span style="color: #0000ff">' The subnet list MUST be sorted in ascending order and MUST NOT contain</span></em>
<em><span style="color: #0000ff">' overlapping subnets. This mode performs a dichotomic search and runs</span></em>
<em><span style="color: #0000ff">' much faster with large subnet lists.</span></em>
<em><span style="color: #0000ff">' The function returns 0 if the IP address is not matched.</span></em>
<em><span style="color: #0000ff">Function IpSubnetMatch(ByVal ip As String, table_array As Range, Optional fast As Boolean = False) As Integer</span></em>
<em><span style="color: #0000ff"> Dim i As Integer</span></em>
<em><span style="color: #0000ff"> IpSubnetMatch = 0</span></em>
<em><span style="color: #0000ff"> If fast Then</span></em>
<em><span style="color: #0000ff"> Dim a As Integer</span></em>
<em><span style="color: #0000ff"> Dim b As Integer</span></em>
<em><span style="color: #0000ff"> Dim ip_bin As Double</span></em>
<em><span style="color: #0000ff"> a = 1</span></em>
<em><span style="color: #0000ff"> b = table_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> ip_bin = IpSubnetToBin(ip)</span></em>
<em><span style="color: #0000ff"> Do</span></em>
<em><span style="color: #0000ff"> i = (a + b + 0.5) / 2</span></em>
<em><span style="color: #0000ff"> If ip_bin &lt; IpSubnetToBin(table_array.Cells(i, 1)) Then</span></em>
<em><span style="color: #0000ff"> b = i - 1</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> a = i</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Loop While a &lt; b</span></em>
<em><span style="color: #0000ff"> If IpSubnetIsInSubnet(ip, table_array.Cells(a, 1)) Then</span></em>
<em><span style="color: #0000ff"> IpSubnetMatch = a</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> Dim previousMatchLen As Integer</span></em>
<em><span style="color: #0000ff"> Dim searchLen As Integer</span></em>
<em><span style="color: #0000ff"> Dim subnet As String</span></em>
<em><span style="color: #0000ff"> Dim subnetLen As Integer</span></em>
<em><span style="color: #0000ff"> searchLen = IpSubnetParse(ip)</span></em>
<em><span style="color: #0000ff"> previousMatchLen = 0</span></em>
<em><span style="color: #0000ff"> For i = 1 To table_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> subnet = table_array.Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> subnetLen = IpSubnetParse(subnet)</span></em>
<em><span style="color: #0000ff"> If subnetLen &gt; previousMatchLen Then</span></em>
<em><span style="color: #0000ff"> If searchLen &gt;= subnetLen Then</span></em>
<em><span style="color: #0000ff"> If IpComp(ip, subnet, subnetLen) Then</span></em>
<em><span style="color: #0000ff"> previousMatchLen = subnetLen</span></em>
<em><span style="color: #0000ff"> IpSubnetMatch = i</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetVLookup</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Tries to match an IP address or a subnet against a list of subnets in the</span></em>
<em><span style="color: #0000ff">' left-most column of table_array and returns the value in the same row based</span></em>
<em><span style="color: #0000ff">' on the index_number</span></em>
<em><span style="color: #0000ff">' 'ip' is the value to search for in the subnets in the first column of</span></em>
<em><span style="color: #0000ff">' the table_array</span></em>
<em><span style="color: #0000ff">' 'table_array' is one or more columns of data</span></em>
<em><span style="color: #0000ff">' 'index_number' is the column number in table_array from which the matching</span></em>
<em><span style="color: #0000ff">' value must be returned. The first column which contains subnets is 1.</span></em>
<em><span style="color: #0000ff">' 'fast' indicates the search mode : BestMatch or Fast mode</span></em>
<em><span style="color: #0000ff">' fast = 0 (default value)</span></em>
<em><span style="color: #0000ff">' This will work on any subnet list. If the search value matches more</span></em>
<em><span style="color: #0000ff">' than one subnet, the smallest subnet will be returned (best match)</span></em>
<em><span style="color: #0000ff">' fast = 1</span></em>
<em><span style="color: #0000ff">' The subnet list MUST be sorted in ascending order and MUST NOT contain</span></em>
<em><span style="color: #0000ff">' overlapping subnets. This mode performs a dichotomic search and runs</span></em>
<em><span style="color: #0000ff">' much faster with large subnet lists.</span></em>
<em><span style="color: #0000ff">' Note: add 0.0.0.0/0 in the array if you want the function to return a</span></em>
<em><span style="color: #0000ff">' default value (best match mode only)</span></em>
<em><span style="color: #0000ff">Function IpSubnetVLookup(ByVal ip As String, table_array As Range, index_number As Integer, Optional fast As Boolean = False) As String</span></em>
<em><span style="color: #0000ff"> Dim i As Integer</span></em>
<em><span style="color: #0000ff"> i = IpSubnetMatch(ip, table_array, fast)</span></em>
<em><span style="color: #0000ff"> If i = 0 Then</span></em>
<em><span style="color: #0000ff"> IpSubnetVLookup = "Not Found"</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetVLookup = table_array.Cells(i, index_number)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetVLookupAreas</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Same as IpSubnetVLookup except that table_array parameter can be a</span></em>
<em><span style="color: #0000ff">' named area containing multiple tables. Use it if you want to search in</span></em>
<em><span style="color: #0000ff">' more than one table.</span></em>
<em><span style="color: #0000ff">' Doesn't have the 'fast' option.</span></em>
<em><span style="color: #0000ff">Function IpSubnetVLookupAreas(ByVal ip As String, table_array As Range, index_number As Integer) As String</span></em>
<em><span style="color: #0000ff"> Dim previousMatch As String</span></em>
<em><span style="color: #0000ff"> previousMatch = "0.0.0.0/0"</span></em>
<em><span style="color: #0000ff"> IpSubnetVLookupAreas = "Not Found"</span></em>
<em><span style="color: #0000ff"> For a = 1 To table_array.Areas.Count</span></em>
<em><span style="color: #0000ff"> For i = 1 To table_array.Areas(a).Rows.Count</span></em>
<em><span style="color: #0000ff"> Dim subnet As String</span></em>
<em><span style="color: #0000ff"> subnet = table_array.Areas(a).Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> If IpIsInSubnet(ip, subnet) And (IpSubnetLen(subnet) &gt; IpSubnetLen(previousMatch)) Then</span></em>
<em><span style="color: #0000ff"> previousMatch = subnet</span></em>
<em><span style="color: #0000ff"> IpSubnetVLookupAreas = table_array.Areas(a).Cells(i, index_number)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> Next a</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetIsInSubnet</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Returns TRUE if "subnet1" is in "subnet2"</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpSubnetIsInSubnet("192.168.1.35/30"; "192.168.1.32/29") returns TRUE</span></em>
<em><span style="color: #0000ff">' IpSubnetIsInSubnet("192.168.1.41/30"; "192.168.1.32/29") returns FALSE</span></em>
<em><span style="color: #0000ff">' IpSubnetIsInSubnet("192.168.1.35/28"; "192.168.1.32/29") returns FALSE</span></em>
<em><span style="color: #0000ff">' IpSubnetIsInSubnet("192.168.0.128 255.255.255.128"; "192.168.0.0 255.255.255.0") returns TRUE</span></em>
<em><span style="color: #0000ff">Function IpSubnetIsInSubnet(ByVal subnet1 As String, ByVal subnet2 As String) As Boolean</span></em>
<em><span style="color: #0000ff"> Dim l1 As Integer</span></em>
<em><span style="color: #0000ff"> Dim l2 As Integer</span></em>
<em><span style="color: #0000ff"> l1 = IpSubnetParse(subnet1)</span></em>
<em><span style="color: #0000ff"> l2 = IpSubnetParse(subnet2)</span></em>
<em><span style="color: #0000ff"> If l1 &lt; l2 Then</span></em>
<em><span style="color: #0000ff"> IpSubnetIsInSubnet = False</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpSubnetIsInSubnet = IpComp(subnet1, subnet2, l2)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpFindOverlappingSubnets</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' this function must be used in an array formula</span></em>
<em><span style="color: #0000ff">' it will find in the list of subnets which subnets overlap</span></em>
<em><span style="color: #0000ff">' 'SubnetsArray' is single column array containing a list of subnets, the</span></em>
<em><span style="color: #0000ff">' list may be sorted or not</span></em>
<em><span style="color: #0000ff">' the return value is also a array of the same size</span></em>
<em><span style="color: #0000ff">' if the subnet on line x is included in a larger subnet from another line,</span></em>
<em><span style="color: #0000ff">' this function returns an array in which line x contains the value of the</span></em>
<em><span style="color: #0000ff">' larger subnet</span></em>
<em><span style="color: #0000ff">' if the subnet on line x is distinct from any other subnet in the array,</span></em>
<em><span style="color: #0000ff">' then this function returns on line x an empty cell</span></em>
<em><span style="color: #0000ff">' if there are no overlapping subnets in the input array, the returned array</span></em>
<em><span style="color: #0000ff">' is empty</span></em>
<em><span style="color: #0000ff">Function IpFindOverlappingSubnets(subnets_array As Range) As Variant</span></em>
<em><span style="color: #0000ff"> Dim result_array() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim result_array(1 To subnets_array.Rows.Count, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To subnets_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> result_array(i, 1) = ""</span></em>
<em><span style="color: #0000ff"> For j = 1 To subnets_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> If (i &lt;&gt; j) And IpSubnetIsInSubnet(subnets_array.Cells(i, 1), subnets_array.Cells(j, 1)) Then</span></em>
<em><span style="color: #0000ff"> result_array(i, 1) = subnets_array.Cells(j, 1)</span></em>
<em><span style="color: #0000ff"> Exit For</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next j</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpFindOverlappingSubnets = result_array</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSortArray</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' this function must be used in an array formula</span></em>
<em><span style="color: #0000ff">' 'ip_array' is a single column array containing ip addresses</span></em>
<em><span style="color: #0000ff">' the return value is also a array of the same size containing the same</span></em>
<em><span style="color: #0000ff">' addresses sorted in ascending or descending order</span></em>
<em><span style="color: #0000ff">' 'descending' is an optional parameter, if set to True the adresses are</span></em>
<em><span style="color: #0000ff">' sorted in descending order</span></em>
<em><span style="color: #0000ff">Function IpSortArray(ip_array As Range, Optional descending As Boolean = False) As Variant</span></em>
<em><span style="color: #0000ff"> Dim s As Integer</span></em>
<em><span style="color: #0000ff"> Dim t As Integer</span></em>
<em><span style="color: #0000ff"> t = 0</span></em>
<em><span style="color: #0000ff"> s = ip_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> Dim list() As Double</span></em>
<em><span style="color: #0000ff"> ReDim list(1 To s)</span></em>
<em><span style="color: #0000ff"> ' copy the IP list as binary values</span></em>
<em><span style="color: #0000ff"> For i = 1 To s</span></em>
<em><span style="color: #0000ff"> If (ip_array.Cells(i, 1) &lt;&gt; 0) Then</span></em>
<em><span style="color: #0000ff"> t = t + 1</span></em>
<em><span style="color: #0000ff"> list(t) = IpStrToBin(ip_array.Cells(i, 1))</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' sort the list with bubble sort</span></em>
<em><span style="color: #0000ff"> For i = t - 1 To 1 Step -1</span></em>
<em><span style="color: #0000ff"> For j = 1 To i</span></em>
<em><span style="color: #0000ff"> If ((list(j) &gt; list(j + 1)) Xor descending) Then</span></em>
<em><span style="color: #0000ff"> Dim swap As Double</span></em>
<em><span style="color: #0000ff"> swap = list(j)</span></em>
<em><span style="color: #0000ff"> list(j) = list(j + 1)</span></em>
<em><span style="color: #0000ff"> list(j + 1) = swap</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next j</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' copy the sorted list as strings</span></em>
<em><span style="color: #0000ff"> Dim resultArray() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim resultArray(1 To s, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To t</span></em>
<em><span style="color: #0000ff"> resultArray(i, 1) = IpBinToStr(list(i))</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpSortArray = resultArray</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetSortArray</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' this function must be used in an array formula</span></em>
<em><span style="color: #0000ff">' 'ip_array' is a single column array containing ip subnets in "prefix/len"</span></em>
<em><span style="color: #0000ff">' or "prefix mask" notation</span></em>
<em><span style="color: #0000ff">' the return value is also an array of the same size containing the same</span></em>
<em><span style="color: #0000ff">' subnets sorted in ascending or descending order</span></em>
<em><span style="color: #0000ff">' 'descending' is an optional parameter, if set to True the subnets are</span></em>
<em><span style="color: #0000ff">' sorted in descending order</span></em>
<em><span style="color: #0000ff">Function IpSubnetSortArray(ip_array As Range, Optional descending As Boolean = False) As Variant</span></em>
<em><span style="color: #0000ff"> Dim s As Integer</span></em>
<em><span style="color: #0000ff"> Dim t As Integer</span></em>
<em><span style="color: #0000ff"> t = 0</span></em>
<em><span style="color: #0000ff"> s = ip_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> Dim list() As String</span></em>
<em><span style="color: #0000ff"> ReDim list(1 To s)</span></em>
<em><span style="color: #0000ff"> ' copy the IP list as binary values</span></em>
<em><span style="color: #0000ff"> For i = 1 To s</span></em>
<em><span style="color: #0000ff"> If (ip_array.Cells(i, 1) &lt;&gt; 0) Then</span></em>
<em><span style="color: #0000ff"> t = t + 1</span></em>
<em><span style="color: #0000ff"> list(t) = ip_array.Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' sort the list with bubble sort</span></em>
<em><span style="color: #0000ff"> For i = t - 1 To 1 Step -1</span></em>
<em><span style="color: #0000ff"> For j = 1 To i</span></em>
<em><span style="color: #0000ff"> Dim m, n As Double</span></em>
<em><span style="color: #0000ff"> m = IpStrToBin(list(j))</span></em>
<em><span style="color: #0000ff"> n = IpStrToBin(list(j + 1))</span></em>
<em><span style="color: #0000ff"> If (((m &gt; n) Or ((m = n) And (IpMaskBin(list(j)) &lt; IpMaskBin(list(j + 1))))) Xor descending) Then</span></em>
<em><span style="color: #0000ff"> Dim swap As String</span></em>
<em><span style="color: #0000ff"> swap = list(j)</span></em>
<em><span style="color: #0000ff"> list(j) = list(j + 1)</span></em>
<em><span style="color: #0000ff"> list(j + 1) = swap</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next j</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' copy the sorted list as strings</span></em>
<em><span style="color: #0000ff"> Dim resultArray() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim resultArray(1 To s, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To t</span></em>
<em><span style="color: #0000ff"> resultArray(i, 1) = list(i)</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpSubnetSortArray = resultArray</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpParseRoute</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' this function is used by IpSubnetSortJoinArray to extract the subnet</span></em>
<em><span style="color: #0000ff">' and next hop in route</span></em>
<em><span style="color: #0000ff">' the supported formats are</span></em>
<em><span style="color: #0000ff">' 10.0.0.0 255.255.255.0 1.2.3.4</span></em>
<em><span style="color: #0000ff">' 10.0.0.0/24 1.2.3.4</span></em>
<em><span style="color: #0000ff">' the next hop can be any character sequence, and not only an IP</span></em>
<em><span style="color: #0000ff">Function IpParseRoute(ByVal route As String, ByRef nexthop As String)</span></em>
<em><span style="color: #0000ff"> slash = InStr(route, "/")</span></em>
<em><span style="color: #0000ff"> sp = InStr(route, " ")</span></em>
<em><span style="color: #0000ff"> If ((slash = 0) And (sp &gt; 0)) Then</span></em>
<em><span style="color: #0000ff"> temp = Mid(route, sp + 1)</span></em>
<em><span style="color: #0000ff"> sp = InStr(sp + 1, route, " ")</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> If (sp = 0) Then</span></em>
<em><span style="color: #0000ff"> IpParseRoute = route</span></em>
<em><span style="color: #0000ff"> nexthop = ""</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpParseRoute = Left(route, sp - 1)</span></em>
<em><span style="color: #0000ff"> nexthop = Mid(route, sp + 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubnetSortJoinArray</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' this function can sort and summarize subnets or ip routes</span></em>
<em><span style="color: #0000ff">' it must be used in an array formula</span></em>
<em><span style="color: #0000ff">' 'ip_array' is a single column array containing ip subnets in "prefix/len"</span></em>
<em><span style="color: #0000ff">' or "prefix mask" notation</span></em>
<em><span style="color: #0000ff">' the return value is also an array of the same size containing the same</span></em>
<em><span style="color: #0000ff">' subnets sorted in ascending order</span></em>
<em><span style="color: #0000ff">' any consecutive subnets of the same size will be summarized when it is</span></em>
<em><span style="color: #0000ff">' possible</span></em>
<em><span style="color: #0000ff">' each line may contain any character sequence after the subnet, such as</span></em>
<em><span style="color: #0000ff">' a next hop or any parameter of an ip route</span></em>
<em><span style="color: #0000ff">' in this case, only subnets with the same parameters will be summarized</span></em>
<em><span style="color: #0000ff">Function IpSubnetSortJoinArray(ip_array As Range) As Variant</span></em>
<em><span style="color: #0000ff"> Dim s As Integer</span></em>
<em><span style="color: #0000ff"> Dim t As Integer</span></em>
<em><span style="color: #0000ff"> Dim a As String</span></em>
<em><span style="color: #0000ff"> Dim b As String</span></em>
<em><span style="color: #0000ff"> Dim nexthop1 As String</span></em>
<em><span style="color: #0000ff"> Dim nexthop2 As String</span></em>
<em><span style="color: #0000ff"> t = 0</span></em>
<em><span style="color: #0000ff"> s = ip_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> Dim list() As String</span></em>
<em><span style="color: #0000ff"> ReDim list(1 To s)</span></em>
<em><span style="color: #0000ff"> ' copy subnet list</span></em>
<em><span style="color: #0000ff"> For i = 1 To s</span></em>
<em><span style="color: #0000ff"> If (ip_array.Cells(i, 1) &lt;&gt; 0) Then</span></em>
<em><span style="color: #0000ff"> t = t + 1</span></em>
<em><span style="color: #0000ff"> ' just use the networks as provide:</span></em>
<em><span style="color: #0000ff"> 'list(t) = ip_array.Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> ' or clean up the host part in each subnet:</span></em>
<em><span style="color: #0000ff"> a = IpParseRoute(ip_array.Cells(i, 1), nexthop1)</span></em>
<em><span style="color: #0000ff"> list(t) = IpClearHostBits(a) + " " + nexthop1</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' sort the list with bubble sort</span></em>
<em><span style="color: #0000ff"> For i = t - 1 To 1 Step -1</span></em>
<em><span style="color: #0000ff"> For j = 1 To i</span></em>
<em><span style="color: #0000ff"> Dim m, n As Double</span></em>
<em><span style="color: #0000ff"> a = IpParseRoute(list(j), nexthop1)</span></em>
<em><span style="color: #0000ff"> b = IpParseRoute(list(j + 1), nexthop2)</span></em>
<em><span style="color: #0000ff"> m = IpStrToBin(IpWithoutMask(a))</span></em>
<em><span style="color: #0000ff"> n = IpStrToBin(IpWithoutMask(b))</span></em>
<em><span style="color: #0000ff"> If ((m &gt; n) Or ((m = n) And (IpMaskBin(a) &lt; IpMaskBin(b)))) Then</span></em>
<em><span style="color: #0000ff"> Dim swap As String</span></em>
<em><span style="color: #0000ff"> swap = list(j)</span></em>
<em><span style="color: #0000ff"> list(j) = list(j + 1)</span></em>
<em><span style="color: #0000ff"> list(j + 1) = swap</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next j</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> ' try to join subnets</span></em>
<em><span style="color: #0000ff"> i = 1</span></em>
<em><span style="color: #0000ff"> While (i &lt; t)</span></em>
<em><span style="color: #0000ff"> remove_next = False</span></em>
<em><span style="color: #0000ff"> a = IpParseRoute(list(i), nexthop1)</span></em>
<em><span style="color: #0000ff"> b = IpParseRoute(list(i + 1), nexthop2)</span></em>
<em><span style="color: #0000ff"> If (IpSubnetIsInSubnet(a, b) And (nexthop1 = nexthop2)) Then</span></em>
<em><span style="color: #0000ff"> list(i) = list(i + 1)</span></em>
<em><span style="color: #0000ff"> remove_next = True</span></em>
<em><span style="color: #0000ff"> ElseIf (IpSubnetIsInSubnet(b, a) And (nexthop1 = nexthop2)) Then</span></em>
<em><span style="color: #0000ff"> remove_next = True</span></em>
<em><span style="color: #0000ff"> ElseIf ((IpSubnetLen(a) = IpSubnetLen(b)) And (nexthop1 = nexthop2)) Then</span></em>
<em><span style="color: #0000ff"> ' create a subnet with the same notation</span></em>
<em><span style="color: #0000ff"> bigsubnet = Replace(IpWithoutMask(a) + "/" + Str(IpSubnetLen(a) - 1), " ", "")</span></em>
<em><span style="color: #0000ff"> If (InStr(a, "/") = 0) Then</span></em>
<em><span style="color: #0000ff"> bigsubnet = IpWithoutMask(a) &amp; " " &amp; IpMask(bigsubnet)</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> If (IpSubnetIsInSubnet(b, bigsubnet)) Then</span></em>
<em><span style="color: #0000ff"> ' OK these subnets can be joined</span></em>
<em><span style="color: #0000ff"> list(i) = bigsubnet &amp; " " &amp; nexthop1</span></em>
<em><span style="color: #0000ff"> remove_next = True</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> End If</span></em>
 
<em><span style="color: #0000ff"> If (remove_next) Then</span></em>
<em><span style="color: #0000ff"> ' remove list(i+1) and make the list one element shorter</span></em>
<em><span style="color: #0000ff"> For j = i + 1 To t - 1</span></em>
<em><span style="color: #0000ff"> list(j) = list(j + 1)</span></em>
<em><span style="color: #0000ff"> Next j</span></em>
<em><span style="color: #0000ff"> t = t - 1</span></em>
<em><span style="color: #0000ff"> ' step back and try again because list(i) may be joined with list(i-1)</span></em>
<em><span style="color: #0000ff"> If (i &gt; 1) Then i = i - 1</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> i = i + 1</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff"> ' copy the sorted list as strings</span></em>
<em><span style="color: #0000ff"> Dim resultArray() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim resultArray(1 To s, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To t</span></em>
<em><span style="color: #0000ff"> resultArray(i, 1) = list(i)</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpSubnetSortJoinArray = resultArray</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpDivideSubnet</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' divide a network in smaller subnets</span></em>
<em><span style="color: #0000ff">' "n" is the value that will be added to the subnet length</span></em>
<em><span style="color: #0000ff">' "SubnetSeqNbr" is the index of the smaller subnet to return</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpDivideSubnet("1.2.3.0/24"; 2; 0) returns "1.2.3.0/26"</span></em>
<em><span style="color: #0000ff">' IpDivideSubnet("1.2.3.0/24"; 2; 1) returns "1.2.3.64/26"</span></em>
<em><span style="color: #0000ff">Function IpDivideSubnet(ByVal subnet As String, n As Integer, index As Integer)</span></em>
<em><span style="color: #0000ff"> Dim ip As String</span></em>
<em><span style="color: #0000ff"> Dim slen As Integer</span></em>
<em><span style="color: #0000ff"> ip = IpAnd(IpWithoutMask(subnet), IpMask(subnet))</span></em>
<em><span style="color: #0000ff"> slen = IpSubnetLen(subnet) + n</span></em>
<em><span style="color: #0000ff"> If (slen &gt; 32) Then</span></em>
<em><span style="color: #0000ff"> IpDivideSubnet = "ERR subnet lenght &gt; 32"</span></em>
<em><span style="color: #0000ff"> Exit Function</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> If (index &gt;= 2 ^ n) Then</span></em>
<em><span style="color: #0000ff"> IpDivideSubnet = "ERR index out of range"</span></em>
<em><span style="color: #0000ff"> Exit Function</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> ip = IpBinToStr(IpStrToBin(ip) + (2 ^ (32 - slen)) * index)</span></em>
<em><span style="color: #0000ff"> IpDivideSubnet = Replace(ip + "/" + Str(slen), " ", "")</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpIsPrivate</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns TRUE if "ip" is in one of the private IP address ranges</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpIsPrivate("192.168.1.35") returns TRUE</span></em>
<em><span style="color: #0000ff">' IpIsPrivate("209.85.148.104") returns FALSE</span></em>
<em><span style="color: #0000ff">Function IpIsPrivate(ByVal ip As String) As Boolean</span></em>
<em><span style="color: #0000ff"> IpIsPrivate = (IpIsInSubnet(ip, "10.0.0.0/8") Or IpIsInSubnet(ip, "172.16.0.0/12") Or IpIsInSubnet(ip, "192.168.0.0/16"))</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpRangeToCIDR</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns a network or a list of networks given the first and the</span></em>
<em><span style="color: #0000ff">' last address of an IP range</span></em>
<em><span style="color: #0000ff">' if this function is used in a array formula, it may return more</span></em>
<em><span style="color: #0000ff">' than one network</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpRangeToCIDR("10.0.0.1","10.0.0.254") returns 10.0.0.0/24</span></em>
<em><span style="color: #0000ff">' IpRangeToCIDR("10.0.0.1","10.0.1.63") returns the array : 10.0.0.0/24 10.0.1.0/26</span></em>
<em><span style="color: #0000ff">' note:</span></em>
<em><span style="color: #0000ff">' 10.0.0.0 or 10.0.0.1 as the first address returns the same result</span></em>
<em><span style="color: #0000ff">' 10.0.0.254 or 10.0.0.255 (broadcast) as the last address returns the same result</span></em>
<em><span style="color: #0000ff">Function IpRangeToCIDR(ByVal firstAddr As String, ByVal lastAddr As String) As Variant</span></em>
<em><span style="color: #0000ff"> firstAddr = IpAnd(firstAddr, "255.255.255.254") ' set the last bit to zero</span></em>
<em><span style="color: #0000ff"> lastAddr = IpOr(lastAddr, "0.0.0.1") ' set the last bit to one</span></em>
<em><span style="color: #0000ff"> Dim list() As String</span></em>
<em><span style="color: #0000ff"> n = 0</span></em>
<em><span style="color: #0000ff"> Do</span></em>
<em><span style="color: #0000ff"> l = 0</span></em>
<em><span style="color: #0000ff"> Do ' find the largest network which first address is firstAddr and which last address is not higher than lastAddr</span></em>
<em><span style="color: #0000ff"> ' build a network of length l</span></em>
<em><span style="color: #0000ff"> ' if it does not comply the above conditions, try with a smaller network</span></em>
<em><span style="color: #0000ff"> l = l + 1</span></em>
<em><span style="color: #0000ff"> net = firstAddr &amp; "/" &amp; l</span></em>
<em><span style="color: #0000ff"> ip1 = IpAnd(firstAddr, IpMask(net)) ' first @ of this network</span></em>
<em><span style="color: #0000ff"> ip2 = IpOr(firstAddr, IpWildMask(net)) ' last @ of this network</span></em>
<em><span style="color: #0000ff"> net = ip1 &amp; "/" &amp; l ' rebuild the network with the first address</span></em>
<em><span style="color: #0000ff"> diff = IpDiff(ip2, lastAddr) ' difference between the last @ of this network and the lastAddr we need to reach</span></em>
<em><span style="color: #0000ff"> Loop While (l &lt; 32) And ((ip1 &lt;&gt; firstAddr) Or (diff &gt; 0))</span></em>
 
<em><span style="color: #0000ff"> n = n + 1</span></em>
<em><span style="color: #0000ff"> ReDim Preserve list(1 To n)</span></em>
<em><span style="color: #0000ff"> list(n) = net</span></em>
<em><span style="color: #0000ff"> firstAddr = IpAdd(ip2, 1)</span></em>
<em><span style="color: #0000ff"> Loop While (diff &lt; 0) ' if we haven't reached the lastAddr, loop to build another network</span></em>
 
<em><span style="color: #0000ff"> Dim resultArray() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim resultArray(1 To n + 1, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To n</span></em>
<em><span style="color: #0000ff"> resultArray(i, 1) = list(i)</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpRangeToCIDR = resultArray</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpSubtractSubnets</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Remove subnets from a list of subnets</span></em>
<em><span style="color: #0000ff">' this function must be used in an array formula</span></em>
<em><span style="color: #0000ff">' 'input_array' is a list of assigned subnets</span></em>
<em><span style="color: #0000ff">' 'subtract_array' is a list of used subnets</span></em>
<em><span style="color: #0000ff">' the result is a list of unused subnets</span></em>
<em><span style="color: #0000ff">Function IpSubtractSubnets(input_array As Range, subtract_array As Range) As Variant</span></em>
<em><span style="color: #0000ff"> Dim i As Integer</span></em>
<em><span style="color: #0000ff"> Dim j As Integer</span></em>
<em><span style="color: #0000ff"> Dim k As Integer</span></em>
<em><span style="color: #0000ff"> Dim s As Integer</span></em>
<em><span style="color: #0000ff"> s = 0</span></em>
<em><span style="color: #0000ff"> Dim list() As String</span></em>
<em><span style="color: #0000ff"> ReDim list(1 To input_array.Rows.Count)</span></em>
<em><span style="color: #0000ff"> ' copy subnet list</span></em>
<em><span style="color: #0000ff"> For i = 1 To input_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> If (input_array.Cells(i, 1) &lt;&gt; 0) Then</span></em>
<em><span style="color: #0000ff"> s = s + 1</span></em>
<em><span style="color: #0000ff"> list(s) = input_array.Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>

<em><span style="color: #0000ff">For i = 1 To subtract_array.Rows.Count</span></em>
<em><span style="color: #0000ff"> ' try to remove each network in subtract_array from the list in input_array</span></em>
<em><span style="color: #0000ff"> subtractNet = subtract_array.Cells(i, 1)</span></em>
<em><span style="color: #0000ff"> If subtractNet &lt;&gt; 0 Then</span></em>
<em><span style="color: #0000ff"> ' try to remove each network in subtract_array from each network in input_array</span></em>
<em><span style="color: #0000ff"> j = 1</span></em>
<em><span style="color: #0000ff"> Do</span></em>
<em><span style="color: #0000ff"> net = list(j)</span></em>
<em><span style="color: #0000ff"> ' is the network to remove equal or larger ?</span></em>
<em><span style="color: #0000ff"> If IpSubnetIsInSubnet(net, subtractNet) Then ' remove the network from input_array</span></em>
<em><span style="color: #0000ff"> For k = j To s - 1</span></em>
<em><span style="color: #0000ff"> list(k) = list(k + 1)</span></em>
<em><span style="color: #0000ff"> Next k</span></em>
<em><span style="color: #0000ff"> s = s - 1</span></em>
<em><span style="color: #0000ff"> ' is the network to remove smaller ?</span></em>
<em><span style="color: #0000ff"> ElseIf IpSubnetIsInSubnet(subtractNet, net) Then ' split this network in input_array</span></em>
<em><span style="color: #0000ff"> ' insert a line in the result array</span></em>
<em><span style="color: #0000ff"> s = s + 1</span></em>
<em><span style="color: #0000ff"> ReDim Preserve list(1 To s)</span></em>
<em><span style="color: #0000ff"> For k = s To j + 2 Step -1</span></em>
<em><span style="color: #0000ff"> list(k) = list(k - 1)</span></em>
<em><span style="color: #0000ff"> Next k</span></em>
<em><span style="color: #0000ff"> ' create 2 smaller subnets</span></em>
<em><span style="color: #0000ff"> list(j + 1) = IpDivideSubnet(list(j), 1, 1)</span></em>
<em><span style="color: #0000ff"> list(j) = IpDivideSubnet(list(j), 1, 0)</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> ' nothing to do, skip to next network in input_array</span></em>
<em><span style="color: #0000ff"> j = j + 1</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Loop While j &lt;= s</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff"> Next i</span></em>

<em><span style="color: #0000ff">Dim resultArray() As Variant</span></em>
<em><span style="color: #0000ff"> ReDim resultArray(1 To s + 1, 1 To 1)</span></em>
<em><span style="color: #0000ff"> For i = 1 To s</span></em>
<em><span style="color: #0000ff"> resultArray(i, 1) = list(i)</span></em>
<em><span style="color: #0000ff"> Next i</span></em>
<em><span style="color: #0000ff"> IpSubtractSubnets = resultArray</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpDiff</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' difference between 2 IP addresses</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpDiff("192.168.1.7"; "192.168.1.1") returns 6</span></em>
<em><span style="color: #0000ff">Function IpDiff(ByVal ip1 As String, ByVal ip2 As String) As Double</span></em>
<em><span style="color: #0000ff"> Dim mult As Double</span></em>
<em><span style="color: #0000ff"> mult = 1</span></em>
<em><span style="color: #0000ff"> IpDiff = 0</span></em>
<em><span style="color: #0000ff"> While ((ip1 &lt;&gt; "") Or (ip2 &lt;&gt; ""))</span></em>
<em><span style="color: #0000ff"> IpDiff = IpDiff + mult * (IpParse(ip1) - IpParse(ip2))</span></em>
<em><span style="color: #0000ff"> mult = mult * 256</span></em>
<em><span style="color: #0000ff"> Wend</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpParse</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Parses an IP address by iteration from right to left</span></em>
<em><span style="color: #0000ff">' Removes one byte from the right of "ip" and returns it as an integer</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' if ip="192.168.1.32"</span></em>
<em><span style="color: #0000ff">' IpParse(ip) returns 32 and ip="192.168.1" when the function returns</span></em>
<em><span style="color: #0000ff">Function IpParse(ByRef ip As String) As Integer</span></em>
<em><span style="color: #0000ff"> Dim pos As Integer</span></em>
<em><span style="color: #0000ff"> pos = InStrRev(ip, ".")</span></em>
<em><span style="color: #0000ff"> If pos = 0 Then</span></em>
<em><span style="color: #0000ff"> IpParse = Val(ip)</span></em>
<em><span style="color: #0000ff"> ip = ""</span></em>
<em><span style="color: #0000ff"> Else</span></em>
<em><span style="color: #0000ff"> IpParse = Val(Mid(ip, pos + 1))</span></em>
<em><span style="color: #0000ff"> ip = Left(ip, pos - 1)</span></em>
<em><span style="color: #0000ff"> End If</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpBuild</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' Builds an IP address by iteration from right to left</span></em>
<em><span style="color: #0000ff">' Adds "ip_byte" to the left the "ip"</span></em>
<em><span style="color: #0000ff">' If "ip_byte" is greater than 255, only the lower 8 bits are added to "ip"</span></em>
<em><span style="color: #0000ff">' and the remaining bits are returned to be used on the next IpBuild call</span></em>
<em><span style="color: #0000ff">' example 1:</span></em>
<em><span style="color: #0000ff">' if ip="168.1.1"</span></em>
<em><span style="color: #0000ff">' IpBuild(192, ip) returns 0 and ip="192.168.1.1"</span></em>
<em><span style="color: #0000ff">' example 2:</span></em>
<em><span style="color: #0000ff">' if ip="1"</span></em>
<em><span style="color: #0000ff">' IpBuild(258, ip) returns 1 and ip="2.1"</span></em>
<em><span style="color: #0000ff">Function IpBuild(ip_byte As Double, ByRef ip As String) As Double</span></em>
<em><span style="color: #0000ff"> If ip &lt;&gt; "" Then ip = "." + ip</span></em>
<em><span style="color: #0000ff"> ip = Format(ip_byte And 255) + ip</span></em>
<em><span style="color: #0000ff"> IpBuild = ip_byte \ 256</span></em>
<em><span style="color: #0000ff">End Function</span></em>

<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' IpMaskBin</span></em>
<em><span style="color: #0000ff">'----------------------------------------------</span></em>
<em><span style="color: #0000ff">' returns binary IP mask from an address with / notation (xx.xx.xx.xx/yy)</span></em>
<em><span style="color: #0000ff">' example:</span></em>
<em><span style="color: #0000ff">' IpMask("192.168.1.1/24") returns 4294967040 which is the binary</span></em>
<em><span style="color: #0000ff">' representation of "255.255.255.0"</span></em>
<em><span style="color: #0000ff">Function IpMaskBin(ByVal ip As String) As Double</span></em>
<em><span style="color: #0000ff"> Dim bits As Integer</span></em>
<em><span style="color: #0000ff"> bits = IpSubnetLen(ip)</span></em>
<em><span style="color: #0000ff"> IpMaskBin = (2 ^ bits - 1) * 2 ^ (32 - bits)</span></em>
<em><span style="color: #0000ff">End Function</span></em>

Save the Macro and close the editor and then save the Excel sheet as Macro Enabled format.</pre>
now we have the functions that can reverse lookup an IP to a Subnet , but we need to import the data to the Excel sheet and then do more steps..

Now we will download the building data and open an empty sheet in the same Excel file that we have created and then Rename the Sheet to <strong>Subnets</strong>

Then on the first Column A write the following Formula in the first cell:

<span style="color: #0000ff">=IF(ISBLANK('C:\tmp\[BuildingDATAFILE.csv]<span>BuildingDATAFILE</span>'!$A2),"",CONCATENATE('C:\tmp\[BuildingDATAFILE.csv]<span>BuildingDATAFILE</span>'!$A:$A,"/",'C:\tmp\[BuildingDATAFILE.csv]<span>BuildingDATAFILE</span>'!$C:$C))</span>

Replace <span>BuildingDATAFILE with your Building data file name and path.</span>

Fill down the rest of the column with this formula:
<ul>
 	<li>Select and copy the cell containing the formula and press CTRL+SHIFT+DOWN to select the rest of the column</li>
 	<li>Fill down by pressing CTRL+D</li>
 	<li>Use CTRL+UP to return up</li>
</ul>
&nbsp;

Now you will get the Subnet and Mask in Column A; we have to sort them

In the same sheet select Column B

type the formula, =iPSubnetsortArray(A1:A5)
<strong>press Ctrl+Shift+Enter instead of Enter </strong>

Now we have them in sorted order in Column B; then on Column C we will add a new Formula to do vlookup for the Subnet name from the data building file.

in Column C type the following Formula:

<span style="color: #0000ff">=VLOOKUP(B1,'C:\tmp\[BuildingDATAFILE.csv]BuildingDATAFILE'!$A$1:$B$5,2,FALSE)</span>

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/12.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/12.jpg" alt="" width="559" height="271" class="alignnone wp-image-516" /></a>

now we got the subnet sorted and with their corresponding names.

lets go back to the first sheet and add a coulmn called <strong>From Subnet </strong>and<strong> To Subnet </strong>corresponding to the to and from IP address

then add the formula respectively to reverse lookup the IPs

<span style="color: #0000ff">=IpSubnetVLookup([@FromIPAddr],Subnets!$A$1:$B$5,3)</span>

<span style="color: #0000ff">=IpSubnetVLookup([@ToIPAddr],Subnets!$A$1:$B$5,3)</span>

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/13.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/13.jpg" alt="" width="439" height="954" class="alignnone wp-image-525" /></a>

Finally as we got all the information we need we will open Power BI Desktop to import this information

Open a new Query

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/14.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/14.jpg" alt="" width="2073" height="1261" class="alignnone size-full wp-image-535" /></a>

then Click Advanced Editor and enter the following query
<pre><span style="color: #0000ff">let
 Source = Excel.Workbook(File.Contents("C:\tmp\Book1.xlsm"), null, true),
 Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
 #"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
 #"Removed Duplicates" = Table.Distinct(#"Promoted Headers", {"DialogId"}),
 #"Removed Blank Rows" = Table.SelectRows(#"Removed Duplicates", each not List.IsEmpty(List.RemoveMatchingItems(Record.FieldValues(_), {"", null})))
in
 #"Removed Blank Rows"
</span></pre>
Click Close and Apply

Then all of the Excel information will be imported into Power BI we will start some interesting reports:

first we will need the From Subnet in percentage as well as the To Subnet

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/16.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/16.jpg" alt="" width="3000" height="2000" class="alignnone size-full wp-image-537" /></a>

Then we will add the Ratings and the Count of Ratings only

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/17.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/17.jpg" alt="" width="2885" height="1784" class="alignnone size-full wp-image-545" /></a>

as you can see if you clicked on these ratings it will show you the percentage of the fro and to subnet names that the users are reporting Very bad, fair, good or excellent from.

you can add as well the users by rating count which will show you the users who most rated poor , very bad, so you can address their issues.

&nbsp;

Now moving to the next part where we Analyse the user sentiment, Thanks to DataCHant blog for helping me out in this task \

(http://community.powerbi.com/t5/Community-Blog/Text-Analytics-in-Power-BI-Extraction-of-key-phrases-from/ba-p/88487)

i am copying most of his post blog here as i had to do the exact steps with minor changes

<strong>Before we start Sentiment Analytics </strong>
<h2 id="prerequisites">Prerequisites</h2>
<p class="lf-text-block lf-block">To do this tutorial, you need:<span class="lf-thread-btn"></span></p>

<div class="checklist">
<ul class="lf-text-block lf-block">
 	<li>Microsoft Power BI Desktop.<span> </span><a href="https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/tutorials/(https://powerbi.microsoft.com/)">Download at no charge</a>.</li>
 	<li>A Microsoft Azure account.<span> </span><a href="https://azure.microsoft.com/free/">Start a free trial</a><span> </span>or<span> </span><a href="https://portal.azure.com/">sign in</a>.</li>
 	<li>A access key for Text Analytics.<span> </span><a href="https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account">Sign up</a>, then<span> </span><a href="https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/how-tos/text-analytics-how-to-access-key">get your key</a>.</li>
 	<li>Customer comments.<span> </span><a href="https://aka.ms/cogsvc/ta">Get our example data</a><span> </span>or use your own.</li>
</ul>
</div>
&nbsp;

<strong>Preparing the API queries - A parameter and a query function</strong>

&nbsp;

In this section we'll prepare the advanced Power Query code that we'll need for the Key Phrase API.

&nbsp;

In the<span> </span><strong>Query Editor</strong>'s <strong>Home </strong>tab, click <strong>Manager Parameters</strong>, then select <strong>New Parameter.</strong>

&nbsp;

In the <strong>Parameters</strong> dialog, set <strong><em>APIKey</em></strong><em> </em>as <strong>Name</strong> and paste the API Key that you obtained from Microsoft Cognitive Services into the text box <strong>Current Value</strong>.

When you are done, click <strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19181iD7EC21E776CE8C58/image-size/large?v=1.0&amp;px=600" alt="Screenshot_28.png" title="Screenshot_28.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

In the Query Editor's <strong>Home</strong> tab, click the drop down menu below the icon of <strong>New Source </strong>and select <strong>Blank Query</strong>. Still in Home tab, click <strong>Advanced Query </strong>and paste the following code:

&nbsp;
<pre><span style="color: #0000ff">(Source) =&gt;
let
    JsonRecords = Text.FromBinary(Json.FromValue(Source)),
    JsonRequest = "{""documents"": " &amp; JsonRecords &amp; "}",
 
    JsonContent = Text.ToBinary(JsonRequest, TextEncoding.Ascii),
    Response =
        Web.Contents("https://westus.api.cognitive.microsoft.com/text/analytics/v2.0/keyPhrases?",
            [
                Headers = [#"Ocp-Apim-Subscription-Key"= APIKey,
                           #"Content-Type"="application/json", Accept="application/json"],
                Content=JsonContent
            ]),
    JsonResponse = Json.Document(Response,1252)
in
    JsonResponse</span></pre>
&nbsp;

&nbsp;

Click <strong>Done</strong> in the Advanced Editor, and rename the new query to <strong><em>GetKeyPhrases</em></strong>.

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19182iC0361A4A28A33B4A/image-size/large?v=1.0&amp;px=600" alt="Screenshot_31.png" title="Screenshot_31.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

&nbsp;

<strong>Note</strong>: Now in Queries pane, you will notice that the new query <strong><em>GetKeyPhrases</em></strong> has an <strong>fx</strong> icon. The query above is not a normal query. It is a query function that receives a table as an input, converts it into a JSON format, sends it to Microsoft Cognitive Services and returns the JSON response.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19183i7ACECF5C75CB2EAE/image-size/large?v=1.0&amp;px=600" alt="Screenshot_32.png" title="Screenshot_32.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Right click on <b><i>the Sheet1 </i></b>in the left<span> </span><strong>Queries</strong><span> </span>pane, and click <strong>Reference</strong>.

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/18.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/18.jpg" alt="" width="370" height="425" class="alignnone wp-image-546" /></a>

Rename the query<span> </span><em><strong>Sheet1(2)</strong></em><span> </span>to<span> </span><em><strong>Sentiment Results</strong></em>. To rename the query, right click on it and click<span> </span><strong>Rename</strong>.

&nbsp;

<strong>Note</strong>: In the next step we will select the columns in our data that contain the actual text for analysis and a unique ID for each text. The unique ID is required by Microsoft Cognitive Services API. The unique ID will help us to map the Sentiment scores in the response to the relevant text. In our data, we use the diagIDs as unique IDs.

In <strong>Home</strong> tab of <strong>Query Editor</strong>, click <strong>Choose Columns</strong>, unselect all columns, then select <em><strong>DiagID</strong></em>and <b><i>FeedbackText </i></b>and click <strong>OK</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/19.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/19.jpg" alt="" width="3000" height="1567" class="alignnone size-full wp-image-555" /></a>

&nbsp;

Now, let's rename the columns. <em><strong>DiagID</strong></em> should be renamed to <em><strong>id</strong></em> <i>and</i><b><i> FeedbackText </i></b>should be renamed to <em><strong>text</strong></em>. This step is critical. Don't miss it. The Sentiment Analysis API requires these names.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-inline"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/9269iC44294A4348E131F/image-size/large?v=1.0&amp;px=600" alt="Screenshot_17.png" title="Screenshot_17.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Note: If you need to perform analysis on text in French, Spanish or Portuguese, you can create another step here and define a custom column whose name is<span> </span><em><strong>language</strong><span> </span></em>and is value is "<em><strong>fr</strong></em>", "<strong><em>es</em></strong>" or "<em><strong>pt</strong></em>" (For French, Spanish or Portuguese). Since English is the default language in the API, we skip this step.

&nbsp;

In the next step, we will remove rows with empty text messages. There is no point in sending such rows for Sentiment Analysis, and the service will return errors if we try to.

&nbsp;

Click in the filter icon of the column<span> </span><em><strong>text</strong></em>, and then click<span> </span><strong>Remove Empty</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-inline"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/9298i83F762E65C9D1C29/image-size/large?v=1.0&amp;px=600" alt="Screenshot_22.png" title="Screenshot_22.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Rename the column <strong><em>message</em></strong> to <strong><em>text</em></strong>. This is crucial. Later on we convert the table into a JSON format with the name <strong><em>text</em></strong>.

&nbsp;

In <strong>Add Column</strong> tab, click <strong>Custom Column</strong>.

Set <strong><em>language</em></strong> as <strong>New column name</strong>, and <strong><em>= "en"</em></strong> as <strong>Custom column formula</strong>. Then click <strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19195i8964976292DB3203/image-size/large?v=1.0&amp;px=600" alt="Screenshot_44.png" title="Screenshot_44.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

<strong>Note</strong>: The Text Analytics Key Phrases API support the following languages: English (en), German (de), Spanish (es) and Japanese (ja). You can use any of these codes if your text is in those languages.

&nbsp;

&nbsp;

<strong>Group data to sub-tables of 1000 messages each</strong>

&nbsp;

Microsoft Cognitive Services allow us to send 1000 different messages on each API call as part of the Key Phrases API. In this part, we'll group the table into sub-tables of 1000 rows.

&nbsp;

In <strong>Add Column</strong> click <strong>Index Column</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19188iA52C5A9B65E445F8/image-size/large?v=1.0&amp;px=600" alt="Screenshot_37.png" title="Screenshot_37.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Select the new column, <strong><em>Index</em></strong>, and in Transform tab, click <strong>Standard</strong>, then select <strong>Integer-Divide</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19190i531ECD0DFB7DAB54/image-size/large?v=1.0&amp;px=600" alt="Screenshot_38.png" title="Screenshot_38.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

In<span> </span><strong>Integer-Divide</strong><span> </span>dialog, set <strong><em>1000</em></strong><em> </em>as <strong>Value</strong> and click <strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19189iAEA58D48C3E46B71/image-size/large?v=1.0&amp;px=600" alt="Screenshot_39.png" title="Screenshot_39.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Now the values in column <strong><em>Index</em></strong><em> </em>are all 0 in the first 1000 rows, all 1 in the next 1000 rows, and so forth.

Select the column <strong><em>Index</em></strong>, and click <strong>Group By </strong>in <strong>Transform</strong> tab<strong>.</strong>

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19192i9034246ECB8C2246/image-size/large?v=1.0&amp;px=600" alt="Screenshot_40.png" title="Screenshot_40.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

In the <strong>Group By</strong> dialog, ensure that <strong><em>Index</em></strong><em> </em>is selected in the drop down menu <strong>Group By</strong>.

Set <strong><em>sub-table</em></strong> as the text in <strong>New column name</strong>.

Select <strong>All Rows</strong> as <strong>Operation</strong>, and click<strong> OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19191i130388D3DF376AB4/image-size/large?v=1.0&amp;px=600" alt="Screenshot_41.png" title="Screenshot_41.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

<strong> </strong>

After the grouping step, we have a new column <strong>sub-table </strong>that contains our tables in bulks of 1000 rows each (excluding the last row that has the remainders).

&nbsp;

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19220iDFEEA00652243638/image-size/medium?v=1.0&amp;px=400" alt="Screenshot_66.png" title="Screenshot_66.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

&nbsp;

We can delete the column <strong><em>Index</em></strong>, and click <strong>Invoke Custom Function</strong> in <strong>Add Column</strong> tab.

&nbsp;

In<strong> Invoke Custom Function </strong>dialog, set<span> </span><em><strong>GetKeyPhrases</strong><span> </span></em>as<span> </span><strong>Function Query</strong><span> </span>and select<span> </span><em><strong>sub-table</strong></em>as the column. When you are done, click<span> </span><strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19222i18A5FDBB1300BDE8/image-size/large?v=1.0&amp;px=600" alt="Screenshot_67.png" title="Screenshot_67.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Delete the column<span> </span><em><strong>sub-table</strong></em>, and click the expand button in the left side of the header<span> </span><em><strong>GetKeyPhrases</strong></em>.

Ensure all columns are selected in the expand pane, uncheck<span> </span><strong>Use original column name as prefix</strong>, and click<span> </span><strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19227i726883E62FE5B88E/image-size/large?v=1.0&amp;px=600" alt="Screenshot_69.png" title="Screenshot_69.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Delete the column<span> </span><em><strong>errors</strong>.</em>

&nbsp;

Click on the expand button in the header of column<span> </span><em><strong>documents</strong></em>, select all columns and click<span> </span><strong>OK</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19200iD8D72929E51503DA/image-size/large?v=1.0&amp;px=600" alt="Screenshot_49.png" title="Screenshot_49.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

<span>Click on the expand button in the header of column </span><em><strong>KeyPhrases</strong>.</em>

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19201i4597D7151EC04952/image-size/large?v=1.0&amp;px=600" alt="Screenshot_50.png" title="Screenshot_50.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Finally, we have a new column with a key phrase for each message id. You should note that we will usually have multiple key phrases per message, so our table is now expended to multiple rows per message id.

&nbsp;

For a final cosmetic touch, let's capitalize each word in column<span> </span><em><strong>KeyPhrases</strong></em>:

Select the column<span> </span><em><strong>KeyPhrases</strong></em>, right click on its header, select<span> </span><strong>Transform</strong><span> </span>and then select<span> </span><strong>Capitalize Each Word</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19228i9EDE1FCA2A5435D9/image-size/large?v=1.0&amp;px=600" alt="Screenshot_70.png" title="Screenshot_70.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

We have completed the extraction of key messages. It's time to move to the modeling and visualization.

In the<span> </span><strong>Query Editor</strong><span> </span>window, click<span> </span><em><strong>Close &amp; Apply</strong></em>.

&nbsp;

<strong>Feeding Key Phrases to a WordCloud Custom Visual</strong>

&nbsp;

We are almost done. It's time to move to the visualization part. We'll now learn how to create a simple WordCloud visual with our key phrases.

&nbsp;

After completing the last two parts, we now have two tables <b><i>FeedbackText </i></b>and <em><strong>KeyPhrases</strong></em>. We can create a relationship between column <em><strong>id<span> </span></strong></em>in both tables (if Power BI Desktop didn't detect them automatically). To do it, go to Relationships view, and drag and drop the column <strong>Diag</strong><em><strong>id</strong><span> </span></em>from  <b><i>FeedbackText </i></b>to <em><strong>KeyPhrases</strong><span> </span></em>as shown here.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19232iE7869E1B95BE540A/image-size/large?v=1.0&amp;px=600" alt="Screenshot_71.png" title="Screenshot_71.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

&nbsp;

Download<span> </span><strong>WordCloud</strong><span> </span>(from<span> </span><a target="_blank" href="https://app.powerbi.com/visuals/show/WordCloud1447959067750" rel="noopener" title="">here</a>), and import it to your report .

&nbsp;

Click the <strong>Report</strong><span> </span>view, and add a WordCloud to your report. Drag and drop the column<span> </span><em><strong>KeyPhrases</strong><span> </span></em>to<span> </span><strong>Category</strong><span> </span>and count of <span> <em><strong>KeyPhrases</strong> </em></span>to<span> </span><strong>Value<span> .</span></strong>

&nbsp;

In<span> </span><strong>Format</strong><span> </span>tab in<span> </span><strong>Visualizations</strong>, turn on <strong>Stop Words</strong><span> </span>and Turn off<span> </span><strong>Rotate Text</strong>.

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/20.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/20.jpg" alt="" width="399" height="843" class="alignnone wp-image-565" /></a>

Under section<span> </span><strong>General</strong>, turn off<span> </span><strong>Word-breaking</strong>.

&nbsp;

<span class="lia-inline-image-display-wrapper lia-image-align-center"><span class="lia-message-image-wrapper"><img src="http://community.powerbi.com/t5/image/serverpage/image-id/19209iA73E46AEAF319B35/image-size/large?v=1.0&amp;px=600" alt="Screenshot_58.png" title="Screenshot_58.png" class="lia-media-image" /><span class="lia-messages-message-image"><i class="lia-fa lia-fa-search-plus lia-media-lightbox-trigger"></i></span></span></span>

You can now resize the WordCloud visual, and see the size of the key phrases is defined by the number of posts.

&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Skype for Business Online connectivity paths</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/skype-for-business-online-connectivity-paths</link>
      <pubDate>Tue, 13 Jun 2017 15:16:47 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=245</guid>
      <description><![CDATA[Recently Microsoft released a blog article to provide awareness and guidance on Simplified...]]></description>
      <content:encoded><![CDATA[<div>
<div>
<div id="page" class="site container-fluid">
<div id="site-content" class="site-content row">
<div id="primary" class="content-area col-sm-9">
<div id="single-content" class="div-content"><article id="post-245" class="post-245 post type-post status-publish format-standard hentry category-networking category-telecommunication category-uncategorized tag-connectivity tag-media tag-office-365 tag-paths tag-ports tag-skype-for-business tag-skype-for-business-online tag-skype-for-business-troubleshooting"><header class="entry-header single">Recently Microsoft released a blog article to provide awareness and guidance on <strong>Simplified port requirements for Skype for Business Online: </strong><a href="https://techcommunity.microsoft.com/t5/Skype-for-Business-Blog/Simplified-port-requirements-for-Skype-for-Business-Online/ba-p/77094">https://techcommunity.microsoft.com/t5/Skype-for-Business-Blog/Simplified-port-requirements-for-Skype-for-Business-Online/ba-p/77094</a></header>
<div class="entry-content single">

which had an updated destination ports to the cloud that makes the high ports TCP and UDP optional.

what concerns us here in this article is any traffic going through the Cloud services; so we will test only the conference media paths.

First lets look on how that is different from On-Premises and how the ICE protocol selects the ports in priorities.

in this scenarios I am going to test the Voice, Video , VBSS and RDP App Share.

I used Netmon to trace the ports and used coloring and marking from the previous blog post https://blogs.msdn.microsoft.com/mahmoud_badran/2017/05/16/netmon-capabilities-for-skype-for-business-online-troubleshooting/

&nbsp;

Here is an-on premises scenario where the caller dialled to a conference; as you can see here after a series of TURN requests the following Ports were selected ; Client Source Port UDP 50006 and Destination Port UDP 50680

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPAudio.png"><img width="1557" height="413" class="alignnone size-full wp-image-265" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPAudio.png" /></a>

What i am going to do is to add Video for the same call and below is my capture and as seen below Client Source Port is UDP 50036 and Destination Port is UDP 53400

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvedio.png"><img width="1576" height="266" class="alignnone size-full wp-image-275" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvedio.png" /></a>

again adding the VBSS (Desktop Share) the following UDP ports were selected Source port UDP 50058 and Destination port UDP 58760

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvbss.png"><img width="1569" height="253" class="alignnone size-full wp-image-285" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvbss.png" /></a>

And Finally with Application Sharing the following TCP ports were selected Source Port TCP 50048 and Destination Port 52972.

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/App.png"><img width="1568" height="190" class="alignnone size-full wp-image-295" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/App.png" /></a>

so in order to enforce the second media path we are going to block all the high ports UDP only from my machine with the Windows Firewall.

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/block-UDP.png"><img width="1565" height="180" class="alignnone size-full wp-image-296" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/block-UDP.png" /></a>

&nbsp;

Now we are going to run the same tests for Audio, Video and VBSS only since they use the UDP high ports and see what happens on Netmon.

for Audio we saw that the second path was Source port 50016 and Destination Port UDP 3478

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPAudio1.png"><img width="1566" height="174" class="alignnone size-full wp-image-305" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPAudio1.png" /></a>

similar results for Video where the destination was UDP 3478

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvedio1.png"><img width="1568" height="181" class="alignnone size-full wp-image-306" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvedio1.png" /></a>

and similar results for VBSS where the destination was UDP 3478

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvbss1.png"><img width="1576" height="188" class="alignnone size-full wp-image-315" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/UDPvbss1.png" /></a>

&nbsp;

&nbsp;

Now for the Third Path we are going to Block UDP 3478 from our Firewall and lets see what happens:

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/block-UDP1.png"><img width="1580" height="204" class="alignnone size-full wp-image-325" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/block-UDP1.png" /></a>

Re Run the same Audio, Video and VBSS Scenarios:

Now the interesting Scenario here the TCP high ports are used for Audio, as seen Source Port TCP 50018 and Destination Port TCP 50921

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/TCPAudio.png"><img width="1572" height="179" class="alignnone size-full wp-image-335" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/TCPAudio.png" /></a>

Video as well got established on the TCP high ports, with Source Port TCP 50032 and Destination Port TCP 57669

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/TCPvedio.png"><img width="1568" height="155" class="alignnone size-full wp-image-345" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/TCPvedio.png" /></a>

and Similarly the VBSS was on TCP high ports, here is Client Source port TCP 50052 and Destination port TCP 55464

<strong>it is very Important to know that this Scenario you cannot differentiate between VBSS or App Share except from the Snooper Logs</strong>

<a href="https://msdnshared.blob.core.windows.net/media/2017/06/TCPVBSS.png"><img width="1572" height="166" class="alignnone size-full wp-image-355" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/TCPVBSS.png" /></a>

and below is the Snooper logs that proves this session was a TCP VBSS and used H264

<span style="color: #808080"><em>06/13/2017|10:28:53.528 45DC:2A20 INFO :: Sending Packet - xx.xx.xx.xx:443 (From Local Address: 192.168.50.121:59364) 3166 bytes:</em></span>
<span style="color: #808080"><em>06/13/2017|10:28:53.528 45DC:2A20 INFO :: </em></span>
<span style="color: #808080"><em>INVITE sip:mbadran@contoso.com;gruu;opaque=app:conf:applicationsharing:id:TLD18BDT SIP/2.0</em></span>
<span style="color: #808080"><em>Via: SIP/2.0/TLS 192.168.50.121:59364</em></span>
<span style="color: #808080"><em>Max-Forwards: 70</em></span>
<span style="color: #808080"><em>From: &lt;sip:mbadran@contoso.com&gt;;tag=dc0670b210;epid=03413c7128</em></span>
<span style="color: #808080"><em>To: &lt;sip:mbadran@contoso.com;gruu;opaque=app:conf:applicationsharing:id:TLD18BDT&gt;;tag=673cc255;epid=361A8A700C</em></span>
<span style="color: #808080"><em>Call-ID: e733471e87ce4f849b9e46122232b0bc</em></span>
<span style="color: #808080"><em>CSeq: 2 INVITE</em></span>
<span style="color: #808080"><em> User-Agent: UCCAPI/16.0.7766.5352 OC/16.0.7766.2091 (Skype for Business)</em></span>
<span style="color: #808080"><em>Supported: ms-dialog-route-set-update</em></span>
<span style="color: #808080"><em>Supported: timer</em></span>
<span style="color: #808080"><em>Supported: histinfo</em></span>
<span style="color: #808080"><em>Supported: ms-safe-transfer</em></span>
<span style="color: #808080"><em>Supported: ms-sender</em></span>
<span style="color: #808080"><em>Supported: ms-early-media</em></span>
<span style="color: #808080"><em>ms-keep-alive: UAC;hop-hop=yes</em></span>
<span style="color: #808080"><em>ms-subnet: 192.168.50.0</em></span>
<span style="color: #808080"><em>ms-endpoint-location-data: NetworkScope;ms-media-location-type=Internet</em></span>
<span style="color: #808080"><em>Proxy-Authorization: TLS-DSK qop="auth", realm="SIP Communications Service", opaque="3E0FAC86", targetname="contoso.com", crand="9ab215e7", cnum="166", response="9e30cf5b6d03f822abb93d19c2bb10b598e1917d"</em></span>
<span style="color: #808080"><em>Content-Type: application/sdp</em></span>
<span style="color: #808080"><em>Content-Length: 1610</em></span>

<span style="color: #0000ff"><span style="font-family: Calibri">v=0</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">o=- 0 2 IN IP4 <span style="color: #000080;font-size: xx-small">xx.xx.xx.xx</span></span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">s=session</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">c=IN IP4 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span></span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">b=CT:99980</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">t=0 0</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-mediabw:applicationsharing-video send=8100;recv=4000</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">m=applicationsharing 50049 TCP/RTP/SAVP 127</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=ice-ufrag:t8XO</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=ice-pwd:/R1zFbA5Rdy5X4V4YVfem42q</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=candidate:14 1 TCP-ACT 1852570879 24.140.230.224 50049 typ prflx raddr 192.168.50.121 rport 50049</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-candidate-info:14 network-type=wlan</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:Enb/Q/W9NCW2r/4A+IJzCq90n18lQYiXot3EVgAa|2^31|1:1</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=remote-candidates:1 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span> 50336 2 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span> 50336</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=setup:active</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=connection:existing</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtpmap:127 x-data/90000</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtcp-mux</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-bwealgorithm:packetpair</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-applicationsharing-session-id:1</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-applicationsharing-role:sharer</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-applicationsharing-media-type:rdp</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-applicationsharing-contentflow:sendonly</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">m=video 50052 TCP/RTP/SAVP 122 123</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-ssrc-range:2832877825-2832877924</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtcp-fb:* x-message app send:src,x-pli recv:src,x-pli</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtcp-rsize</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=label:applicationsharing-video</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=ice-ufrag:NLIp</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=ice-pwd:oX/60lMgeMaJTxar75FhtfCk</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-mediasettings:applicationsharing-video=required</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=candidate:11 1 TCP-ACT 1852567295 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span> 50052 typ prflx raddr 192.168.50.121 rport 50052</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-candidate-info:11 network-type=wlan</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=cryptoscale:1 client AES_CM_128_HMAC_SHA1_80 inline:Enb/Q/W9NCW2r/4A+IJzCq90n18lQYiXot3EVgAa|2^31|1:1</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=remote-candidates:1 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span> 55646 2 <span style="color: #0000ff;font-family: Calibri">xx.xx.xx.xx</span> 55646</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=setup:active</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=connection:existing</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=sendonly</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtpmap:122 X-H264UC/90000</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=fmtp:122 packetization-mode=1;mst-mode=NI-TC</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtpmap:123 x-ulpfecuc/90000</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=rtcp-mux</span></span>

<span style="color: #0000ff"><span style="font-family: Calibri">a=x-bwealgorithm:packetpair</span></span>
<p align="LEFT" dir="LTR">Now we will run the same Session for RDP and see the difference in Snooper, as you see the Source port was TCP 50043 and Destination Port TCP 51039</p>
<p align="LEFT" dir="LTR"><a href="https://msdnshared.blob.core.windows.net/media/2017/06/TCPRDP.png"><img width="1570" height="206" class="alignnone size-full wp-image-365" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/TCPRDP.png" /></a></p>
<p align="LEFT" dir="LTR"><span style="color: #808080"><em>06/13/2017|10:43:01.703 45DC:2A20 INFO :: Sending Packet - xx.xx.xx.xx:443 (From Local Address: 192.168.50.121:59364) 2320 bytes:</em></span>
<span style="color: #808080"><em>06/13/2017|10:43:01.703 45DC:2A20 INFO :: </em></span>
<span style="color: #808080"><em>INVITE sip:mbadran@contoso.com;gruu;opaque=app:conf:applicationsharing:id:Y6FD73H2 SIP/2.0</em></span>
<span style="color: #808080"><em>Via: SIP/2.0/TLS 192.168.50.121:59364</em></span>
<span style="color: #808080"><em>Max-Forwards: 70</em></span>
<span style="color: #808080"><em>From: &lt;sip:mbadran@contoso.com&gt;;tag=dc77454c41;epid=03413c7128</em></span>
<span style="color: #808080"><em>To: &lt;sip:mbadran@contoso.com;gruu;opaque=app:conf:applicationsharing:id:Y6FD73H2&gt;;tag=bbeffade50;epid=D9672F7281</em></span>
<span style="color: #808080"><em>Call-ID: 4d4d16fe0a9643f3ac565ca370b095d7</em></span>
<span style="color: #808080"><em>CSeq: 2 INVITE</em></span>
<span style="color: #808080"><em>Contact: &lt;sip:mbadran@contoso.com;opaque=user:epid:5c4Y0LZ-P16OxFNemnoO7gAA;gruu&gt;</em></span>
<span style="color: #808080"><em>User-Agent: UCCAPI/16.0.7766.5352 OC/16.0.7766.2091 (Skype for Business)</em></span>
<span style="color: #808080"><em>Supported: ms-dialog-route-set-update</em></span>
<span style="color: #808080"><em>Supported: timer</em></span>
<span style="color: #808080"><em>Supported: histinfo</em></span>
<span style="color: #808080"><em>Supported: ms-safe-transfer</em></span>
<span style="color: #808080"><em>Supported: ms-sender</em></span>
<span style="color: #808080"><em>Supported: ms-early-media</em></span>
<span style="color: #808080"><em>ms-keep-alive: UAC;hop-hop=yes</em></span>
<span style="color: #808080"><em>ms-subnet: 192.168.50.0</em></span>
<span style="color: #808080"><em>ms-endpoint-location-data: NetworkScope;ms-media-location-type=Internet</em></span>
<span style="color: #808080"><em>Proxy-Authorization: TLS-DSK qop="auth", realm="SIP Communications Service", opaque="3E0FAC86", targetname="contoso.com", crand="eac0f45a", cnum="383", response="2e315122a3a496c4abaa2e70d7b154567e64f1a2"</em></span>
<span style="color: #808080"><em>Content-Type: application/sdp</em></span>
<span style="color: #808080"><em>Content-Length: 763</em></span>
<span style="color: #0000ff">v=0</span>
<span style="color: #0000ff">o=- 0 1 IN IP4 xx.xx.xx.xx</span>
<span style="color: #0000ff">s=session</span>
<span style="color: #0000ff">c=IN IP4 xx.xx.xx.xx</span>
<span style="color: #0000ff">b=CT:99980</span>
<span style="color: #0000ff">t=0 0</span>
<span style="color: #0000ff">m=applicationsharing 50043 TCP/RTP/SAVP 127</span>
<span style="color: #0000ff">a=ice-ufrag:VvoJ</span>
<span style="color: #0000ff">a=ice-pwd:za3jOXA4LzS7Lr4eZCC9appB</span>
<span style="color: #0000ff">a=candidate:14 1 TCP-ACT 1852570879 xx.xx.xx.xx 50043 typ prflx raddr 192.168.50.121 rport 50043</span>
<span style="color: #0000ff">a=x-candidate-info:14 network-type=wlan</span>
<span style="color: #0000ff">a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:z0oEcJPviJ2Q4CNEXt75fE3PyOrJyDDE33PsRDUe|2^31|1:1</span>
<span style="color: #0000ff">a=remote-candidates:1 xx.xx.xx.xx 51039 2 xx.xx.xx.xx 51039</span>
<span style="color: #0000ff">a=setup:active</span>
<span style="color: #0000ff">a=connection:existing</span>
<span style="color: #0000ff">a=mid:1</span>
<span style="color: #0000ff">a=rtpmap:127 x-data/90000</span>
<span style="color: #0000ff">a=rtcp-mux</span>
<span style="color: #0000ff">a=x-bwealgorithm:packetpair</span>
<span style="color: #0000ff">a=x-applicationsharing-session-id:1</span>
<span style="color: #0000ff">a=x-applicationsharing-role:sharer</span>
<span style="color: #0000ff">a=x-applicationsharing-media-type:rdp</span>
<span style="color: #0000ff">a=x-applicationsharing-contentflow:sendonly</span></p>
<p align="LEFT" dir="LTR">And now Finally if we Blocked all UCP high ports , low ports and TCP high ports the final path will be port TCP 443 for all media types.</p>
<p align="LEFT" dir="LTR"><a href="https://msdnshared.blob.core.windows.net/media/2017/06/block-all.png"><img width="1574" height="224" class="alignnone size-full wp-image-375" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/06/block-all.png" /></a></p>
<p align="LEFT" dir="LTR">Note that i noticed a degradation in voice quality at this point but the SILKWide was still used as a codec, which i found in the VQReport.</p>

<h1 align="LEFT">Conclusion :</h1>
Destination Ports for Skype for Business Online and the alternative paths are different from that of the on-premises.

The tables below illustrate the destination ports and alternative paths in priority for each of the on-premises and cloud.
<h2><strong>Outbound</strong> Traffic preferred route for <strong>On-premises</strong>:</h2>
<span style="color: #ff0000"><strong>Route 1:</strong></span>
<table width="809">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">50000 - 59999</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">50000 - 59999</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 2:</strong></span>
<table width="813">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">3478</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 3:</strong></span>
<table width="813">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">TCP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">50000 - 59999</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">TCP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Edge  Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 4:</strong></span>
<table width="846">
<tbody>
<tr>
<td width="104"><strong>Media Type</strong></td>
<td width="104"><strong>Transport</strong></td>
<td width="104"><strong>Source</strong></td>
<td width="104"><strong>Port</strong></td>
<td width="255"><strong>Destination</strong></td>
<td width="104"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">TCP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">TCP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

&nbsp;

&nbsp;
<h2><strong>Inbound</strong> Traffic preferred route:</h2>
<span style="color: #ff0000"><strong>Route 1:</strong></span>
<table width="827">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="85" class="auto-style2"><strong>Transport</strong></td>
<td width="246" class="auto-style2"><strong>Source</strong></td>
<td width="113" class="auto-style2"><strong>Port</strong></td>
<td width="113" class="auto-style2"><strong>Destination</strong></td>
<td width="113" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="85">UDP</td>
<td width="246">SfB Edge Server IPs OR Client Subnet in P2P</td>
<td width="113">50000 - 59999</td>
<td width="113">Client Subnet</td>
<td width="113">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="85" class="auto-style3">UDP</td>
<td width="246" class="auto-style3">SfB Edge Server IPs OR Client Subnet in P2P</td>
<td width="113" class="auto-style3">50000 - 59999</td>
<td width="113" class="auto-style3">Client Subnet</td>
<td width="113" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="85">UDP</td>
<td width="246">SfB Edge Server IPs OR Client Subnet in P2P</td>
<td width="113">50000 - 59999</td>
<td width="113">Client Subnet</td>
<td width="113">50040 - 50059</td>
</tr>
<tr>
<td width="104">AppShare RDP</td>
<td width="85">TCP</td>
<td width="246">SfB Edge Server IPs OR Client Subnet in P2P</td>
<td width="113">50000 - 59999</td>
<td width="113">Client Subnet</td>
<td width="113">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 2:</strong></span>
<table width="819">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="255" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="104" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">3478</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 3:</strong></span>
<table width="815">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="255" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="104" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">TCP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">50000 - 59999</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">TCP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000"><strong>Alternative Route 4:</strong></span>
<table width="815">
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="255" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="104" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">TCP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">TCP</td>
<td width="255">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Edge Server IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

&nbsp;

&nbsp;

<span style="color: #ff0000"><strong>The Way its configured now in the cloud is Different and below is the table for the cloud media paths:</strong></span>
<h2>Outbound Traffic preferred route for Skype for Business <strong>Online</strong>:</h2>
<span style="color: #ff0000"><strong>Route 1:</strong></span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">50000 - 59999</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">50000 - 59999</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000">Alternative Route 2:</span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478 or Transport Relay 3479</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">3478 or Transport Relay 3480</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478 or Transport Relay 3481</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000">Alternative Route 3:</span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="104" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="255" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104" class="auto-style1">Audio</td>
<td width="104" class="auto-style1">TCP</td>
<td width="104" class="auto-style1">Client Subnet</td>
<td width="104" class="auto-style1">50000 - 50019</td>
<td width="255" class="auto-style1">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style1">443</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
<tr>
<td width="104" class="auto-style1">VBSS</td>
<td width="104" class="auto-style1">TCP</td>
<td width="104" class="auto-style1">Client Subnet</td>
<td width="104" class="auto-style1">50040 - 50059</td>
<td width="255" class="auto-style1">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style1">443</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
</tr>
</tbody>
</table>
&nbsp;

&nbsp;
<h3>Inbound Traffic preferred route:</h3>
<span style="color: #ff0000"><strong>Route 1:</strong></span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="85" class="auto-style2"><strong>Transport</strong></td>
<td width="246" class="auto-style2"><strong>Source</strong></td>
<td width="113" class="auto-style2"><strong>Port</strong></td>
<td width="113" class="auto-style2"><strong>Destination</strong></td>
<td width="113" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="85">UDP</td>
<td width="246">SfB Online IPs OR Client Subnet in P2P</td>
<td width="113">50000 - 59999</td>
<td width="113">Client Subnet</td>
<td width="113">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="85" class="auto-style3">UDP</td>
<td width="246" class="auto-style3">SfB Online IPs OR Client Subnet in P2P</td>
<td width="113" class="auto-style3">50000 - 59999</td>
<td width="113" class="auto-style3">Client Subnet</td>
<td width="113" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="85">UDP</td>
<td width="246">SfB Online IPs OR Client Subnet in P2P</td>
<td width="113">50000 - 59999</td>
<td width="113">Client Subnet</td>
<td width="113">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="85" class="auto-style3">TCP</td>
<td width="246" class="auto-style3">SfB Online IPs OR Client Subnet in P2P</td>
<td width="113" class="auto-style3">443</td>
<td width="113" class="auto-style3">Client Subnet</td>
<td width="113" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000">Alternative Route 2:</span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="255" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="104" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">UDP</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478  or Transport Relay 3479</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">UDP</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">3478 or Transport Relay 3480</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">UDP</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">3478 or Transport Relay 3481</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

<span style="color: #ff0000">Alternative Route 3:</span>
<table>
<tbody>
<tr>
<td width="104" class="auto-style2"><strong>Media Type</strong></td>
<td width="104" class="auto-style2"><strong>Transport</strong></td>
<td width="255" class="auto-style2"><strong>Source</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
<td width="104" class="auto-style2"><strong>Destination</strong></td>
<td width="104" class="auto-style2"><strong>Port</strong></td>
</tr>
<tr>
<td width="104">Audio</td>
<td width="104">TCP</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
<td width="104">Client Subnet</td>
<td width="104">50000 - 50019</td>
</tr>
<tr>
<td width="104" class="auto-style3">Video</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50020 - 50039</td>
</tr>
<tr>
<td width="104">VBSS</td>
<td width="104">TCP</td>
<td width="255">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104">443</td>
<td width="104">Client Subnet</td>
<td width="104">50040 - 50059</td>
</tr>
<tr>
<td width="104" class="auto-style3">AppShare RDP</td>
<td width="104" class="auto-style3">TCP</td>
<td width="255" class="auto-style3">SfB Online IPs <strong>OR</strong> Client Subnet in P2P</td>
<td width="104" class="auto-style3">443</td>
<td width="104" class="auto-style3">Client Subnet</td>
<td width="104" class="auto-style3">50040 - 50059</td>
</tr>
</tbody>
</table>
&nbsp;

&nbsp;

</div>
</article></div>
</div>
</div>
</div>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>Netmon capabilities for Skype for Business online troubleshooting</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/netmon-capabilities-for-skype-for-business-online-troubleshooting</link>
      <pubDate>Tue, 16 May 2017 22:06:56 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=205</guid>
      <description><![CDATA[Many times we need to do network trace using tools like wireshark, netmon or Message analyzer.

i...]]></description>
      <content:encoded><![CDATA[Many times we need to do network trace using tools like wireshark, netmon or Message analyzer.

i find wireshark overwhelming since it doesnt filter the by process, Netmon and Message analyzer provide a way more efficient user interface and filtering based on process as shown on the picture below from netmon:

<a href="https://msdnshared.blob.core.windows.net/media/2017/05/process.png"><img width="493" height="325" class="alignnone wp-image-215" alt="process" src="https://msdnshared.blob.core.windows.net/media/2017/05/process.png" /></a>

but even when you sort by process still you get some noise and i will help you have a clean fast look on by the following capabilities in netmon.

1- Display Filters

First we need to know that SfB online use pre defined source ports based on modality; unlike SfB on-premises where you can configure and change source ports as you wish (reference https://technet.microsoft.com/en-us/library/jj204760(v=ocs.15).aspx)

The pre-defined source ports are listed here https://support.microsoft.com/en-us/help/2409256/you-can-t-connect-to-skype-for-business-online,-or-certain-features-don-t-work,-because-an-on-premises-firewall-blocks-the-connection
<table width="941">
<tbody>
<tr>
<td><strong>Modality</strong></td>
<td><strong>Source</strong></td>
<td><strong>Destination</strong></td>
<td><strong>Source Port</strong></td>
<td><strong>Destination port</strong></td>
</tr>
<tr>
<td>Audio</td>
<td>Client</td>
<td>Office 365</td>
<td>50000 - 50019 UDP and TCP</td>
<td>443 TCP, 3478 UDP, 50000 - 59999 UDP and TCP</td>
</tr>
<tr>
<td>Video</td>
<td>Client</td>
<td>Office 365</td>
<td>50020 - 50039 UDP and TCP</td>
<td>443 TCP, 3478 UDP, 50000 - 59999 UDP and TCP</td>
</tr>
<tr>
<td>Desktop Sharing</td>
<td>Client</td>
<td>Office 365</td>
<td>50040 - 50059 UDP and TCP</td>
<td>443 TCP, 50000 - 59999 TCP</td>
</tr>
</tbody>
</table>
so based on these ports we can have the following display filters to narrow down on which network capture we need.
<blockquote>
<pre><span style="color: #808080">//INBOUND SfB</span>

<span style="color: #808080">// Source ports: 50000 - 50019 Audio</span>
<span style="color: #808080">(tcp.dstPort&gt;=50000 AND tcp.dstPort&lt;=50019) OR (udp.dstPort&gt;=50000 AND udp.dstPort&lt;=50019)</span>
<span style="color: #808080">// Source ports: 50020 - 50039 Video</span>
<span style="color: #808080">or</span>
<span style="color: #808080">(tcp.dstPort&gt;=50020 AND tcp.dstPort&lt;=50039) OR (udp.dstPort&gt;=50020 AND udp.dstPort&lt;=50039)</span>
<span style="color: #808080">// Source ports: 50040 - 50060 VBSS and AppShare</span>
<span style="color: #808080">or</span>
<span style="color: #808080">(tcp.dstPort&gt;=50040 AND tcp.dstPort&lt;=50060) OR (udp.dstPort&gt;=50040 AND udp.dstPort&lt;=50060)</span>

<span style="color: #808080">OR</span>

<span style="color: #808080">//OUTBOUND SfB</span>

<span style="color: #808080">// Source ports: 50000 - 50019 Audio</span>
<span style="color: #808080">(tcp.SrcPort&gt;=50000 AND tcp.SrcPort&lt;=50019) OR (udp.SrcPort&gt;=50000 AND udp.SrcPort&lt;=50019)</span>
<span style="color: #808080">// Source ports: 50020 - 50039 Video</span>
<span style="color: #808080">or</span>
<span style="color: #808080">(tcp.SrcPort&gt;=50020 AND tcp.SrcPort&lt;=50039) OR (udp.SrcPort&gt;=50020 AND udp.SrcPort&lt;=50039)</span>
<span style="color: #808080">// Source ports: 50040 - 50060 VBSS and AppShare</span>
<span style="color: #808080">or</span>
<span style="color: #808080">(tcp.SrcPort&gt;=50040 AND tcp.SrcPort&lt;=50060) OR (udp.SrcPort&gt;=50040 AND udp.SrcPort&lt;=50060)</span></pre>
</blockquote>
All you need is to past the above code in the display filter and Apply then "Save Filter" like in the below picture

<a href="https://msdnshared.blob.core.windows.net/media/2017/05/display.png"><img width="654" height="75" class="alignnone wp-image-225" alt="display" src="https://msdnshared.blob.core.windows.net/media/2017/05/display.png" /></a>

2- Color Rules

now we would need to do some color coding for easy reading of these traffic, like below screen shot; i filtered the voice packets on green color, video on red, RDP traffic on grey and VBSS traffic on grey with bold fonts

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/05/color.png"><img width="471" height="955" class="alignnone wp-image-235" alt="color" src="https://msdnshared.blob.core.windows.net/media/2017/05/color.png" /></a>

&nbsp;

you can use import the following color rules to match these setting by doing the following:

1- Create a new file named <em>color.nmcr</em>

2- Paste the following in the file using notepad
<pre><span style="color: #808080">Version = 1</span>

<span style="color: #808080">BEGIN_RULE</span>

<span style="color: #808080">BEGIN_FILTER_TEXT</span>

<span style="color: #808080">(tcp.SrcPort&gt;=50000 AND tcp.SrcPort&lt;=50019) OR (udp.SrcPort&gt;=50000 AND udp.SrcPort&lt;=50019)</span>
<span style="color: #808080">or</span>
<span style="color: #808080">(tcp.dstPort&gt;=50000 AND tcp.dstPort&lt;=50019) OR (udp.dstPort&gt;=50000 AND udp.dstPort&lt;=50019)</span>


<span style="color: #808080">END_FILTER_TEXT</span>

<span style="color: #808080"> Active = 1</span>

<span style="color: #808080"> Foreground = 0, 0, 0</span>

<span style="color: #808080"> Background = 128, 255, 128</span>

<span style="color: #808080"> Bold = 0</span>

<span style="color: #808080"> Italic = 0</span>

<span style="color: #808080"> Underline = 0</span>

<span style="color: #808080">END_RULE</span>

<span style="color: #808080">BEGIN_RULE</span>

<span style="color: #808080">BEGIN_FILTER_TEXT</span>

<span style="color: #808080">(tcp.SrcPort&gt;=50020 AND tcp.SrcPort&lt;=50039) OR (udp.SrcPort&gt;=50020 AND udp.SrcPort&lt;=50039)</span>
<span style="color: #808080">or (tcp.dstPort&gt;=50020 AND tcp.dstPort&lt;=50039) OR (udp.dstPort&gt;=50020 AND udp.dstPort&lt;=50039)</span>

<span style="color: #808080">END_FILTER_TEXT</span>

<span style="color: #808080"> Active = 1</span>

<span style="color: #808080"> Foreground = 0, 0, 0</span>

<span style="color: #808080"> Background = 255, 0, 128</span>

<span style="color: #808080"> Bold = 0</span>

<span style="color: #808080"> Italic = 0</span>

<span style="color: #808080"> Underline = 0</span>

<span style="color: #808080">END_RULE</span>

<span style="color: #808080">BEGIN_RULE</span>

<span style="color: #808080">BEGIN_FILTER_TEXT</span>

<span style="color: #808080">(tcp.SrcPort&gt;=50040 AND tcp.SrcPort&lt;=50059)</span>
<span style="color: #808080">or (tcp.dstPort&gt;=50040 AND tcp.dstPort&lt;=50059)</span>

<span style="color: #808080">END_FILTER_TEXT</span>

<span style="color: #808080"> Active = 1</span>

<span style="color: #808080"> Foreground = 0, 0, 0</span>

<span style="color: #808080"> Background = 192, 192, 192</span>

<span style="color: #808080"> Bold = 0</span>

<span style="color: #808080"> Italic = 0</span>

<span style="color: #808080"> Underline = 0</span>

<span style="color: #808080">END_RULE</span>

<span style="color: #808080">BEGIN_RULE</span>

<span style="color: #808080">BEGIN_FILTER_TEXT</span>

<span style="color: #808080">(udp.SrcPort&gt;=50040 AND udp.SrcPort&lt;=50059)</span>
<span style="color: #808080">OR(udp.dstPort&gt;=50040 AND Udp.dstPort&lt;=50059)</span>

<span style="color: #808080">END_FILTER_TEXT</span>

<span style="color: #808080"> Active = 1</span>

<span style="color: #808080"> Foreground = 0, 0, 0</span>

<span style="color: #808080"> Background = 192, 192, 192</span>

<span style="color: #808080"> Bold = 1</span>

<span style="color: #808080"> Italic = 0</span>

<span style="color: #808080"> Underline = 0</span>

<span style="color: #808080">END_RULE</span></pre>
3- from the color rules click Open and browse and select that file.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Is your Exchange Unified Messaging protected against telecommunication fraud?</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/is-your-exchange-unified-messaging-protected-against-telecommunication-fraud</link>
      <pubDate>Wed, 15 Feb 2017 03:45:14 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/?p=85</guid>
      <description><![CDATA[What is Telecommunications Fraud?
Telecommunications fraud is the process of exploiting a...]]></description>
      <content:encoded><![CDATA[What is Telecommunications Fraud?
Telecommunications fraud is the process of exploiting a misconfiguration in telecommunications systems to gain access to your telecommunication platform to make calls on your behalf.

Few things that are really bad about this type of exploit:
<ul>
 	<li>The exploiter don't even need an internet to perform such hack.</li>
 	<li>The exploiter doesn't need your users PIN</li>
 	<li>It can be very costly.</li>
 	<li>it can go unnoticed for a long time, or till you get a surprise bill.</li>
 	<li>The exploiter caller ID will be your company number, might pretend to be your company representative.</li>
 	<li>it can even be so bad that they can sell calling cards to use your system for long distance calls.</li>
 	<li>other scenarios are left for imagination...</li>
</ul>
While Lync/SfB and Exchange UM doesn't have a DISA feature (direct inward system access ) the below mix of configuration can cause a serious leak in the system to allow telecom fraud even when your users have a secure voicemail PIN.

Lets first have a look on how that could be possible:

When you configure Lync/SfB integration with Exchange UM via the OCSUtil ; two contacts are going to be created in Lync/SfB and assigned automatic Dial Plan and Voice Policy.
<ol>
 	<li>The Auto Attendant contact</li>
 	<li>The Subscriber access contact</li>
</ol>
Also you in exchange UM an important component will be populated by running the exchUCUtil script which is the "virtual" 1:1 IP gateway.

Now lets go to the configuration:

I've seen a lot of companies now avoid the short extension assignment in Lync/SfB and just use E164 format with 10 digit North America DID for the users' line URI.

so when they start the integration with Exchange UM they will need to assign Exchange UM extensions for the users in Exchange, and to simplify things, they will use that 10 digit DID as an "Extension".

So far that is not going to cause an issue until they enable "Allow calls to Extension" in the UM dial plan, UM mailbox Policy or the Auto attendant.

Configuration of my lab was the following:
<ul>
 	<li>7 and 10 digits North American plan is configured in SfB/Lync at the <strong>Default,Pool or Site</strong> Dial plan to allow E.164 normalization.; Also if you dont have <b>Default,Pool or Site</b> dial plan normalization defined and created Translation rules on <strong>Global</strong> trunk normalization to capture 10 digits coming from the Trunk and normalize to E.164 that will also work.</li>
 	<li>SfB Users have 10 digits DID normalized in E.164;  e.g: (lineURI is <strong>tel:+1(NPA)XXX-XXXX</strong>)</li>
 	<li>Exchange UM dial plan is 10 digits extension and "<em>allow calls to extensions"</em> is enabled on Dial Plan , Auto Attendant and UM mailbox Policy</li>
 	<li><a href="https://msdnshared.blob.core.windows.net/media/2017/02/10-digit.png"><img width="402" height="478" class="wp-image-115 alignnone" alt="10-digit" src="https://msdnshared.blob.core.windows.net/media/2017/02/10-digit.png" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2017/02/policy.png"><img width="426" height="483" class="wp-image-145 alignnone" alt="policy" src="https://msdnshared.blob.core.windows.net/media/2017/02/policy.png" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2017/02/calls-to-exten.png"><img width="429" height="506" class="wp-image-135 alignnone" alt="calls-to-exten" src="https://msdnshared.blob.core.windows.net/media/2017/02/calls-to-exten.png" /></a><a href="https://msdnshared.blob.core.windows.net/media/2017/02/calls-to-exten-AA.png"><img width="447" height="505" class="wp-image-125 alignnone" alt="calls-to-exten-aa" src="https://msdnshared.blob.core.windows.net/media/2017/02/calls-to-exten-AA.png" /></a></li>
 	<li>

<hr />

</li>
</ul>
With this configuration the following scenarios was dialled:
<ol>
 	<li><strong>Scenario 1: </strong>Caller dials the AA number and as it prompts to dial an extension, I dialled any 10 Digits number (eg.my mobile) and the call was made outside of my SfB server. so for that to happen:
<ul>
 	<li>A- The Extensions expected are 10 digits based on the UM dialplan</li>
 	<li>B- ExUM send that through the 1:1 IP gateway.</li>
 	<li>C- The 7 or 10 digit Extension will get Normalized to E.164 on the SfB Global, Site or Pool Dialplan which is the default/automatic dialplan for the UMAA object OR on the Trunk Global number translation.</li>
 	<li>D- The UMAA contact object that was created by the OCSUtil has the default Global or Site voice policy that has a route to terminate E164 digits on the PSTN.</li>
</ul>
</li>
 	<li><strong>Scenario 2:</strong> Caller dials the SA number and navigate till it prompts to dial an extension, I dialled any 10 Digits number (eg.my mobile) and the call was made outside of my SfB server.</li>
</ol>
<ul>
 	<li>A- The Extensions expected are 10 digits based on the UM dialplan</li>
 	<li>B- ExUM send that through the 1:1 IP gateway.</li>
 	<li>C- The 7 or 10 digit Extension will get Normalized to E.164 on the SfB Global, Site or Pool Dialplan which is the default/automatic dialplan for the UMSA object OR on the Trunk Global number translation.</li>
 	<li>D- The UMSA contact object that was created by the OCSUtil has the default Global or Site voice policy that has a route to terminate E164 digits on the PSTN.</li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/02/ps1.png"><img width="1264" height="286" class="alignnone size-full wp-image-165" alt="ps" src="https://msdnshared.blob.core.windows.net/media/2017/02/ps1.png" /></a>
<ul>
 	<li>3.   <strong>Scenario 3:</strong> Caller dials any SfB DID number and timeout to voicemail the caller press **## then it prompts to dial an extension, I dialled any 10 Digits number (eg.my mobile) and again the call was made outside of my SfB server.
<ul>
 	<li>A- The Extensions expected are 10 digits based on the UM dialplan</li>
 	<li>B- ExUM send that through the 1:1 IP gateway.</li>
 	<li>C- The 7 or 10 digit Extension will get Normalized to E.164 on the SfB Global, Site or Pool Dialplan which is the default/automatic dialplan for the Referred User (In that case the SfB Dialed/Voicemail User ).</li>
 	<li>D- The Referred User has the Global, Site or User voice policy that has a route to terminate E164 digits on the PSTN.</li>
</ul>
</li>
</ul>
&nbsp;

Below is a flowchart of my lab findings that I logged and how the call could be routed outside of your system from an anonymous caller.

&nbsp;
<ul></ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/02/ExUM-routing2.jpg"><img width="1239" height="1081" class="alignnone size-full wp-image-186" alt="exum-routing2" src="https://msdnshared.blob.core.windows.net/media/2017/02/ExUM-routing2.jpg" /></a>

&nbsp;

&nbsp;

<strong><em></em>That was the problem now for the solution:</strong>

For the<strong> First</strong> and <strong>Second Scenario</strong> where the Caller Dials the AA and SA you need the Allow Extensions dialling to be enabled in both the UMdial Plan and Auto Attendant, the reason is that you may have a PBX that is behind the SfB server that the legitimate caller might need to call.

So the solution is to assign both the AA and SA objects a Voice Policy and a Route that ONLY routes to PBXes without PSTN access (if your PBX are 7 or 10 digits) ; if your PBX extensions is less than the UMDial plan, it will not route anyway. Also you can remove the Associated Trunk altogether from that Route so if the number isnt found in SfB Server it doesn't leave to any where.

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/ps2.png"><img width="1336" height="367" class="alignnone size-full wp-image-175" alt="ps2" src="https://msdnshared.blob.core.windows.net/media/2017/02/ps2.png" /></a>

&nbsp;

But for the <strong>Third Scenario</strong> where the caller dials the voicemail and then press **## you wouldn't be able to change the voice policy as the Referrer is the SfB user.

<strong>So you will need to do the following:</strong>
<ol>
 	<li>Turn off "Dial by Extension" from the <strong>UM Mailbox Policy</strong> to prevent callers from dialing on behalf of the user being dialed.</li>
 	<li>Redirect the Caller to the Operator <strong>only;</strong> where they can dial other <strong>Internal</strong> Extensions from the Auto Attendant or Subscriber Access after we apply the restrictive voice policies as discussed above .</li>
</ol>
You will have to <strong>turn off</strong> the "dial by extension" from the <strong>UM Mailbox Policy.</strong> But at the same time you can enable the caller to dial (0) at the voicemail prompt to transfer only to the operator.
<div>For a caller to be transferred to an operator, the caller must press 0 on their telephone keypad while the user's custom voice mail greeting is being played.</div>
<div></div>
<div>If the user has not created a customized voice mail greeting, the default system greeting will be used and the system will add the operator prompt automatically.</div>
<div>For example, <em>"Please leave a message for Tony Smith. To speak to an operator, press 0." </em> If the caller does not press 0 during the voice mail greeting, they can leave a voice message for the user.</div>
<div></div>
<div>If you have not configured a personal operator extension for a user, or if you have not correctly configured the dialing rules on the UM dial plan that is associated with the UM-enabled user, the Unified Messaging server will use the operator extension number that is configured for the dial plan. The default digit to reach the dial plan operator is 0.</div>
<div></div>
<div><span style="color: #ff0000">For that '0' Operator feature to work you have to configure <strong>dialing rule groups</strong> for the<strong> (UM) dial plan</strong> in the Exchange Server.</span></div>
<div></div>
<div>After you create a <strong><em>dialing rule group</em>,</strong> you must add a<strong><em> dialing group entry</em>.</strong> After you create the dialing rule group and configure the dialing rule entries, you must <strong>add</strong> the <strong>dialing rule group</strong> to the<strong><em> dialing restrictions</em> </strong>on the <strong>UM mailbox policy</strong> associated with the <strong>UM dial plan</strong>.</div>
<div></div>
<div>When you add the dialing rule group to the dialing restrictions on the UM mailbox policy, the settings you use will apply to <strong>all</strong> UM-enabled users associated with the UM mailbox policy.</div>
<div></div>
<div>Creating those Dialing groups and rules will allow the following features for the Users:</div>
<div>1- The ability for callers to press 0 at the voicemail to transfer to an operator</div>
<div>2- Ability to play on Phone for the applied Users from the OWA voicemail settings</div>
<div>3- Ability to use follow me settings from the OWA voicemail.</div>
<div></div>
<div>You'll probably find it unnecessary to build patterns in the dialing rules or dialing rule groups in Exchange Unified Messaging.</div>
<div>SfB Server voice policy will perform call routing and number translation for the corresponding users when the calls are made by Exchange Unified Messaging on behalf of users , so you can use the wildcard * for the Mask number and dialled number to allow any digits from the user OWA voicemail features like play on phone and/or follow me.</div>
<div></div>
<div></div>]]></content:encoded>
    </item>
    <item>
      <title>Azure Site to Site VPN required Device configuration parameters</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/azure-site-to-site-vpn-required-device-configuration-parameters</link>
      <pubDate>Sun, 08 Nov 2015 17:33:00 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/2015/11/08/azure-site-to-site-vpn-required-device-configuration-parameters/</guid>
      <description><![CDATA[Whether you Selected IKEv1 or IKEv2 the following settings needs to be configurable with the...]]></description>
      <content:encoded><![CDATA[<h3 id="t101704" class="heading3">Whether you Selected IKEv1 or IKEv2 the following settings needs to be configurable with the following values:</h3>
<h3 class="heading3">Methods of Encryption and Integrity</h3>
<p class="tpbodytext">Two parameters are decided during the negotiation:</p>
<ul class="listbullet">
<li class="listbullet">Encryption algorithm</li>
<li class="listbullet">Hash algorithm</li>
</ul>
<table class="tableintopic" style="border: 1px solid #dddddd; width: 606px; border-collapse: collapse; border-image: none;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr align="left" valign="top"><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="192">
<p class="tableheading">Parameter</p>
</th><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="192">
<p class="tableheading">IKE Phase 1 (IKE SA)</p>
</th><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="222">
<p class="tableheading">IKE PHASE 2 (IPSec SA)</p>
</th></tr>
<tr align="left" valign="top">
<td style="border: 1px solid #dddddd; border-image: none;" width="192">
<p class="tablebodytext">Encryption</p>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="192">
<ul class="tablelistbullet">
<li class="tablelistbullet">AES-128</li>
<li class="tablelistbullet"><strong>AES-256(Required)</strong></li>
<li class="tablelistbullet">3DES</li>
<li class="tablelistbullet">DES</li>
<li class="tablelistbullet">CAST (IKEv1 only)</li>
</ul>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="222">
<ul class="tablelistbullet">
<li class="tablelistbullet">AES-128</li>
<li class="tablelistbullet"><strong>AES-256 (Required)</strong></li>
<li class="tablelistbullet">3DES</li>
<li class="tablelistbullet">DES</li>
<li class="tablelistbullet">DES-40CP (IKEv1 only)</li>
<li class="tablelistbullet">CAST (IKEv1 only)</li>
<li class="tablelistbullet">CAST-40 (IKEv1 only)</li>
<li class="tablelistbullet">NULL</li>
<li class="tablelistbullet">AES-GCM-128</li>
<li class="tablelistbullet">AES-GCM-256</li>
</ul>
</td>
</tr>
<tr align="left" valign="top">
<td style="border: 1px solid #dddddd; border-image: none;" width="192">
<p class="tablebodytext">Integrity</p>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="192">
<ul class="tablelistbullet">
<li class="tablelistbullet">MD5</li>
<li class="tablelistbullet">SHA1</li>
<li class="tablelistbullet"><strong>SHA -256 (Required)</strong></li>
<li class="tablelistbullet">AES-XCBC</li>
<li class="tablelistbullet">SHA -384</li>
</ul>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="222">
<ul class="tablelistbullet">
<li class="tablelistbullet">MD5</li>
<li class="tablelistbullet">SHA1</li>
<li class="tablelistbullet"><strong>SHA -256 (Required)</strong></li>
<li class="tablelistbullet">AES-XCBC</li>
<li class="tablelistbullet">SHA -384</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h4 id="t99989" class="heading4">Diffie Hellman Groups</h4>
<p class="tpbodytext">The Diffie-Hellman key computation (also known as exponential key agreement) is based on the Diffie Hellman (DH) mathematical groups. A Security Gateway supports these DH groups during the two phases of IKE.</p>
<table class="tableintopic" style="border: 1px solid #dddddd; width: 612px; border-collapse: collapse; border-image: none;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr align="left" valign="top"><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="156">
<p class="tableheading">Parameter</p>
</th><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="246">
<p class="tableheading">IKE Phase 1 (IKE SA)</p>
</th><th style="border: 1px solid #dddddd; border-image: none;" bgcolor="#f5f6fb" width="210">
<p class="tableheading">IKE Phase 2 (IPSec SA)</p>
</th></tr>
<tr align="left" valign="top">
<td style="border: 1px solid #dddddd; border-image: none;" width="156">
<p class="tablebodytext">Diffie Hellman Groups</p>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="246">
<ul class="tablelistbullet">
<li class="tablelistbullet"><strong>Group2 (1024 bits) (Required)</strong></li>
<li class="tablelistbullet">Group1 (768 bits)</li>
<li class="tablelistbullet">Group5 (1536 bits)</li>
<li class="tablelistbullet">Group14 (2048 bits)</li>
<li class="tablelistbullet">Group19 (256-bit ECP)</li>
<li class="tablelistbullet">Group20 (384-bit ECP)</li>
</ul>
</td>
<td style="border: 1px solid #dddddd; border-image: none;" width="210">
<ul class="tablelistbullet">
<li class="tablelistbullet"><strong>Group2 (1024 bits) (Required)</strong></li>
<li class="tablelistbullet">Group1 (768 bits)</li>
<li class="tablelistbullet">Group5 (1536 bits)</li>
<li class="tablelistbullet">Group14 (2048 bits)</li>
<li class="tablelistbullet">Group19 (256-bit ECP)</li>
<li class="tablelistbullet">Group20 (384-bit ECP)</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;<strong>(Main mode is the required</strong>) vs aggressive mode</p>
<p><strong>Perfect Forward Secrecy is Disabled</strong></p>
<p><strong>ESP&nbsp; (Encapsulating Security Payload) is required</strong> vs AH &nbsp;(Authentication Header)</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Ref: <a href="https://sc1.checkpoint.com/documents/R77/CP_R77_VPN_AdminGuide/13847.htm">https://sc1.checkpoint.com/documents/R77/CP_R77_VPN_AdminGuide/13847.htm</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Create Custom OS in Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/create-custom-os-in-azure</link>
      <pubDate>Sat, 09 May 2015 13:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/2015/05/09/create-custom-os-in-azure/</guid>
      <description><![CDATA[1- Create you Custom VM in a Hyper-v in your local machine with disk format of VHD
2- Sysprep the...]]></description>
      <content:encoded><![CDATA[<p>1- Create you Custom VM in a Hyper-v in your local machine with disk format of <strong>VHD</strong></p>
<p>2- Sysprep the Windows Machine or&nbsp;in Linux "waagent"</p>
<p>Sysprep for Hyper-v VM</p>
<ul>
<li>Open a Command Prompt window using Run as administrator</li>
<li>Change the directory to %windir%\system32\sysprep.</li>
<li>Run sysprep.exe as shown below<br />&nbsp;</li>
</ul>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/6087.image002_213.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/6087.image002_5F00_213.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/6087.image002_213.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/6087.image002_5F00_213.png" alt="" border="0" /></a></p>
<p>for Linux:</p>
<p>Follow the Linux waagent guide from this link&nbsp;<a href="http://azure.microsoft.com/en-in/documentation/articles/virtual-machines-linux-agent-user-guide/">http://azure.microsoft.com/en-in/documentation/articles/virtual-machines-linux-agent-user-guide/</a></p>
<p>&nbsp;&nbsp;</p>
<p>3-&nbsp; Create Azure Storage and create a container</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/6811.1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/6811.1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/6811.1.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/6811.1.png" alt="" border="0" /></a></p>
<p>Select the created storage account, click the CONTAINERS tab and click ADD CONTAINER .</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/8130.2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/8130.2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/8130.2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/8130.2.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>4- Download&nbsp; and Install Azure PowerShell from here</p>
<p><a href="https://github.com/Azure/azure-powershell/releases">https://github.com/Azure/azure-powershell/releases</a></p>
<p>&nbsp;</p>
<p>5&nbsp;- Connect to AzureAccount</p>
<p>&nbsp;After the installation is complete Open the Azure PowerShell console</p>
<p>Type the following command:<br /><em>Add-AzureAccount</em></p>
<p>&nbsp;Enter your Azure Credentials</p>
<p>6- Upload your VHD to the container you created in Step 3</p>
<p><em>Add<span style="color: gray;">-</span>AzureVhd <span style="color: gray;">-</span>Destination http:<span style="color: gray;">/</span><span style="color: gray;">/</span><strong>mytestaccount</strong>.blob.core.windows.net<span style="color: gray;">/</span><strong>testcontainer</strong><span style="color: gray;">/</span>win7baseimage.vhd <span style="color: gray;">-</span>LocalFilePath C:\vhd\MyWin7Image.vhd </em></p>
<p>&nbsp;</p>
<p>7- Create an Image from the VHD</p>
<p>Navigate to <strong>Virtual Machines</strong> &gt;&gt; <strong>Images</strong> &gt;&gt; <strong>Create Image</strong></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4024.Untitled%20picture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4024.Untitled-picture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4024.Untitled%20picture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4024.Untitled-picture.png" alt="" border="0" /></a>&nbsp;</p>
<p>Type the Name, Description and Select the VHD you uploaded in Step 6, Select the OS type and continue</p>
<p>8- Create a Virtual Machine from "My Image" found in Gallery</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/2475.Untitled%20picture2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/2475.Untitled-picture2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/2475.Untitled%20picture2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/2475.Untitled-picture2.png" alt="" width="280" height="1007" border="0" /></a></p>
<p>&nbsp;</p>
<p>Reference: <a href="http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-create-upload-vhd-windows-server/">http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-create-upload-vhd-windows-server/</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Create Azure VPN point to Site</title>
      <link>https://docs.microsoft.com/archive/blogs/mahmoud_badran/create-azure-vpn-point-to-site</link>
      <pubDate>Fri, 08 May 2015 22:35:00 GMT</pubDate>
      <dc:creator><![CDATA[Mahmoud Badran]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mahmoud_badran/2015/05/08/create-azure-vpn-point-to-site/</guid>
      <description><![CDATA[1- Download the MakeCert tool from the SDK to create the&nbsp;certificates for the VPN:
Install...]]></description>
      <content:encoded><![CDATA[<p>1- Download the MakeCert tool from the SDK to create the&nbsp;certificates for the VPN:</p>
<p>Install Windows Software Development Kit (SDK) for Windows&nbsp;8.1&nbsp;<a href="https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx">https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx</a></p>
<p>Only Select <strong>windows software development kit </strong>and<strong> net framework 4.5.1 software development kit </strong>those should be enough to have the MakeCert tool for creating the VPN certificate</p>
<p>&nbsp;</p>
<p>2- Create the certificate:</p>
<p>Create a folder on your c: drive and run the following commands</p>
<p>PS C:\TempFolder&gt; &amp; 'C:\Program Files (x86)\Windows Kits\8.1\bin\x64\makecert.exe'&nbsp; -sky exchange -r -n "CN=<strong>RootCertificateName</strong>" -pe -a sha1 -len 2048 -ss My "<strong>RootCertificateName</strong>.cer"</p>
<p>&nbsp;</p>
<p>PS C:\TempFolder&gt; &amp; 'C:\Program Files (x86)\Windows Kits\8.1\bin\x64\makecert.exe' -n "CN=<strong>ClientCertificateName</strong>" -pe -sky exchange -m 96 -ss My -in "<strong>RootCertificateName</strong>" -is my -a sha1</p>
<p>&nbsp;</p>
<p>From&nbsp;MMC verify that the RootCertificate is installed on your Local Machine Root Certificate&nbsp;Container &nbsp;and that the ClientCertificate is installed in the Local Machine Personal Certificate container.</p>
<p>&nbsp;</p>
<p>3- Enable VPN Point to Site</p>
<p style="margin: 0in;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/2577.Untitled%20picture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/2577.Untitled-picture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/2577.Untitled%20picture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/2577.Untitled-picture.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>4 -Add a Subnet for the VPN client&nbsp;Address</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/5710.Untitled%20picture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/5710.Untitled-picture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/5710.Untitled%20picture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/5710.Untitled-picture.png" alt="" border="0" /></a></p>
<p>5- Add Gateway to the Virtual Network you already have</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4405.Untitled%20picture2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4405.Untitled-picture2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4405.Untitled%20picture2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4405.Untitled-picture2.png" alt="" border="0" /></a></p>
<p>5- Upload the Certificate</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/0447.Untitled%20picture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/0447.Untitled-picture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/0447.Untitled%20picture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/0447.Untitled-picture.png" alt="" border="0" /></a></p>
<p>6- Now the Client will appear to Download</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/8686.Untitled%20picture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/8686.Untitled-picture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/8686.Untitled%20picture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/8686.Untitled-picture.png" alt="" border="0" /></a></p>
<p>Download either 64 or 32 and you are now set to connect</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4760.Untitled%20picture2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4760.Untitled-picture2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/71/12/4760.Untitled%20picture2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-71-12/4760.Untitled-picture2.png" alt="" border="0" /></a></p>
<p>Enjoy!</p>
<p>&nbsp;<a href="https://azure.microsoft.com/en-us/documentation/articles/vpn-gateway-point-to-site-create/">https://azure.microsoft.com/en-us/documentation/articles/vpn-gateway-point-to-site-create/</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>