Thursday, August 22, 2013
Microsoft Enables Remote Powershell for Lync Online
As announced by the Office 365 Team here, Microsoft finally enabled remote Powershell for Lync Online. Here is the link to Technet's Introduction to Lync Online Powershell Documentation which will give you information about how to connect, list available Powershell cmdlets, and other general information about the new feature. You can download the Powershell Module for Lync Online here and see the list of all Lync Online cmdlets here.
Thursday, August 1, 2013
Script to mass enable users for Exchange UM
During Lync deployments, I have often run into the need to mass enable multiple users for Unified Messaging. To do this, I altered an existing script (I cannot remember where I found it) to do this using a CSV file. Here is the script:
if ($args[0] -eq $null)
{
$userNameFile = read-host "Please enter the full path of the .csv file with user aliases."
$usernamefile = $usernamefile -replace '"',""
} else {
$usernamefile = $args[0]
}
if($userNameFile -ne "")
{
$csv=import-csv $userNameFile
} else {
"Unable to find a valid CSV with user Aliases, extensions and UM policy name. Please try again later."
exit
}
foreach($c in $csv )
{
"Enabling User " + $c.Alias + " using UM mailbox policy = " + $c.umpolicy
Enable-ummailbox -id $c.Alias -PinExpired $True -ummailboxpolicy $c.umpolicy -extensions $c.extension
}
The CSV file for this script will look like this:
The Alias column can contain any of the following values for the Identity parameter:
Let me know if you have any questions or comments about this script. Hope this helps.
if ($args[0] -eq $null)
{
$userNameFile = read-host "Please enter the full path of the .csv file with user aliases."
$usernamefile = $usernamefile -replace '"',""
} else {
$usernamefile = $args[0]
}
if($userNameFile -ne "")
{
$csv=import-csv $userNameFile
} else {
"Unable to find a valid CSV with user Aliases, extensions and UM policy name. Please try again later."
exit
}
foreach($c in $csv )
{
"Enabling User " + $c.Alias + " using UM mailbox policy = " + $c.umpolicy
Enable-ummailbox -id $c.Alias -PinExpired $True -ummailboxpolicy $c.umpolicy -extensions $c.extension
}
The CSV file for this script will look like this:
Alias | extensions | umpolicy |
User1 | 1234 | Policy Name |
User2 | 1235 | Policy Name |
User3 | 1236 | Policy Name |
The Alias column can contain any of the following values for the Identity parameter:
- ADObjectID
- GUID
- Distinguished name (DN)
- Domain\Account
- user principal name (UPN)
- LegacyExchangeDN
- SmtpAddress
- Alias
Let me know if you have any questions or comments about this script. Hope this helps.
Friday, July 12, 2013
Lync 2013 Server Prerequisites on Server 2008 R2 SP1
The following Powershell cmdlets will install the system prerequisites for Server 2008 R2 SP1:
Import-Module ServerManager
Add-WindowsFeature RSAT-ADDS,desktop-experience,Web-Server,Web-Static-Content,Web-Default-Doc,Web-Scripting-Tools,Web-Windows-Auth,Web-Asp-Net,Web-Log-Libraries,Web-Http-Tracing,Web-Stat-Compression,Web-Dyn-Compression,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Http-Errors,Web-Http-Logging,Web-Net-Ext,Web-Client-Auth,Web-Filtering,Web-Mgmt-Console,msmq-server,msmq-directory,Telnet-Client
Then download and install the following:
.NET 4.5 Framework (install this before Powershell 3.0) - http://www.microsoft.com/en-us/download/details.aspx?id=30653
Powershell 3.0 - http://www.microsoft.com/en-us/download/details.aspx?id=34595
Windows Identity Foundation - http://www.microsoft.com/en-us/download/details.aspx?id=17331
Windows Update (heap corruption in IIS 7.5) - http://support.microsoft.com/?kbid=2646886
I have not had a chance yet to test this yet as I only installed Lync 2013 on Server 2008 R2 SP1 last year. If there is anything missing or it errors out, please let me know.I will remove this statement once I get a chance to test this. *Update - I have run this script during a recent Lync 2013 deployment for a client and it is valid.
Import-Module ServerManager
Add-WindowsFeature RSAT-ADDS,desktop-experience,Web-Server,Web-Static-Content,Web-Default-Doc,Web-Scripting-Tools,Web-Windows-Auth,Web-Asp-Net,Web-Log-Libraries,Web-Http-Tracing,Web-Stat-Compression,Web-Dyn-Compression,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Http-Errors,Web-Http-Logging,Web-Net-Ext,Web-Client-Auth,Web-Filtering,Web-Mgmt-Console,msmq-server,msmq-directory,Telnet-Client
.NET 4.5 Framework (install this before Powershell 3.0) - http://www.microsoft.com/en-us/download/details.aspx?id=30653
Powershell 3.0 - http://www.microsoft.com/en-us/download/details.aspx?id=34595
Windows Identity Foundation - http://www.microsoft.com/en-us/download/details.aspx?id=17331
Windows Update (heap corruption in IIS 7.5) - http://support.microsoft.com/?kbid=2646886
I have not had a chance yet to test this yet as I only installed Lync 2013 on Server 2008 R2 SP1 last year. If there is anything missing or it errors out, please let me know.
Wednesday, May 29, 2013
Lync 2013 replication issue with the Edge server installed on Windows Server 2012
On a recent Lync 2013 deployment to migrate from Lync 2010, I ran into an issue with the Lync 2013 Management Store Replication not working on the Edge servers that were installed on Windows 2012 OS (all the servers in the Lync 2013 deployment were on 2012). I notice the red X's on replication on the Lync Control Panel and I ran the PowerShell cmdlet Get-CsManagementStoreReplicationStatus showing UpToDate as False, LastStatusReport blank and ProductVersion blank for both Lync 2013 Edge servers.
The event logs on the Lync 2010 Front Ends, Lync 2013 Front Ends and Lync 2013 Edge servers didn't show any errors or warnings stating that replication was failing. I checked all the usual suspects:
The event logs on the Lync 2010 Front Ends, Lync 2013 Front Ends and Lync 2013 Edge servers didn't show any errors or warnings stating that replication was failing. I checked all the usual suspects:
- Certificate issues
- I looked and verified the internal certificate had the proper Subject Name
- Verified the internal root CA certificate was in the proper location
- Verified that certificate checks based on the Microsoft KB article Lync Server 2013 Front-End service cannot start in Windows Server 2012 http://support.microsoft.com/kb/2795828 was not the case
- Verified I could telnet to the Edge servers from the Front Ends over port 4443
- Verified DNS was correct
- Verified the computer name on the Edge servers were correct with the proper primary DNS suffix entered
- Performed a WireShark trace on the Edge server and verified that there were connections to the server over port 4443
...and finally performed an comprehensive web search about this issue with no luck.
I spent enough time on this issue and decided to enroll the help of a very knowledgeable coworker named James Denavit (who happens to be a Lync 2010 MCM) before I throw in the towel and call Microsoft Support.
Luckily for me, James had the great idea of running the Lync Logging Tool from one of the Lync 2010 Front End servers. We ran it on the 2010 Front End because I did not move the CMS to the Lync 2013 yet. So we ran logging with the following options:
After running the Invoke-CsManagementStoreReplication PowerShell cmdlet from the Lync 2010 Front End server a couple times. I stopped the Logging tool and analyzed them. What we found were the following warnings:
One of the red flags we saw was:
TL_WARN(TF_COMPONENT) [2]0560.2E58::05/24/2013-20:25:24.920.4d11ccab (XDS_File_Transfer_Agent,FileTransferTask.CopyFilesFromReplicaUsingWcf:filetransfertask.cs(644))
(0000000002D2AF4D)[FileTransferTask(7, 5/24/2013 1:21:30 PM): {TASK_NOT_STARTED, fromReplica, [L13EdgeServerFQDN, HttpsWebService, 4443], 0}] Failed to copy files from replica. Exception: [System.ServiceModel.EndpointNotFoundException: Could not connect to https://L13EdgeServerFQDN:4443/ReplicationWebService. TCP error code 10061: No connection could be made because the target machine actively refused it 10.61.1.204:4443. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 10.61.1.204:4443
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
James did a search based on this and found the following post from The Lync Guy Blog:
I did find this blog post during my web search but lucky for me, James read the responses (which obviously I didn't) and pointed out the response from Jonatan talking about adding the registry entry: DWord value SendTrustedIssuerList to the HKey_Local_Machine\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL key and assigning it a value of 0.
After modifying the registry, I rebooted the Edge server and ran the Invoke-CsManagementStoreReplication PowerShell cmdlet from the Lync 2010 Front End server a couple times again and still no luck. I then proceeded to read more of the responses and the last response from Chris Duva stated that he added another registry entry.
I added the registry entry DWord value ClientAuthTrustMode to the HKey_Local_Machine\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL key and assigning it a value of 2. I rebooted the Edge server again and ran the Invoke cmdlet again and voila!!! It worked.
Since I had 2 Lync 2013 Edge servers, I just wanted to verify that only the ClientAuthTrustMode registry entry was needed so I added only that entry to the second Edge server and rebooted it and it worked! So I removed the registry entry for SendTrustedIssuerList from the first Edge server, rebooted it and verified that the replication still worked.
Thanks to James for helping me with this issue as well as answering questions whenever I have them.
Hope this helps.
Thursday, March 28, 2013
Lync PowerShell Script to Mass Enable Users
* Updated 1/22/15 - I added the option to add dial plan and voice policy as well to the script
* Updated 6/20/13 - I forgot to add the dash in set-csuser on the bottom script so the enable-csuser cmdlet would fail.
Of course there is always a need to mass enable users for Lync once you have Lync deployed in your environment. The easiest way to mass enable users for Lync is via a PowerShell script and a CSV file with the user information.
To enable PC-to-PC users only
Here is a script I created to mass enable users:
if ($args[0] -eq $null)
{
$userNameFile = read-host "Enter the full path of the .csv file with the user information."
$userNameFile = $usernamefile -replace '"',""}
else
{$usernamefile = $args[0]}
if ($userNameFile -ne "")
{$csv=import-csv $userNameFile}
else
{"Could not find a valid .csv with the user information."
exit}
foreach($c in $csv)
# enable for lync
{
"Enabling " + $c.Identity + " for Lync 2010"
Enable-csuser -identity $c.Identity -registrarpool $c.RegistrarPool –sipaddresstype $c.SipAddressType -sipdomain $c.SipDomain
}
This script will enable the users with basic PC-to-PC configuration. This script allows for organizations with multiple SIP domains and multiple pools with the columns in the .csv file for RegistrarPool and SipDomain. The .csv file will look like this:
To enable Enterprise Voice users
To enable the users for Enterprise Voice, we will make the following addition (highlighted in yellow and green) to the above script. The green highlighted section is optional if you have extensions set up in your LineURI’s like tel+12815551234;ext=1234. You can omit this section and remove the Extensions column from the .csv file if you are not using extensions in your LineURI’s:
if ($args[0] -eq $null)
{
$userNameFile = read-host "Enter the full path of the .csv file with the user information."
$userNameFile = $usernamefile -replace '"',""}
else
{$usernamefile = $args[0]}
if ($userNameFile -ne "")
{$csv=import-csv $userNameFile}
else
{"Could not find a valid .csv with the user information."
exit}
foreach($c in $csv)
# enable for lync
{
"Enabling " + $c.Identity + " for Lync"
$lineuri = "tel:+1" + $c.PhoneNumber + ";ext=" + $c.Extension
Enable-csuser -identity $c.Identity -registrarpool $c.RegistrarPool -sipaddresstype $c.SipAddressType -sipdomain $c.SipDomain
# Pause for 30 seconds for AD Replication
write-host -foregroundcolor Green "Pausing for 30 seconds for AD Replication"
Start-Sleep -s 30
Set-CsUser -Identity $c.Identity -enterprisevoiceenabled $True -lineuri $lineuri
Grant-CsDialPlan -Identity $c.Identity -PolicyName $c.DialPlan
Grant-CsVoicePolicy -Identity $c.Identity -PolicyName $c.VoicePolicy
}
As you can see, the script turns the 10 digit phone number into E.164 format and adds the extension (if needed) and then sets it as the LineURI for the user. The .csv file will have the following columns added for this script:
* Updated 6/20/13 - I forgot to add the dash in set-csuser on the bottom script so the enable-csuser cmdlet would fail.
Of course there is always a need to mass enable users for Lync once you have Lync deployed in your environment. The easiest way to mass enable users for Lync is via a PowerShell script and a CSV file with the user information.
To enable PC-to-PC users only
Here is a script I created to mass enable users:
if ($args[0] -eq $null)
{
$userNameFile = read-host "Enter the full path of the .csv file with the user information."
$userNameFile = $usernamefile -replace '"',""}
else
{$usernamefile = $args[0]}
if ($userNameFile -ne "")
{$csv=import-csv $userNameFile}
else
{"Could not find a valid .csv with the user information."
exit}
foreach($c in $csv)
# enable for lync
{
"Enabling " + $c.Identity + " for Lync 2010"
Enable-csuser -identity $c.Identity -registrarpool $c.RegistrarPool –sipaddresstype $c.SipAddressType -sipdomain $c.SipDomain
}
This script will enable the users with basic PC-to-PC configuration. This script allows for organizations with multiple SIP domains and multiple pools with the columns in the .csv file for RegistrarPool and SipDomain. The .csv file will look like this:
Identity | RegistrarPool | SipAddressType | SipDomain |
John Doe | PoolFQDN.Domain.com | EmailAddress | SIPDomain.com |
To enable Enterprise Voice users
To enable the users for Enterprise Voice, we will make the following addition (highlighted in yellow and green) to the above script. The green highlighted section is optional if you have extensions set up in your LineURI’s like tel+12815551234;ext=1234. You can omit this section and remove the Extensions column from the .csv file if you are not using extensions in your LineURI’s:
if ($args[0] -eq $null)
{
$userNameFile = read-host "Enter the full path of the .csv file with the user information."
$userNameFile = $usernamefile -replace '"',""}
else
{$usernamefile = $args[0]}
if ($userNameFile -ne "")
{$csv=import-csv $userNameFile}
else
{"Could not find a valid .csv with the user information."
exit}
foreach($c in $csv)
# enable for lync
{
"Enabling " + $c.Identity + " for Lync"
$lineuri = "tel:+1" + $c.PhoneNumber + ";ext=" + $c.Extension
Enable-csuser -identity $c.Identity -registrarpool $c.RegistrarPool -sipaddresstype $c.SipAddressType -sipdomain $c.SipDomain
# Pause for 30 seconds for AD Replication
write-host -foregroundcolor Green "Pausing for 30 seconds for AD Replication"
Start-Sleep -s 30
Set-CsUser -Identity $c.Identity -enterprisevoiceenabled $True -lineuri $lineuri
Grant-CsDialPlan -Identity $c.Identity -PolicyName $c.DialPlan
Grant-CsVoicePolicy -Identity $c.Identity -PolicyName $c.VoicePolicy
}
As you can see, the script turns the 10 digit phone number into E.164 format and adds the extension (if needed) and then sets it as the LineURI for the user. The .csv file will have the following columns added for this script:
PhoneNumber | Extension | DialPlan | VoicePolicy |
2815551234 | 1234 | HoustonDialPlan | HoustonVoicePolicy |
PowerShell Script to Create a User, Mailbox Enable the Account, and Enable the Account for Lync
I have created a handy script that will create a user account, mailbox enable the account, enable the account for Lync, enable the Lync account for Enterprise Voice, and finally UM enable the account from a local computer without having to log onto the Exchange or Lync servers. This script basically creates the user account creating the Display Name as FirstName Last Name, UPN as FirstInitialLastName@InternalDomain, Alias as FirstInitial.LastName, SIP URI as the same as the e-mail address, and sets the LineURI in the format of tel:+13335551234;ext=1234.
This script is pieced together from other scripts I had so it may not be the most efficient. I will do some more testing and update the script once I get it optimized as well as creating one that will allow you to use a .csv file to mass enable users.
# Enable for lync and configure settings
"Enabling " + $fname + " " + $lname + " for Lync 2010"
$lineuri = "tel:+1" + $phone + ";ext=" + $ext
Get-mailbox -identity $name | Enable-csuser -registrarpool $Registrar -sipaddresstype EmailAddress -sipdomain $sipdomain -enterprisevoiceenabled $True -lineuri $lineuri
# Static Entries
$ExchangeServer = "ExchangeServer.domain.com"
$LyncServer = "LyncServer.domain.com"
$Registrar = "LyncServer.domain.com"
$dialplan = "Registrar:LyncServer.domain.com"
$intdomain = "domain.com"
$sipdomain = "SIPDomain.com"
$company = "Company Name"
$mbdb = "Mailbox Database Name"
$umpolicy = "Unified Messaging Policy Name"
# Import session information
$user = Get-Credential
$ExchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://$ExchangeServer/powershell -Credential $user
Import-PSSession $ExchSession
$LyncSession = New-PSSession -ConnectionURI https://$LyncServer/ocspowershell -Credential $user
Import-PSSession $LyncSession
# Data Entry section
$fname = Read-Host "First Name"
$finit = Read-Host "First Initial"
$lname = Read-Host "Last Name"
$password = Read-Host "Password"
$ou = Read-Host "AD OU account will be created in. In the format of OU=OUname,DC=Domain,DC=com"
$desc = Read-Host "Description"
$dept = Read-Host "Department"
$title = Read-Host "Title"
$manager = Read-Host "Manager"
$phone = Read-Host "Phone Number"
$ext = Read-Host "4 Digit Extension"
# Create user and enable mailbox
"Creating and enabling " + $fname + " " + $lname + " for AD and Exchange 2010"
$pwd = convertto-securestring $password -asplaintext -force
$name = $fname + " " + $lname
$upn = $finit + $lname + "@" + $intdomain
$alias = $finit + "." + $lname
$sam = $finit + $lname
New-Mailbox -name $name -userprincipalname $upn -Alias $alias -OrganizationalUnit $ou -SamAccountName $sam -FirstName $fname -Initials '' -LastName $lname -Password $pwd -ResetPasswordOnNextLogon $true -Database $mbdb
# Pause for 30 seconds for AD
write-host "Pausing for 30 seconds for AD Changes"
Start-Sleep -s 30
# Set user properties
"Configuring AD settings for " + $fname + " " + $lname
Get-Mailbox -identity $name | Set-User -Company $company -Department $dept -Title $title -Manager $manager -Phone $phone
# Pause 10 for AD changes
write-host "Pausing 10 Seconds for AD Changes"
Start-Sleep -s 10
# Enable for lync and configure settings
"Enabling " + $fname + " " + $lname + " for Lync 2010"
$lineuri = "tel:+1" + $phone + ";ext=" + $ext
Get-mailbox -identity $name | Enable-csuser -registrarpool $Registrar -sipaddresstype EmailAddress -sipdomain $sipdomain -enterprisevoiceenabled $True -lineuri $lineuri
# Pause 10 for Lync changes
write-host "Pausing 10 Seconds for Lync Changes"
Start-Sleep -s 10
# Enable For Unified Messaging
"Configuring " + $fname + " " + $lname + " for Unified Messaging"
$sipuri = $fname + "." + $lname + "@" + $sipdomain
Get-Mailbox -identity $name | Enable-UMMailbox -PinExpired $true -UMMailboxPolicy $umpolicy -Extensions $ext -SIPResourceIdentifier $sipuri
I will walk you thru what this script does...
The first commented area (# Static Entries) will be the entries that will be consistent thru the account creation and configuration process. The $ExchangeServer and $LyncServer variables are the servers that you are going to be connecting to via the PowerShell remote connections. The $intdomain and $sipdomain variables are in case your internal domain is different than your SIP domain.
The second commented area (# Import session information) is where it allows you to run this script from your computer instead of logging into the Exchange or Lync servers.
The third commented area (# Data Entry section) is where you will manually type in the requested information. Be careful with your entries because you will have to go back and manually fix anything that may be misspelled after the script has run.
The fourth commented area (# Create user and enable mailbox) is where it will create the user account and enable the mailbox.
The pauses in the script are to allow ample time for AD to replicate prior to making the additional changes. Depending on how large your AD environment is, you may need to add more time to the pauses to allow for AD replication to occur.
If you have any questions or need the script customized, let me know.
I will update the post later with a script that will use a .csv file to mass enable users and allow you to assign them to different MBX databases, Lync pools, Policies, etc.
Use the script at your own risk. There might be typos in the script so test first before running it in production.
Monday, March 25, 2013
Install Lync 2013 Prerequisites on Windows Server 2012 Using PowerShell
Install-WindowsFeature RSAT-ADDS,Web-Server,Web-Static-Content,Web-Default-Doc,Web-Http-Errors,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor,Web-Http-Tracing,Web-Basic-Auth,Web-Windows-Auth,Web-Client-Auth,Web-Filtering,Web-Stat-Compression,Web-Dyn-Compression,NET-WCF-HTTP-Activation45,Web-Asp-Net45,Web-Mgmt-Tools,Web-Scripting-Tools,Web-Mgmt-Compat,NET-Framework-Core,NET-HTTP-Activation,Desktop-Experience,Windows-Identity-Foundation,Telnet-Client,BITS -Source D:\sources\sxs
For those of you wondering, the Telnet Client is not required but helps with troubleshooting in case you need it. An example of this would be testing connectivity to your Edge server. You can do this by opening the command prompt and typing in telnet EdgeServerFQDN 5061. This will verify that you can connect to the Edge server over port 5061.
Thursday, March 21, 2013
Disabling SSLv2 on Lync Edge Server is OK
On a recent Lync deployment at a client site, it was brought to my attention from the security team that SSLv2 was enabled on the Edge Server. I have never heard of this being a vulnerability but then again I am not a security expert. So looking into it and knowing that the Lync 2010 Edge server does not use SSL for any communications (it uses TLS and MTLS), we disabled SSLv2 following the instructions on this link. Then ran this cool online tool to test if the server has SSLv2 enabled by entering in the FQDN of the Access Edge server showing in green letters that the test passed and SSLv2 was disabled on the Access Edge server. The security expert also ran his tests on the server and verified that SSLv2 was disabled. We performed a full battery of Lync functionality testing involving the Edge server and it still worked without any issues.
Friday, March 15, 2013
Lync 2013 Mobile Client out for iPhone, iPad, and Windows Phone
As you may have seen already, the Lync 2013 mobile client is out for Windows Phone, iPhone, and iPad.
You will need to install the February Cumulative Update 1 for Lync 2013 (download and install instructions can be found here) in order for the mobile clients to connect to your deployment.
I was able to connect to my Office 365 seamlessly with the new client on my iPhone 5. I am in the process of rebuilding my new lab so I have not had a change to test it with a on-prem deployment with enterprise voice.
A great FAQ on the new mobile client can be found on the NextHop Blog located here.
Thursday, January 3, 2013
Lync 2013 installation errors out when you run Forest Prep during coexistence with Lync 2010
After clicking Next and it came up with the following error:
After clicking Next, it completed without errors.
Hope this helps.
Wednesday, January 2, 2013
Search for specific EUM extensions with Exchange Powershell and EMC
Trying to find extensions that are already assigned to someone in Exchange Unified Messaging can be frustrating if you have never done it before. The easiest way to do it is to perform a search in Mailboxes in the EMC and enter in eum:1234 in the search field.
Another way to do it for the Powershell users is to use this:
Get-mailbox | ?
{$_.emailaddresses.eumaddress -like "*1234*"}
Subscribe to:
Posts (Atom)