Testing Lync server 2013 external URLs from Lync clients (external web service, meet, office webapps, lyncdiscover and dialin)

Hi there,

 

In this blog post, I’ll be talking about another powershell based tool which could be used to check name resolution, TCP layer connectivity and SSL/TLS negotiation for various URLs that are accessible through your reverse proxy which are:

 

- External web services URL

- Meet URL

- Office WebApps URL

- Lyncdiscover URL

- Dialin URL

 

When the tool is run, you can see if the given URL is successfully resolved to a name. If name resolution succeeds, a TCP session is attempted to the target and if the TCP session successfully created an SSL/TLS negotiation is done with the target URL. And if that succeeds as well, the subject names and subject alternative names in the returned certificate are dumped by the tool. Also expiration time of each certificate is dumped.

 

You’ll have to provide each URL manually (actually I was planning to read all such details from topology file removing the requirement of manual input but due to some issues I decided to enter the information manual for the time being).

 

Such URL details could be easily obtained from your topology file:

 

- External Web services FQDN:

 

- Meet URL and Dialin URL:

 

- Office WebApps URL:

 

- Lyncdiscover URL:

Lyncdiscover URL is built by adding “lyncdiscover” to the beginning of sip domain. Examples:

 

lyncdiscover.contoso.com

lyncdiscover.fabrikam.com

 

=> Here is the full Powershell script source:

 

 

#------------SCRIPT STARTS HERE-----------

 

 

# ResolveLyncNames() resolves various Lync names to IP addresses

 

function ResolveLyncNames {

 

param($LyncFqdn)

 

try {

$ipaddr = [System.Net.Dns]::GetHostAddresses($LyncFqdn)

Write-Host "Successfully resolved $LyncFqdn to $ipaddr" -ForegroundColor Green

return 1

}

 

catch {

 

$exception = New-Object system.net.sockets.socketexception

$errorcode = $exception.ErrorCode

write-host "Name resolution failed, error code:$errorcode" -foregroundcolor Red

write-host "Error details: $exception" -foregroundcolor Red

return 0

}

 

 

 

}

 

 

# TLSConnectionCheck() establishes TLS session to remote host at the given TCP port

 

function TLSConnectionCheck {

 

param ($remotehost,$remoteport)

 

try {

 

$TCPConnection = New-Object System.Net.Sockets.Tcpclient($remotehost, $remoteport)

Write-Host "TCP connection has succeeded" -ForegroundColor Green

$TCPStream = $TCPConnection.GetStream()

 

 

try {

 

$SSLStream = New-Object System.Net.Security.SslStream($TCPStream)

Write-Host "SSL connection has succeeded" -ForegroundColor Green

 

try {

$SSLStream.AuthenticateAsClient($remotehost)

Write-Host "SSL authentication has succeeded" -ForegroundColor Green

}

catch {

Write-Host "There's a problem with SSL authentication to $remotehost" -ForegroundColor Red

return

}

 

$certificate = $SSLStream.get_remotecertificate()

 

$certificateX509 = New-Object system.security.cryptography.x509certificates.x509certificate2($certificate)

$SANextensions = New-Object system.security.cryptography.x509certificates.x509Certificate2Collection($certificateX509)

$SANextensions = $SANextensions.Extensions | Where-Object {$_.Oid.FriendlyName -eq "subject alternative name"}

 

Write-Host "=> Remote host certificate details:"

 

Write-Host "Issuer: " $SSLStream.RemoteCertificate.Issuer -ForegroundColor Green

Write-Host "Subject name: " $SSLStream.RemoteCertificate.Subject -ForegroundColor Green

Write-Host "Expiration time: " $SSLStream.RemoteCertificate.GetExpirationDateString() -ForegroundColor Green

Write-Host "Serial number: " $SSLStream.RemoteCertificate.GetSerialNumberString() -ForegroundColor Green

Write-Host "=> Subject alternative names: "

$SANextensions.Format(1)

 

Write-Host "Please make sure that Subject name and Subject alternative names in the certificate are compatible with the names given in https://technet.microsoft.com/en-us/library/gg429704.aspx" -BackgroundColor DarkCyan

Write-Host "Wildcard names in SAN are supported for meet, dialin and Lyncdiscover URLs. Please see https://technet.microsoft.com/en-us/library/hh202161.aspx for more details" -BackgroundColor DarkCyan

 

}

 

catch {

 

Write-Host "$remotehost doesn't support SSL connections at TCP port $remoteport" -foregroundcolor Red

 

}

 

}

 

catch {

 

$exception = New-Object system.net.sockets.socketexception

$errorcode = $exception.ErrorCode

write-host "TCP connection to $remotehost failed, error code:$errorcode" -foregroundcolor Red

write-host "Error details: $exception" -foregroundcolor Red

 

 

}

}

 

 

 

#

# TESTING

#

 

 

write-host "Please enter your external Web services FQDN. This could be seen from your Lync topology. You can skip it by pressing Enter. Example: webext.contoso.com" -ForegroundColor Green

$LyncExternalWebserviceFqdn = Read-Host

write-host "Please enter your meet URL. This could be seen from your Lync topology. You can skip it by pressing Enter. Example: meet.contoso.com" -ForegroundColor Green

$SimpleURL_meet = Read-Host

write-host "Please enter your Office WebApp server FQDN. This could be seen from your Lync topology. You can skip it by pressing Enter. Example: wac.contoso.com" -ForegroundColor Green

$LyncWac = Read-Host

write-host "Please enter your Lyncdiscover URL. You can skip it by pressing Enter. Example: lyncdiscover.contoso.com" -ForegroundColor Green

$SimpleURl_lyncdiscover = Read-Host

write-host "Please enter your dialin URL. This could be seen from your Lync topology. You can skip it by pressing Enter. Example: dialin.contoso.com" -ForegroundColor Green

$SimpleURL_dialin = Read-Host

 

 

 

# ==============================================================================================

# Resolve and access external web service fqdn

# ==============================================================================================

 

Write-Host "================================================================================================================"

Write-Host "TEST 1: External Web service FQDN name resolution and access tests" -ForegroundColor yellow

Write-Host "================================================================================================================"

 

 

$LyncExternalWebserviceFqdnport = 443

 

 

If([string]::IsNullOrEmpty($LyncExternalWebserviceFqdn)) {

 

 Write-Host "External Web services URL is NULL. Bypassing External web services accessibility check"

 

}

 

 

else {

 

 

Write-Host "=> Attempting to resolve External Web Service fqdn ("$LyncExternalWebserviceFqdn" )"

if(ResolveLyncNames($LyncExternalWebserviceFqdn)) {

 

Write-Host "=> Attempting to connect to External Web Service fqdn ("$LyncExternalWebserviceFqdn" ) at TCP port $LyncExternalWebserviceFqdnport"

TLSConnectionCheck $LyncExternalWebserviceFqdn $LyncExternalWebserviceFqdnport

}

 

 

 

# ==============================================================================================

# Resolve and access Meet URL

# ==============================================================================================

 

Write-Host "================================================================================================================"

Write-Host "TEST 2: Meet URL name resolution and access tests" -ForegroundColor yellow

Write-Host "================================================================================================================"

 

 

If([string]::IsNullOrEmpty($SimpleURL_meet)) {

 

 Write-Host "Meet URL is NULL. Bypassing Meet URL accessibility check"

 

}

 

else {

 

$SimpleURL_meet_port = 443

 

Write-Host "=> Attempting to resolve Meet URL ("$SimpleURL_meet" )"

if(ResolveLyncNames($SimpleURL_meet)) {

 

Write-Host "=> Attempting to connect to Meet URL ("$SimpleURL_meet" ) at TCP port $SimpleURL_meet_port"

TLSConnectionCheck $SimpleURL_meet $SimpleURL_meet_port

}

 

 

}

 

 

# ==============================================================================================

# Resolve and access Office WebApps URL

# ==============================================================================================

 

 

Write-Host "================================================================================================================"

Write-Host "TEST 3: Office WebApps server FQDN name resolution and access tests" -ForegroundColor yellow

Write-Host "================================================================================================================"

 

 

$LyncWacport = 443

 

 

If([string]::IsNullOrEmpty($LyncWac)) {

 

 Write-Host "Office WebApps URL is NULL. Bypassing Office WebApps services accessibility check"

 

}

 

 

else {

 

 

Write-Host "=> Attempting to resolve Office WebApps server fqdn ("$LyncWac" )"

if(ResolveLyncNames($LyncWac)) {

 

Write-Host "=> Attempting to connect to resolve Office WebApps server fqdn ("$LyncWac" ) at TCP port $LyncWacport"

TLSConnectionCheck $LyncWac $LyncWacport

}

 

 

 

# ==============================================================================================

# Resolve and access Lyncdiscover URL

# ==============================================================================================

 

Write-Host "================================================================================================================"

Write-Host "TEST 4: Lyncdiscover URL name resolution and access tests" -ForegroundColor yellow

Write-Host "================================================================================================================"

 

 

If([string]::IsNullOrEmpty($SimpleURl_lyncdiscover)) {

 

 Write-Host "Lyncdiscover URL is NULL. Bypassing Lyncdiscover URL accessibility check"

 

}

 

else {

 

 

$SimpleURL_lyncdiscover_port = 443

 

Write-Host "=> Attempting to resolve Admin URL ("$SimpleURl_lyncdiscover" )"

if(ResolveLyncNames($SimpleURl_lyncdiscover)) {

 

Write-Host "=> Attempting to connect to Admin URL ("$SimpleURl_lyncdiscover" ) at TCP port $SimpleURL_lyncdiscover_port"

TLSConnectionCheck $SimpleURl_lyncdiscover $SimpleURL_lyncdiscover_port

}

 

 

}

 

 

# ==============================================================================================

# Resolve and access Dialin URL

# ==============================================================================================

 

Write-Host "================================================================================================================"

Write-Host "TEST 5: Dialin URL name resolution and access tests" -ForegroundColor yellow

Write-Host "================================================================================================================"

 

 

If([string]::IsNullOrEmpty($SimpleURL_dialin)) {

 

 Write-Host "Dialin URL is NULL. Bypassing Dialin URL accessibility check"

 

}

 

else {

 

$SimpleURL_dialin_port = 443

 

 

Write-Host "=> Attempting to resolve Dialin URL ("$SimpleURL_dialin" )"

if(ResolveLyncNames($SimpleURL_dialin)) {

 

Write-Host "=> Attempting to connect to Dialin URL ("$SimpleURL_dialin" ) at TCP port $SimpleURL_dialin_port"

TLSConnectionCheck $SimpleURL_dialin $SimpleURL_dialin_port

}

 

}

 

 

#------------SCRIPT ENDS HERE-----------

=> You can also find a sample output below:

 

Hope this helps

 

Thanks,

Murat