Joined The Mother Ship

VMware Heaven!

To all those interested, I am excited to say that I’ve been recently recruited by VMware to work as a Technical Support Engineer for the Business Critical Support team in VMware’s Broomfield office.

This is amazing news for me and my readers for many reasons: new information, new knowledge, new resources, and new issues. All of these mean that this blog will hopefully be picking up in production and provide more inside looking into VMware’s virtualization products.

I will continue to provide solutions and issue resolution on various technologies, but now with a more solid VMware focus. In working with the cases that I anticipate to be facing with some of our more high-profile customers, I will be taking careful note for tips and tricks as well as streamlined or custom approaches to resolving and preventing issues.

This is an exciting time for me and I hope that my readers will continue to benefit from the knowledge that I will continue to share here.

Keep checking in for more Virtualization Goodness!




Nuance Dragon – Dictaphone PowerMic II Suddenly Not Working in Windows 7


I currently manage Dragon Medical 10 Network Edition in our VMWare View VDI for about 85 dictating physicians. In this deployment, we use a combination of the Dictaphone-branded and Nuance-branded PowerMic II devices. These have worked great from day one, and we haven’t had many issues aside from getting around the “Audio Levels Wizard” that pops up in certain situations.

Recently, we have been planning and testing an upgrade of the DMNE client to an updated service pack in preparation for the update to version 12. During the testing phase, however, we found that somewhere along the process, the PowerMic II devices began malfunctioning. The observed behavior was reproducible and seemed to affect a large majority of the devices that we have in the field, so a major issue to say the least.

After debugging and investigating the on the machine, I was able to determine that there were changes to the native USB and USB Audio drivers on the system. In moving backwards, I found that some Microsoft Windows security updates have been released that update kernel drivers on the system in order to resolve a reported vulnerability. The negative result of these updates is that it essentially breaks a large majority of our current dictation microphones, the Dictaphone PowerMic II.

The Issue

The behavior of the issue is seen in two cases. Let’s consider the two following situations:

Situation 1

  1. PowerMic II devices are all pre-installed on the VDI base image
  2. A user plugs in a PowerMic II and the device is detected
  3. The device is unplugged and plugged back in, or a user roams
  4. The device may briefly be detected in Device Manager, but then disappears
  5. The device may not be detected at all

Situation 2

  1. PowerMic II devices are not installed on the base image
  2. A user plugs in a PowerMic II, the device is detected and installed
  3. The device then immediately disappears from Device Manager after installing
  4. After disconnecting and reconnecting the device or roaming, it disappears from the system


The reason for this breaking is because of the following Microsoft security updates. Microsoft has released updated USB drivers which will cause the older PowerMic II devices to not work. These updates, and information about the patches, can be found in the following security bulletins:

  1. MS13-081
  2. MS13-101
  3. MS14-015

To avoid or fix this problem, either uninstall or hide the following updates from your Windows 7 client:

  1. KB2847311
  2. KB2855844
  3. KB2862330
  4. KB2862335
  5. KB2863725
  6. KB2864202
  7. KB2868038
  8. KB2884256
  9. KB2883150
  10. KB2876284
  11. KB2887069
  12. KB2930275

The affected drivers from these releases are found in the following locations:

USB Audio





There may be additional changes in these patches, but it is a larger issue to decommission half of our devices at once with a single set of updates. Be sure to read through the security bulletins to decide what’s best for you.

Let me know if you have any questions or comments!


Link App-V Packages to “C:\Program Files” Directory


In working with sequencing different App-V 5 applications, I’ve found there can be requirements for binaries to exist at absolute paths in C:\Program Files.

This is somewhat problematic because, from what I can find, there is no built-in or easy way to deliver packages to their originally named, and absolute location on a system. No worries, though. We can use some custom scripting to help us out along with the help of System Center Configuration Manager 2012 R2.


The application that I was working with when I encountered the issue, Meditech Client Server, gave me an error stating that the program was “Not installed in the correct location under C:\Program Files“.

In researching, there wasn’t much info in the way of placing App-V packages into their original location. It always goes somewhere under the App-V folder using the Package ID and Version ID of the published application.

I decided that a symlink could possibly work for this situation since the app seemed to run fine and only complained about the file location. I created a new symlink in C:\Program Files\ with the following command from a PowerShell terminal:

mklink /J "C:\Program Files\APPLICATION_DIRECTORY" C:\ProgramData\App-V\*Package_ID*\*Package_Version*\root

Sure enough mapping the directory as a Windows junction allowed the application to run without issue.

If this application was going to work as an App-V package, an automated way to perform this symlink creation would need to be implemented so that the user would have a working App-V delivery without any additional wait or hassle.

Package Scripts, not

My first attempt at resolution was to use Package Scripts to configure the changes from within the application deployment. It was a logical solution.

The problem here is that the Machine and User Package Event tags don’t provide good timing in making the customization change. The way to make a symlink to an App-V package is by using both the Package and Version IDs, so we need for a script to run after the package has been published in order to use the get-appvclientpackage cmdlet to discover the parameters for mapping.

After playing with the different Event Tags I found that they either initiated too early, before get-appvclientpackage would return any information, or at first run of the App-V application which would cause the associated shortcuts to fail.

Script Installer

To work around this I set up a new Script Installer in SCCM 2012 and created a PowerShell script to perform the symlink creation. This allows us to config the junctions immediately after the application dependencies are met by linking the two in SCCM.

We can then configure Start Menu shortcuts pointing to “C:\Program Files\” during sequencing the App-V 5 applications, or by editing the DeploymentConfig.xml after sequencing. This allows users to launch App-V applications from shortcuts pointing to original absolute paths which will fulfill any path requirements that are hard-coded into the binaries.


As mentioned above, the components of this implementation are:

  1. An App-V 5 Application w/ Absolute Path Requirements
  2. Symlink Creation Script
  3. SCCM 2012 R2 Script Installer Application
  4. New App-V Package Shortcuts (if needed)

Let’s start with the script since we’re assuming you already have your application sequenced and added to SCCM.

We’ll then move on to setting the absolute path shortcuts in your DeploymentConfig.xml file after discussing the creation of the Script Installer application in SCCM.

Please note: Don’t distribute the content of your package in SCCM until you’ve made the changes to the shortcuts or you’ll have to redistribute. You can add the package in order to assign the dependency of the Script Installer, but don’t distribute or deploy. Updating shortcuts is in the last section of this guide.

The Script

This PoSH script takes the “Name” of your application, returned in the results of the get-appvclientpackage cmdlet, and the name of your the Program Files folder that we’re creating for the application.

As always, portions to modify in this script are in BOLD & ITALICS:

#  Scriptname: mapPackage.ps1
#  Description: This script will map a specified App-V
#               appliaction to "C:\Program Files\"
#  By:          Adam Baldwin
#  Usage:       Define the value for your package name and
#               for the destination folder name under "C:\Program Files\".
#               This script assumes you are using the default installation
#               source for App-V in "C:\ProgramData\App-V"

# Define the package name to search from present packages

# Define the name of the folder under "C:\Program Files" to
# map the application

# Set the Package object to a string
$package = get-appvclientpackage | where {$_.Name -eq $name}

# Get the Package ID and Version ID
$id = $package.packageID.ToString()
$vid = $package.versionID.ToString()

# Create the symlink mapping command
$cmd = "mklink /J `"C:\Program Files\$pathName`" `"C:\ProgramData\App-V\$id\$vid\root`""

# Run the symlink mapping command
cmd /c $cmd

Put this script into your  application repository. I keep all of my App-V applications, software installers, and script installers in a central place in order to reference and add them to SCCM easily. You can also put this, or any other scripts for Script Installers, on your domain’s netlogon volume. We’ll be using this location in the example below.

Setting up the Script Installer

Now it’s time to configure the Script Installer with the PoSH script that we created above. Be sure that you have your parent App-V application added to SCCM, first, before you create the Script Installer.

In SCCM, navigate to Software Library> Application Management> Applications. 

Right-click and select Create Application.

Check the radio button for Manually specify the application information and click Next

New Manual Application

On the General page, fill in the identifying information for this installer.

Since the function is to set up a specific configuration for an app, in this case to map a symlink to C:\Program Files\, give it some clear descriptions to indicate this behavior.

New Manual General

Click Next and select an Icon and set Categories if you’d like.

On the Deployment Types screen, click Add.

Add Deployment Type

Now you’ll be brought back to a screen that looks like the one we started with, except there is one additional option in the drop-down for Type. 

Click the drop-down and select Script Installer. Click Next to continue.

Script Installer


Again, give this installer a good name and description.

Script Installer General

Click Next to continue.

On the Content page, specify the Content location. If using a scripts folder on your netlogon volume, enter:


For the Installation Program, indicate PowerShell.exe with an -f switch pointing to the script created above.

Script Installer Content

Click Next to continue.

On the Detection page, Add a new Clause and specify a Folder for the Type.

Enter C:\Program Files\ for the Path field and enter your application’s folder name in the File or folder name field.

Script Installer Detection

Click OK to save and click Next on the Detection page to continue.

On the User Experience page, decide on your deployment settings. For this application, I’m deploying App-V apps to cloned machines, targeting device groups. In this situation, I’ve decided to use the following:

  1. Install for system if resource is device; otherwise install for user
  2. Whether or not user is logged on
  3. Hidden

Script Installer Experience

Click Next to continue. Click Next through the Requirements page.

On the Dependencies page, click Add and specify a name for the dependency group.

Click Add and browse to your parent application. Check the box and click OK to save.


Click OK again to save and click Next to continue to the Summary. 

Verify your settings and click Next to complete.

Update App-V Shortcuts

You can edit the DeploymentConfig.xml file either during sequencing or after. Below I will describe how to make the changes after sequencing.

Open up the folder containing your App-V application and right-click on XXX_DeploymentConfig.xml to Edit or Open With your favorite editor or IDE.

Search for “<shortcut>” and find the entry with the Name and Target of the shortcut you’d like to update.

Once you’ve found your shortcut object, change the value for <Target> to point to your Symlink that we created with the Script Installer. Be sure to put quotes around your path name.

My particular application that was not working was Meditech Client Server. So you can see in my screen shot below, I’ve changed the target for the shortcut to point to an absolute path in C:\Program Files\ rather than to the App-V directory. Once the application is published, the dependent Script Installer will run and make this path accessible and create a seemless experience for the user.

Deployment Config


Once this is set, Distribute the content of your App-V app and the Script Installer to your Distribution Point and Deploy to your liking.


App-V is a great platform for delivering applications, but some, especially legacy applications, can be problematic because of the way they were coded.

If you find any applications that require absolute paths to the binaries, this method is the solution for you.

Let me know if you have any questions or comments below!



Deploying App-V to VMWare View Floating Pools using SCCM 2012 R2

Custom App-V Applications Installed and Ready on a View Linked Clone Pool?

This week I successfully designed and deployed a method for on-the-fly delivery of applications to VMWare View floating VMs using Microsoft’s App-V and SCCM 2012 R2. I wanted to achieve this in order to leverage the administrative capabilities of App-V while allowing the user experience to be enhanced by the upgradeable and customizable nature of the platform.

My design involves using a System Center Configuration Manager 2012 R2 server to deliver App-V 5.0 applications to targeted VMWare View pool device collections. This is in order to stage cloned machines, on-the-fly, and with specific group-based applications rather than deploying forked clones or one monolithic clone to each pool. The architecture allows for floating clones to immediately request a compliant  state as soon as the VM is finished cloning, using some special scripting.

The end result is a fully presentable, floating VM that is prepped and ready with all assigned applications available to a user at login.


I haven’t found very much information in regards to setting up SCCM 2012 to do what we’re talking about here, but luckily the system is extensible and can be customized with just about any query that you can come up with. The problem is that SCCM wasn’t really designed to do what I wanted it to do.

The polling intervals, even at their most frequent, were too slow to get a discovered machine into a collection and push out all of the published apps all before a user grabs the desktop. There is just no built-in way to initiate a client check or software push, you have to wait for your configured schedules to pass or the schedule on the client in order for a health check to occur and for missing applications to be sent. I never let things like that stop me, though. I pulled up my bootstraps and went digging through logs, WMI, and process traces. After exhausting my resources and subjecting myself to hours of pouring through the different CCM namespaces and instances in the client and server WMI, I finally found some methods and queries to help accomplish my goal.

Because there isn’t much information on what we’re about to do here, and because it’s a somewhat non-standard architecture, I recommend performing a little extra development and stress testing to get a sense of how your network will handle the application deployment process. I’ve tested this deployment in a pool of machines that clone 10 at a time without any reaching any sort of limit on our 10GbE back-end network.

In the end this deployment can be used for group-limited or specialized apps that you need to deliver to only one set of users or many. In addition to locally installed applications on the base image, such as MS Office, and even ThinApp delivered applications using ThinReg, we can create a very customized and extensible experience for our users.

SCCM Configuration

There are a lot of great guides online for setting up SCCM 2012 R2. One in particular is this multi-part series on the forum. I highly recommend using this or another guide for installing and setting up the initial configurations for your SCCM 2012 R2 system. If you use the guide linked above, follow it until Part 3 and stop. We’ll be configuring our Discovery Methods and everything else from this point on. If you use another guide, just get to the point where you have your initial site configured and all of your base roles installed.

The primary focus of our SCCM configuration will be in the discovery, client polling settings, application deployment settings, collection queries, as well as many other areas. We’ll also be assigning some scripts to the server and master clone image as well as to VMWare’s QuickPrep post-sync script assignment.

The CCM client also has to be installed in a particular way on a VMWare View master image in order for it to properly register with SCCM.

The idea is to have three collections of computers, one for Active and one for Inactive, and one for Non-Client machines. The active collection should be targeted towards the View pool OU where you’d like to deliver the applications, while the other two will help in management and keeping our deployment clean. We’ll want polling for discovery of systems and members of collections to happen very frequently in order to discover new machines as they’re being cloned. We will then have to customize our base image with a scheduled task and script in order for the policy request to happen, immediately, without waiting for the polling interval.

If you have your SCCM 2012 R2 server in place and have not yet configured it with any discovery or boundary settings, then we’re ready to begin.

Step 1 – Configuring Application Web Services

From a standard deployment, without any further configuration past install and site setup, we’ll require these two additional roles:

  1. Application Catalog Web Service Point
  2. Application Catalog Web Site Point

To add these roles, navigate to Administration> Site Configuration> Servers and Site System Role, right-click on the server that you want as your distribution point and select Add Site System Roles.

Add site role

Click Next through the General and Proxy pages to accept the defaults or enter your preferred values.

At the Role Selection screen choose the Application Catalog Web Service Point and Application Catalog Web Site Point and click Next.

Role Selection

In this example we won’t be using a certificate, only the default HTTP on port 80, but if you’d like to add a certificate and configure HTTPS please do so now.

Leave the IIS website and Web application name as the default and click Next to continue.

Web Services Point


Once at the Application Catalog Customization screen select a custom title to display on your Application Catalog web page. The color you select here will set the theme of the Application Catalog website only, not the Software Center.

Catalog Customization

After setting the name, click Next to add the roles and Close to finish.

To verify successful web services installation, use CMTrace to check C:\Program Files\Microsoft Configuration Manager\Logs\awebsvcMSI.log. Search for the message “installation operation completed successfully“.

Install Success

To verify that application web services are running and online, check C:\Program Files\Microsoft Configuration Manager\Logs\awebsctl.log for the message “previous state was 0” which indicates an Online status.

Previous State was Online

Step 2 – Configuring Discovery

The Discovery Methods I’ve chosen are only Active Directory User Discovery and Heartbeat Discovery. Navigate to Administration> Hierarchy Configuration> Discovery Methods. 

We will be enabling only the following Discovery methods:

  1. Active Directory User Discovery
  2. Heartbeat Discovery



If you enable Active Directory Forest Discovery in hopes of automatically setting boundaries you might find that every object in your forest has been replicated to the SCCM server. This is unnecessary bloat that can be avoided by not enabling Forest Discovery.

Right-click Active Directory System Discovery and select Properties. Click the star icon to create a new Target OU and select the container holding the users for your View environment.

User Discovery

Click OK to save and close.

Right-click and configure the Heartbeat Discovery to collect client data every 1 hour.



Step 3 – Configure Boundaries and Boundary Groups

To configure Boundaries and Boundary Groups without Forest Discovery turned on is no problem.

Navigate to Administration> Hierarchy Configuration> Boundaries. Right-click and select Create Boundary. In the Type dropdown select Active Directory site.

Click Browse to view your AD sites and choose the one for this boundary. Click OK to save and close. If you have multiple AD sites, repeat the process.

AD Site Boundary

Boundary Group

Once the Boundary is set up, right-click on the Boundary Groups node on the Navigation pane and select Create Boundary Group.

Give this a general name and add all of your targeted boundaries.

Boundary Group

Click OK to save and close.

We’ll be using this Boundary Group to associate with the Distribution Point that clients will be streaming the App-V packages from.

Step 4 – Configure Distribution Point

A default Distribution Point should have been installed with the initial site installation. If you want to configure a separate DP, add the new CM server, role, and configure it with the settings below.

Navigate to Administration> Site Configuration> Distribution Points and right-click the DP server. Select Properties.

We want to enable the following few settings:

  1. On the General tab check Enable and configure BranchCache for this distribution point.
  2. On the Boundary Groups tab add the boundary created in Step 3 above

Step 5 – Configuring Device Settings

In order to adjust some of our client polling schedule and agent settings, we must create a custom Device Setting.

To do so, Navigate to Administration> Client Settings. Right-click and select Create Custom Client Device Settings.

Create Client Settings

Give the new Device Setting template a descriptive name and check the boxes for:

  1. Client Policy
  2. Computer Agent Policy
  3. Software Deployment
  4. State Messaging

Device Settings

We’re setting high frequency polling intervals, against all recommendations, for the policy and client checks. This is in order to maintain communication so that we can more accurately age and decommission deleted linked clones.

On the Client Policy tab set the polling interval to 3 Minutes.

Client Polling


On Computer Agent, click Set Website and select your default catalog website that we configured in Step 1. 

Catalog Website

Still in Computer Agent, set an Organization name to be displayed in the Software Center, much like the “Organization Name” on the Application Catalog webpage.

Organization Name

Name displayed in Software Center

On the Software Deployment tab set the schedule to every 5 minutes.

Software Deployment

On the State Messaging tab, set the State message reporting cycle to 1 minute.

State Message

Click OK to save and continue.

Step 6 – Configuring Collections

Now that we have the Server Roles and Discovery squared away, we can focus on our Device Collections.

Collection Issues

I first wanted to talk a little about the issues I had to overcome in order to get my collections working how I wanted.

SCCM is a great tool because it allows for customizable queries based on pretty much any WQL command you can think of and has a number of built in queries available to use. You can also use Powershell, VBS, and check registry keys for queries. These are great features! However the built in aging and deletion policies just couldn’t keep up with the churn of a floating desktop pool where machines are constantly being created with the same name over and over again. The built-in tools just couldn’t handle it.

To resolve this I engineered a set of scripts and tasks to either automatically re-register an inactive device or remove it from one of the two inactive collections.

There are three sets of collections that we need in order to handle our immediate discover and app distribution. We also need scheduled scripts to poll the inactive collections to delete or register them in a controlled way.

Collection One – The Easy Collection (Healthy VMs)

The first device collection will be for our healthy VMs that were discovered. This is a very simple collection and only requires a couple of queries depending on how many OUs you are targeting. Ideally, we should only be targeting one View pool per DP and per Application Collection in order to maintain a manageable load.

To create the first Collection go to Assets and Compliance> Device Collections. Right-click and Create Device Collection.

Give the collection a name like “App-V Pool VMs” or something for the application group. Click Browse and select the All Systems device collection as the Limiting collection.

Device Collection

Click Next.

Click the Add Rule dropdown and select Query Rule.

In the next prompt give the rule a name identifying it as an OU rule and click Edit Query Statement…

Create Query

Click on the Criteria tab and then click the little star button to create a new criteria.



Select System Resource as the Attribute Class and System OU Name for the Attribute.

Select is equal for the Operator and click the Value button to find and select your target OU.

OU Query

Click OK to continue and save. Repeat for any other target OUs in this deployment.

Once all of the queries are added check the box for Use incremental updates for this collection. 

Now click Schedule and set the Custom Interval for 1 minute.

Click Next to continue and create the collection.

Once the Device Collection has been created, navigate back to Administration> Client Settings and right-click the Custom Device Setting that you created in Step 5 and select Deploy.

Select your App-V Pool VMs and click OK to apply your device settings to the new device collection.

Deploy Client Settings

Collection Two – The Problem Child (Aged Device Records)

The second collection will be a collection of old VMs that have been replaced by new clones. We want our old device discoveries to be cleared out of our active collection in order to clear administrative clutter and and prevent possible issues.

This collection will be based on a custom query that I built after digging through the WMI to find a suitable value to represent an aged machine. I decided to use the Last Policy Request time because active clients maintain regular policy requests based on our configured polling schedule.

Create a new Device Collection and name it “Unresponsive Devices”. Select All Systems as the Limiting collection and click Next.

Create a new Query Rule like in the previous collection. Name the query “No Policy Check for 10 Minutes” and click Edit Query Statement…

On the General tab, click Show Query Language. Copy and paste the following custom query into the field and click OK to save.

Note: I’m a bit new to WQL queries, so if you have a suggestion on how to clean this up feel free to post a comment. This is not the most pretty statement I’ve ever written.

select SMS_G_System_CH_ClientSummary.LastPolicyRequest from SMS_R_System inner join SMS_G_System_CH_ClientSummary as s1 on s1.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_CH_ClientSummary on SMS_G_System_CH_ClientSummary.ResourceID = SMS_R_System.ResourceId WHERE dateDiff(mi, SMS_G_System_CH_ClientSummary.LastPolicyRequest, GetUTCDate()) > 10

Once you click OK you will be notified that the query has a syntax error. Just ignore this and click Yes to continue.
Syntax Error

Once the query is added check the box for Use incremental updates for this collection.

Click Schedule and set the Custom Interval for 2 minutes.

Click Next to continue and create the collection.

Add Collection Exclusion to Active Devices

Now we need to exclude the Unresponsive Devices collection from the App-V Pool VMs device collection.

To do so, right-click the App-V Pool VMs collection and select Properties.

Click the Membership Rules tab. Click the Add Rule dropdown and select Exclude Collections.

Check the box next to the Unresponsive Devices collection and click OK to save.

Select Unresponsive Collection

Unresponsive Devices

Collection 3 – Inactive Devices that need Re-register or Delete

In the third collection contains devices that I’ve identified as either needing to be re-registered or deleted.

The cloned machines all come up so fast that sometimes the old device entry is still in the collection and it causes some problem with the aging calculation. A machine like this will sit as “Inactive” in the Configuration Manager and never receive its deployed apps.

Once we put these machines into a collection,we can run a re-register commands to attempt and discover the machine. The method we’ll use has built in logic to only attempt to re-register a machine if it has not been re-registered in the last runtime cycle. This helps ensure fault-protection.

If the machines continue to appear here, we will have a scheduled task to remove them in the same way the unavailable machines will be removed. More on that below.

Create a new Device Collection and name it “Non-Client Devices“. Select the App-V Pool VMs device collection as the Limiting collection and click Next.

Create a new Query Rule. Name the query “Non-Client Devices” and click Edit Query Statement

Click on the Criteria tab and click the star icon to create a new criteria..

For the Criterion Type, select Null Value. Click Select and set the Attribute Class to System Resource and set the Attribute to Client Type.

Null Client Type

Click OK and then select is NULL for the Operator.

Null Client Criteria

Click OK to save this criteria and click the star icon again to create a second criteria for this rule.

For the Criterion Type, select Null Value. Click Select and set the Attribute Class to System Resource and set the Attribute to Client.

Null Client

Click OK and then select is NULL for the Operator.

Click OK to save this criteria. You should now see two Criteria linked with an And operator. This makes sure that both queries are true for this rule to take effect.

No Client Rules

Click OK to save this query.

Now add an exclusion rule to this collection to exclude the Unresponsive Devices collection.

Set the Schedule for this collection to every 3 minutes.

Non-Client Polling

Step 7 – Automatically Remove Unresponsive Devices or Re-Register Machines

We have our collections set up, the custom client settings applied, our boundaries configured, our Distribution Point in place, and our application web services ready and waiting. But before we move on to the client and application delivery, let’s take one last look at the SCCM server to do a little more for our cleanup routine.

We moved all of our Unresponsive Devices into a new collection that detects clients that haven’t checked in with the SCCM server for more than 15 minutes. SCCM has no way of automatically deleting or clearing a collections with an automated task, so I had to come up with a custom script to perform this as a Windows Scheduled Task.

Device Removal Tasks

The script is a PoSH script that queries WMI for all members of a specified collection and deletes them.

We first need to retrieve the Unresponsive Devices Collection ID for the script. To find this, right click the Unresponsive Devices collection and select Properties.

Collection ID
Record the Collection ID.

Now create a new PowerShell script under the folder C:\Scripts named removeUnresponsiveDevices.ps1.

Create the script with the following code. As always, code that needs to be modified is in Bold and Italics:

# Scriptname: removeUnresponsiveDevicesMembers.ps1
# Description: Remove aged SCCM devices
# By: Adam Baldwin
# Usage: The script checks the Unresponsive device collection in
# SCCM and removes all members.
# Set as a scheduled task on the SCCM server

# Set site name and SCCM Server name

$sitename = "YOURSITENAME"

# Specify the Collection to target

$compObject = get-wmiobject -namespace "root\sms\site_$sitename" -query "select * from SMS_FullCollectionMembership WHERE SMS_FullCollectionMembership.CollectionID='$collID'" -computername $SCCMServer

# Delete each member of the Collection

foreach ($member in $compObject) {
	$resourceid = $member.ResourceID.ToString()
	If ($resourceid -eq $null) {
	Else {
		# Invoke delete() method on WMI instance sms_r_system
        $comp = [wmi]"\\$SCCMServer\root\sms\site_$($sitename):sms_r_system.resourceID=$($resourceid)"


Once this is ready and saved create a new scheduled task to run daily and repeat every 5 minutes, indefinitely.

5 minutes Delete

For the Action, select Start a program. Type in “powershell.exefor the Program/Script. Add the following Arguments:

-command "& c:\scripts\removeUnresponsiveDevices.ps1"


The task should be set to run with an account that is local admin and is allowed to log on as service. Check the radio button to Run whether user is logged on or not and Run with highest privileges.

Run w privileges

 Non-Client Device Removal

Retrieve the Device Collection ID of the Non-Client Devices collection and create a second script called removeNonClientDevices.ps1. The script should be exactly the same as the one above except with the Non-Client Devices ID.

Create a Second Scheduled Task and set this one to run every 10 minutes to remove Non-Client Devices.

Remember to set the user account to run when not logged on and use the service account that we assigned in the previous task.

Re-Registration Task

Now we need to create a re-registration script and task to attempt to bring online Inactive devices.

Another PoSH script needs to be created and set to another scheduled task. You’ll need to fill in Both of the collection IDs for your Active App-V Pool VMs collection and for the Non-Client Devices collection.

You’ll also need a copy of Psexec for this to run, so pick it up in the Sysinternals suite and put it in your local scripts folder on the server where the task is set.

Here’s the script:

# Scriptname: registerDevices.ps1
# Description: Re-registers inactive SCCM devices
# By: Adam Baldwin
# Usage: The script checks the Non-client device collection in
# SCCM and re-registers them once per two rounds of execution.
# Set as a scheduled task on the SCCM server

# Creates registry keys if they do not already exist
# The key contains previously registered machines in the 
# Last iteration of the script 

if (!(Test-Path -Path "hklm:software\SCCM\register")) {
 new-item -path "hklm:software\SCCM"
 new-item -path "hklm:software\SCCM\register"
 New-ItemProperty "hklm:\software\SCCM\register" -Name "registered" -Value "" -PropertyType "String"

# Set site name and SCCM Server name

$sitename = "YOURSITENAME"

# Assign the clients from the Active and Inactive device collections

$inactiveComps = get-wmiobject -namespace "root\sms\site_$sitename" -query "select * from SMS_FullCollectionMembership WHERE SMS_FullCollectionMembership.CollectionID='$inactiveCol'" -computername $SCCMServer
$activeComps = get-wmiobject -namespace "root\sms\site_$sitename" -query "select * from SMS_FullCollectionMembership WHERE SMS_FullCollectionMembership.CollectionID='$activeCol'" -computername $SCCMServer

$registered = ""

# Delete each member of the Collection

foreach ($inactive in $inactiveComps) {
   # Convert the member name to a string
   $inactiveName = $inactive.Name.ToString()
   # If active comps does not contain the inactive device
   # then perform the remote command

   # Collects the previously registered machines from registry
   # and splits it into an array
   $test = (Get-ItemProperty "hklm:software\SCCM\register").registered
   $test = $test -split ","

   # Check to see if the test array contains the current name
   # if so just run an empty statmenet. Else run the remote command
   if ($test -contains $inactiveName){}
   Else {
      # Use PSExec to run a re-register script on remote machines
      e:\scripts\psexec.exe /accepteula \\$inactiveName /d /s powershell.exe " \\contoso.local\netlogon\scripts\re-registerccm.ps1"
      # Record which devices have been registered this roud
      $registered += $inactiveName + ","
      $registered = $registered -Replace " ", ""


# Sets the registered devices from this round into the registry
Set-ItemProperty "hklm:software\SCCM\register" -Name registered -Value $registered

Make sure the account is able to write and read to the registry where we’re recording our hits. That key is HKLM\Software\SCCM\register.

Name the script registerDevices.ps1 and set the scheduled task to run every 5 minutes. Use the same service account that you used in the previous tasks.

Client Portion of the Re-Register

The above script references a PoSH script on the domain’s netlogon volume. It also requires Certmgr.exe in order to delete and re-register the certificates for the CCM agent. I’ve uploaded a x86 Visual Studio 2010 copy of certmgr.exe here. Save certmgr.exe it to the netlogon volume where your PoSH are sitting.

Place a new .ps1 there named “re-registerCCM.ps1” and use the following code:

# Scriptname: re-registerCCM.ps1
# Description: Resets the SCCM registration for the device
# By: Adam Baldwin
# Usage: Place this script onto an accessible share and initiate 
# with the SCCM scheduled task that runs psexec against
# all inactive machines with this code

# Stop SMS AGEnt service
stop-service ccmexec

# Delete the SMS config
del c:\windows\smscfg.ini

# Reference shared volume for certmgr.exe
# to remove SMS certificates
\\contoso.local\netlogon\scripts\certmgr.exe -del -all -s -r localMachine "SMS"

# Starts the SMS Agent Service
start-service ccmexec

# Pause for 5 sec
sleep 5

# Run CCM Evaluation executeable

# Run local scheduled task to check-in with SCCM
SCHTASKS /Run /TN "Request Client Policy"

A Special Note about SCCM Service Account and Script Tasks

The service account used to drive these tasks on the SCCM Server should be assigned the Full Administrator role in SCCM and have had the PowerShell terminal launched from inside of SCCM.


In order for the script to run with the specified account on the server, Powershell needs to be launched from the Configuration Manager while logged in with said account. Either log into windows with the account or right-click the Configuration Manager and run as different user.

Log into the Configuration Manager with the account that will be driving this scheduled task and click the Menu dropdown in the top left of the application. Select Connect via Windows PowerShell.

Connet via Powershell

This will enable your account to connect to and manage the SCCM namespace.

VMWare View Master Image Configuration

Now that the server components are all in place and ready we need to configure our master image to work with SCCM 2012 R2.

As part of the setup we need to configure the CCM agent to be available in a clean state until first run. We’re also going to implement a Computer Startup scheduled task that will initiate an immediate client policy health check, which in turn immediate requests missing software packages to be installed.

Part 1 – Configuring Master Image Check-in Task

To save time and avoid complication, we’re going to set the script and scheduled task first. This way we don’t have to repeat Part 2 of this process over again.

NOTE: The master image needs to be joined to the domain in this step and a service account needs to be configured to run scheduled tasks on the VM

Start up and log into your master clone image. Join it to the domain.

In order for our script to work we need to set the ExecutionPolicy to either Bypass, if you don’t plan to sign your script, or RemoteSigned if you plan to sign it. To set the ExecutionPolicy for the local machine, run PowerShell as an Administrator and type in following command:

Set-ExecutionPolicy -Scope MachinePolicy Bypass

This can also be applied in GPO under Computer Configuration> Policies> Administrative Templates> Windows Components> Windows Powershell. The setting is Turn on Script Execution. Set to Allow all scripts or Allow local scripts and remote signed scripts respectively.

Execution GPO

Now that ExecutionPolicy is set, create a new script PowerShell in C:\Scripts named requestMachinePolicy.ps1. 

The script should contain the following:


Invoke-WMIMethod -Namespace "root/ccm" -ComputerName "." -Class SMS_Client -EnableAllPrivileges -Name RequestMachinePolicy

This script immediately starts up the SMS Agent service and then performs a WMI method invocation that performs the Client Health and Policy check. This command will initiate communication back to the server and trigger software installation.

Now that the script is saved and ready we need to implement a Scheduled Task that runs at machine power on. Create a new Basic Task and name it Request Client Policy. Set the Trigger to run One Time. 

Since we’ll be running this on-demand, just set it to some time in the past and click Next.

One time task


For the Action, select Start a program and type “Powershell.exe” into the Program/script field. Add the following argument:

-command "& c:\scripts\requestMachinePolicy.ps1"

Check the box to bring up the task Properties once it’s been created.

For the User Account, use the service account that you created that has been set to allow Run as Service and is a local administrator on the VM. Check the radio button for Run whether user is logged on or not and Run with highest priveleges. Click OK and type in your Service Account credentials to save the task.

Policy Request Task AccountPolicy Request Task Account - Authenticate

Click on the Settings tab. Make sure that the box is checked to Allow task to be run on demand. I also set the retry to every 5 minutes.

Run on demand

Now that our scheduled task and client-side script is in place, Remove the VM from the Domain and continue along with Part 2 of the Client Setup.

Part 2 – Configuring CCM Agent for VMWare Master Image

Thanks to this article by Henk Hoogendoorn on his blog I was able to correctly configure the CCM client on a VMWare master image to show up properly in the management console. This was a big step forward in this project and the task is very straightforward.

The simple procedure is as follows:

  1. Install the CCM client on your master image with all of your site parameters
  2. Stop the SMS Agent service in the Services console or from command line
    (command line: net stop ccmexec)
  3. Delete %systemroot%\SMSCFG.ini
  4. Open Computer Account Certificates console. Start> Run> type “MMC” and press Enter.
  5. Click File> Add/Remove Snap-in and select Certificates. Choose Computer Account and click OK to continue.
  6. Navigate to SMS> Certificates and delete both SMS certificates.
  7. Immediately Shutdown and take a Snapshot

SMS Certs

This will make our master image so that it creates fresh identifiers in its CCM config for the server to identify it as a new machine.

Part 3 – Configure VMWare Script Timeout

In order for the next script to run for the amount of time we need it to we have to increase our master image’s quickprep script timeout in the registry. See this VMWare publication for more info.

We’ll be modifying a key in the registry so go to Start> Run – regedit.exe

Navigate to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\vmware-viewcomposer-ga

Change the DWORD value of ExecScriptTimeout to 900000


This gives us a total script runtime duration of 15 minutes, even though we’ll only be allowing up to 13 minutes of runtime at first.

Part 4 – VMWare View Pool Configuration

The final piece of the puzzle is configuring the VMWare View pool to allow the newly cloned VMs a certain amount of time in order for the applications to download and install.

I’ve accomplished this task by using the QuickPrep post-synchronization script which allows execution of a remote script on a new clone immediately following customization.

In my script I’ve included a method for preventing the new clone from becoming available by simply disabling the View Agent service for a period of time before re-enabling it. I used sleep in order to pause the execution of lines and include a call to the local scheduled task to ensure Client Health Check has initiated and passed.

Once the script finds that the folder C:\ProgramData\App-V exists it knows that the software has been installed and it then stops requesting health checks. This occurs every 1 minute for a maximum of 13 minutes.

Put this .ps1 script on the Domain’s netlogon volume for the client to access:

# Scriptname: ccmstart.ps1
# Description: Start SMS Agent and initiate client check-in
# procedure to begin installing App-V packages
# By: Adam Baldwin
# Usage: Set as the VMWare View QuickPrep Post-syncrhonization script
# for your App-V deployment pool

# Stop and disable View Agent Service
stop-service WSNM
set-service -name WSNM -StartupType Disabled

# Start SMS Agent service and execute CCMEval.exe
start-service ccmexec

# Set loop counter
$count = 0
$ding = 0
# Loop the check-in task every 1 minute while the App-V folder
# does not exist or for 6 minutes

while (((Test-path C:\ProgramData\App-V) -ne $True) -or ($count -lt 5)) {

   # Initiate the local task on the VM to perform
   # client check-in
   SCHTASKS /Run /TN "Request Client Policy"

   sleep 60


   # If the count reaches 13 (minutes) or more, start the View service
   # and Exit the routine
   if (($count -eq 13) -or ($count -gt 13)) {
      Write-Host "Reached 10 minutes. Starting View Services..."

      set-service -name WSNM -StartupType Automatic
      start-service WSNM

   # If the count reaches 8 (minutes), initiate re-register
   if ($count -eq 8) {
      Write-Host "Reached 8 minutes. Initiating re-registration..."
      # Stop SMS AGEnt service
      stop-service ccmexec

      # Delete the SMS config
      del c:\windows\smscfg.ini

      # Reference shared volume for certmgr.exe
      # to remove SMS certificates
      \\contoso.local\netlogon\scripts\certmgr.exe -del -all -s -r localMachine "SMS"

      # Starts the SMS Agent Service
      start-service ccmexec

      # Pause for 5 sec
      sleep 5

      # Run CCM Evaluation executeable

      # Run local scheduled task to check-in with SCCM
      SCHTASKS /Run /TN "Request Client Policy"

      Write-Host "Re-registration Complete"

   # If the App-V folder is detected, write output
   if (((Test-path c:\ProgramData\App-V) -eq $True) -and ($ding -ne 1)) {
      Write-Host "App-V Folder Detected"
      $ding = 1

Write-Host "Script Fully Completed"

# Enable and start the View Agent service
set-service -name WSNM -StartupType Automatic

start-service WSNM


Save this file as CCMSTART.PS1 in a location that is accessible to all the VMs in the pool, again recommended to be your netlogon volume. Once the script is saved and ready configure your VMWare View Floating Pool to use a QuickPrep post-synchronization script.

Here are the instructions:

  1. Open View Administrator
  2. Navigate to Inventory> Pools
  3. Right-click your pool and select Edit (or wait until the Guest Customization screen if creating a new pool)
  4. Open the Guest Customizations tab
  5. Next to Post-synchronization script name, type “C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe”
  6. Next to Post-synchronization script parameters, type “-command & \\contso.local\netlogon\scripts\CCMSTART.ps1″ (Path to your CCMSTART.ps1 script)
  7. Click OK to save and close

Guest Customization

That’s it for the Client Setup!


SCCM App-V – Application Deployment Process

Now we need to move onto the process of distributing the App-V Applications. There are just a few specifications that we need to verify when publishing new App-V apps so be sure to review all areas closely.

Part 1 – Configure the Application

In the SCCM 2012 R2 console navigate to Software Library> Application Management. In this tree, right-click Applications and select Create Application.

Select Microsoft Application Virtualization 5 in the Type dropdown and Browse to your App-V application on the datastore.

Create Application

Click Next to continue and create the application.

Now that the application is added, we have to configure its distribution and deployment settings. To do so, right-click on the App-V program in the Applications window and select Properties.

On the General Information tab, check the box for Allow this application to be installed from the Install Application task sequence action without being deployed.

App Properties - General

On the Distribution Settings tab, check the radio button for Automatically download content when packages are assigned to distribution points and set the Distribution Priority to High.

Distribute Content

On the Deployment Types tab, select the Deployment type that is present and click Edit.

Deployment Type Edit

Click on the Content tab and make sure that the box for Enable peer-to-peer content distribution is checked. Click the dropdown for both Deployment options fields and select Stream content from distribution point. 

Deployment Type Properties

Click OK to save and close this window.

Now click OK to close and save the Properties window.

Part 2 – Deploy and Distribute the Application

Now that all the properties are set on the application, we need to distribute the content.

Still in the Applications window, right-click on the newly created application and select “Distribute Content“. Once you reach the Content Destination page, click Add and select Distribution Point.


Select the Distribution Point we created earlier and click OK to save.

Select DP


Click Next to continue and distribute the content.

Now we need to Deploy the content to our VM device collection.

Right-click the Application and select Deploy. On the first page click Browse next to Collection to bring up the Select Collection window. Click the dropdown in the top left where it says User Collections and select Device Collections.

Select Collection

Select your App-V Pool VMs (or similarly named) device collection and click OK to continue.

Select Healthy Device Collection

Click Next. We’ve already distributed the content so you should be able to click Next through the Content page.

When you arrive at the Deployment Settings page, we need to change the Purpose field to have Required instead of Available. Click the dropdown and select Required. Click Next to continue.



On the Scheduling page, keep the defaults with the radio button As soon as possible after the available time checked. click Next.


On the User Experience page, select your preferred User notifications option and check the box for Software Installation. This ensures that the software can be pushed to the desktops without intervention or waiting for a maintenance window.

User Experience

Click Next to continue through the remaining sections and deploy the software to your device collection.

Completion and Testing

Congratulations! You’ve just implemented a staging solution for App-V applications for VMWare View Floating VMs, which is no easy task!

Our implementation will cause a delay on the availability of newly cloned machines, but once they become ready the user should have access to all of the provisioned applications at login.

To test simply delete all available machines from your App-V View pool and delete all discovered devices in the SCCM 2012 R2 management console.

Once the new VMs have cloned they should sit in an Agent Unreachable state for the specified period of time. If they come up immediately, without a pause, then the post-synchronization script didn’t run or something went wrong.

Monitor the SCCM to make sure that new devices are being discovered and added to the App-V Pool VMs device collection. The devices must be discovered and available in the proper device collection in order for the correct policies and applications to be assigned.

A good way to ensure that your devices are checking in and communicating is to look at the timestamp of the Policy Request for a client. If the timestamp is within the last 10 minutes (according to our query rule) then the client is most likely active. A healthy client should be checking in every 5 minutes with our configuration.

Policy Request


Once machines are Available in your View pool, log into the pool to make sure you have your application load. If not, there are a couple of places to check for logs and see if the client ran all of the proper scripts and requests.


To check the VMWare QuickPrep logs, navigate to C:\Windows\Temp on the client machine and find the vmware-viewcomposer-ga-new.log. 

Search this file for the word “Post” and you should find the post-synchronization script results. All of the output from the script, including any errors returned from the PoSH script, are displayed here. You should see a similar output for a machine in the App-V pool. If the script completes successfully you will see “Script Fully Completed” at the end of the Post-script logging message, otherwise the machine will simply be enabled in View with or without applications:

2014-04-27 18:58:04,328 [336] INFO  Ready  -  [Ready.cpp, 128] Running the PostSync script: "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -command & \\dcprod1\netlogon\scripts\ccmstart.ps1 with timeout: 900000
2014-04-27 19:07:31,218 [336] INFO  Guest  -  [Guest.cpp, 509] Script "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -command & \\dcprod1\netlogon\scripts\ccmstart.ps1 standard ouput: WARNING: Waiting for service 'VMware View Agent (WSNM)' to stop...
SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

Reached 8 minutes. Initiating re-registration...
CertMgr Succeeded

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

Re-registration Complete
INFO: scheduled task "Request Client Policy" is currently running.

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

SUCCESS: Attempted to run the scheduled task "Request Client Policy".

Script Fully Completed

To verify the scheduled task ran successfully, check the task in Task Scheduler for the Last Run Time and the Last Run Results.

If you would like to investigate the CCM logs, navigate to C:\Windows\CCM\logs and use CMTrace.exe to check through the following log files:

  1. AppDiscovery.log
  2. CAS.log
  3. CCMEval.log

You should find recent messages about successfully running checks and retrievals of application packages.

Increase Timeout

If you find that VMs are coming available after the timeout but still don’t have the requested applications installed, increase the timeout on the CCMSTART.PS1 file that we set in the Post-synchronization scripts field.

The default is to allow for 13 minutes until forcing a VM online, whether apps are available or not. Increase this timeout to give the machines more time to install the application load. Look for the line of code where $count -eq 13 and $count -gt 13 and set the values to 15 minutes before forcing the VM to an available state:

# If the count reaches 15 (minutes) or more, start the View service
# and Exit the routine
if (($count -eq 15) -or ($count -gt 15)) {

Also monitor the App-V Pool VMs device collection during the cloning phases to see how your devices are showing up and if they become Active. You may see duplicates and the old machines will be moved to the Unresponsive Devices collection, this is normal. Verify the timestamps on the Policy Request for a client in order to verify that the new machine is active in the correct device collection.

Manually Initiating Client Policy Request

In order to manually initiate a client policy request to check for new software, you can run the PowerShell script that we created on the local VM or run the scheduled task that we created. Either one will perform the Client Health Policy check-in to request missing software and compliance states. If you’d like to just run the PowerShell command that initiates this client check, simply use the following:

Invoke-WMIMethod -Namespace "root/ccm" -ComputerName "." -Class SMS_Client -EnableAllPrivileges -Name RequestMachinePolicy


That’s it! Some of the components of this deployment aren’t necessarily the most pretty, but they’re functional. If you’d like to hang on to your VMWare View linked-clone pools while still using an App-V solution then this is the design for you.

We delayed the availability of our VMs a bit but the resulting effect is a fully staged VM with App-V applications delivered and ready. I feel that this App-V deployment, in conjunction with both locally installed and other virtualized applications, can deliver the benefit of increased flexibility to the user experience. We hope to cut down the time it takes to make changes or upgrade applications in our environment, to the point where testing and configuration can occur in the same cycle and be released much sooner than the cycle of image change requests that we currently use.

I’ve considered testing full download and deployment rather than streaming for some of the Applications, because of the delay when first launching, so stay tuned for any new advice or tricks that I might come up with.

Please let me know if you have any trouble, questions, or suggestions. This is still a work in progress that I hope to improve upon as time goes by!

Happy Scripting!



Lync 2013 – Mobility and Edge Topology: Explained


This article is intended to serve as a supplement to any Lync 2013 Front End/Edge setup documentation. There are a lot of really great how-to’s out there and Technet has extensive documentation on the process. However, there are some things that are unclear or somewhat ambiguous and could really use the help of some explanation.

We’ll be looking at the different server roles, how each component interacts, and an explanation of the network requirements outlined by Microsoft. Having a clear understanding of the overall layout will help when trying to make sense of the topology and how to plan.

The scenario below describes a Single Consolidated Edge Topology with NAT, utilizing a single server for each the Front End and the Edge. While not completely accurate, I will be referring to the Lync Standard Edition server in my deployment as the Front End server. The reason being that the Standard Edition server plays essentially the same role as an Enterprise Front End so the concepts will apply here.


    1. Lync 2013: Ins and Outs
      1. Server Roles
        1. Lync Front End Server
        2. Lync Edge Server
        3. Reverse Proxy
    2. Network Layout
      1. Network Planning
      2. Edge IPs and URLs
        1. Edge vs “Simple” URLs
        2. Static Routes
      3. Reverse Proxy IPs and URLs
        1. IP Addresses
        2. Simple URLs
      4. Firewall and Port Requirements
        1. STUN/TURN
        2. Edge Requirements
          1. External Interface
          2. Internal Interface
        3. Reverse Proxy Requirements
        4. Port Diagram
    3. DNS Requirements
      1. External DNS
      2. Internal Public Zone DNS
    4. Certificates
      1. Required SANs
      2. Applying Certificates in Lync 2013
    5. Applying Cumulative Updates
      1. Updating Central Management Database
    6. Testing
    7. Summary

Lync 2013: Ins and Outs

To understand how Lync fits together, let’s first become familiar with the server roles.

Server Roles

The Front End, Edge, and Reverse Proxy are all very different players, and understanding how each of them works will help when trying to digest the technical requirements. There are many unique network specifications that will be outlined below and accompanied by a clear description of what’s necessary and why.

Lync Front End Server

In a non-Enterprise deployment this is known as the Standard Edition server. This guide uses the term Front End to describe either an Enterprise FE or Standard Edition server depending on the setup.

The Front End serves as the core component of Lync. Basically, anything that happens on Lync takes place in some fashion on the Front End. What’s important here is to note how the Front End server communicates with the Edge and the Reverse Proxy and how the ensuing connections are handled between peers (specifics outlined below).

This server sits on the internal network and is directly accessible by a single interface. The server resolves to clients using either the FQDN, LyncDiscoverInternal record, or SIP internal SRV record.

Front End Services Include:

      • IM/Chat
      • Address Book
      • Presence
      • Conferencing
      • Enterprise Voice

Lync Edge Server

The Edge server handles outside connections via the Federation, Web Conferencing, and A/V services. This server requires very particular network configurations that will be discussed in detail below.

Meetings joined from external locations into the corporate network are all directed through Edge after having first authenticated through the Reverse Proxy. Edge brokers features such as desktop sharing, whiteboard, and A/V meetings with external users as well as providing federation with other Lync organizations (XMPP Federation is also supported in Lync 2013).

Edge Services Include:

    • Access Edge: Federation
    • Web Conferencing Edge: Conferencing for External Users
    • A/V Edge: External A/V communication, Desktop Sharing

    Reverse Proxy

    The Reverse Proxy is a basic firewall that provides NAT and port translation for a single external interface to five internal Lync services. These services are Autodiscover for External Clients, Mobility (push notifications), Voice Dial-in, meeting URL access point, and certificate provisioning for outside Lync connections.

    The Reverse Proxy communicates directly with the Front End server and does not forward through the Edge.

    Reverse Proxy Services Include:

        • Dial-in for Voice conference
        • Meet URL to join meetings
        • External Autodiscover
        • Push notification for Mobile clients
        • CertProvisioningServices

    Network Layout

    Please refer to the Lync Diagram poster v6.7, Found Here, for a comprehensive view of the many routes and ports that are utilized by the different Edge services. This diagram is very useful in being able to give a full visual of all the port requirements at a glance for any given service. Keep it on hand at all times.

    Also find below a basic layout for the external services’ IP addressing scheme, firewall configuration, and certificate requirements.

    Network Planning

    Now that we have a better understanding of the services that run on each server, let’s look at where they sit and how they communicate.

    Lync Topology

    The DMZ

    In a Single Consolidated Edge Topology with NAT, it’s best to segregate the Edge and Reverse Proxy from the internal network by placing them in the DMZ. The DMZ should have a perimeter firewall on each side in order to separate the internal and external networks completely. This helps reduce the attack surface of the Edge since it is the primary point of exposure to the outside world.

    It is also recommended NOT to join the Edge to the domain for the same reason.

    Open port requirements for each firewall will be outlined in depth below.

    Edge IPs and URLs

    IP Addresses

    It is recommended that the Edge server have 3 IP addresses assigned to the external interface. These three addresses, as well as their URLs, are configured in Lync when creating an Edge Server pool in Lync Topology Builder.

    Edge IPs

    Important! Be sure to select the option The external IP address of this Edge pool is translated by NAT if your external IP addresses are translated through the firewall. Enter your A/V public IP for this field.

    External NAT

    In Windows, configure the External NIC to have three network addresses as well as a default gateway. Do not register this interface with DNS.

    Edge External NIC


    The Internal interface should have just a single IP as well as an internal DNS if desired. There should be no gateway on this NIC.

    Edge Internal NIC


    Edge vs Simple URLs

    It is very important to not use any reserved names for your Edge URLs. For instance, is reserved by Lync as the meeting URL. This cannot be changed, so if you use the Meet URL for any other Edge services they will not work.

    The downfall here is that Lync will not warn you if you do happen to use any of these names, so be cautious.

    Simple URLs

    Choose names that can be clearly identified for their associated service (ie Access, webconf, and AV are good).

    Edge URLs

    All three of these URLs, as well as and, will need to be registered in Public DNS and a SAN is required for each on the public certificate. More details below.

    Edge Static Routes

    Because the Edge resides in the DMZ and the default gateway is configured on the external interface, static routing may be required to direct incoming traffic to the internal Front End server.

    To do this, use “route add” with the -p switch on the Edge server from an elevated command prompt. The entry should be set to route all traffic directed to the internal network (ie where FE sits) over the internal interface.

    To find the Interface value assigned to your NIC, use the route print command. Find and record the numeric value representing the internal NIC under the Interface List table from the route print output.

    Interface List - Route Print

    You may require several route add entries depending on your network layout. A basic static route entry should look something like this:

    route add -p mask IF 12 -p

    The above example assumes that the destination network is destination subnet is, the gateway capable of routing to the destination is, and the interface used to route the traffic is 12. In the image above we can see that “vmxnet3 Ethernet Adapter”  is IF 12. The -P switch sets the route as persistent.

    Reverse Proxy IPs and URLs

    In regards to the Reverse Proxy and associated public DNS, I’ve written an article on deploying Mobility and tips for setting up the RP with Microsoft TMG. Be sure to check that out here.

    (Lync 2013 – Mobility Setup Tips)

    Also take a look at these great guides if setting up a TMG server for the Reverse Proxy solution.

    TMG Publishing Rules for Lync – Publishing Lync Server Simple URLs and Web Components with Forefront TMG 2010
    Reverse Proxy TMG Setup – Lync Reverse Proxy Setup

    IP Addresses

    The Reverse Proxy will have a similar network config as the Edge server with only one IP address facing the outside.

    The gateway will need to be set on the external interface and no DNS.

    As with the Edge server, the RP may require a static route for sending traffic to the FE server. Please see the steps above for configuring static routes.

    Set up the internal interface the same way as the Edge server. DNS is optional.


    The Reverse Proxy is not only important for Mobility and Autodiscover, but it also provides access for guests to join meetings and for internal users to use the Lync Web App.

    The URLs that resolve to the Reverse Proxy externally are as follows:

        1. (External FQDN)
        2. (Lync Autodiscover URL)
        3. (Meeting Simple URL)
        4. (Dial-in Simple URL for phone dial-in)

    The External FQDN is selected when building the Front End pool and can be updated at any time in the Topology Builder.

    External Web Services

    These URLs, in addition to the Edge URLs, will need to be included in a single public certificate.

    It is also advisable to direct internal authoritative DNS for to the Reverse Proxy’s external interface. This helps keep mobile clients from timing out if they roam to an internal network from an outside area.

    Firewall and Port Requirements

    There are many incoming/outgoing port requirements to allow for External Lync services to function properly. It is very important to open all of the ports listed below unless otherwise stated.

    The port table is a transposition of Microsoft’s set requirements, with a little additional detail and explanation. At the end of this section there will be a link to a tool that can be used to verify all necessary ports from different originating locations.

    The Lync Front End server should be fully open on the single internal interface to avoid any issues. However, granular port configuration can be used if desired.

    Using the IP examples from above, let’s assume that our Edge services have the following IP addresses:

    Lync Services Public IP External IP Internal IP
    Access Edge
    Web Conferencing Edge
    A/V Edge
    Reverse Proxy
    Edge Internal FQDN

    Again, here is the simple external services layout using the above addressing scheme.

    Lync Topology


    A quick mention on STUN/TURN: Microsoft explicitly states the need for STUN or TURN capabilities on the firewall. These features are designed to provide symmetric NATing and allow bi-directional communication between peers.

    We used a Cisco ASA in our deployment for the NAT, and while it did not have any specifications about STUN/TURN, the translation was confirmed as being symmetrical. If your firewall specifically defines STUN or TURN, be sure to enable it on the following port rules. If you’re having issue and see no specification for STUN or TURN, you may want to contact the manufacturer to verify symmetric NAT capabilities on the firewall.

    Port Requirements – Edge

    The following port requirements are for the Edge Server’s Internal and External interfaces.

    The Reverse Proxy port requirements are far less comprehensive and only include incoming ports 80 and 443 on the external interface and ports 8080 and 4443 opened on the internal interface. This will be discussed briefly below.

    Edge External Interface

    Role/Protocol/TCP or UDP/Port Source IP address Destination IP address Explanation



    XMPP Proxy service (shares IP address with Access Edge service)

    XMPP Federation is for partners with 3rd party IM services such as AIM, MSN, GChat, or Jabber.

    Only necessary if federating with XMPP partners.


    Edge Server Access Edge service


    Certificate revocation/CRL check and retrieval for Federated/External Partners


    Edge Server Access Edge service


    DNS query over TCP for resolving Federated/External Partners


    Edge Server Access Edge service


    DNS query over UDP for resolving Federated/External Partners



    Edge Server Access Edge service

    Client-to-server SIP traffic for external user access

    Allows _sip._tls resolution for Federated/External Partners



    Edge Server Access Edge service

    For federated and public IM connectivity using SIP

    Part of the _sip._tls resolution and communication.

    Both ways!


    Edge Server Access Edge service


    For federated and public IM connectivity using SIP

    Part of the _sip._tls resolution and communication.

    Both ways!

    Web Conferencing/PSOM(TLS)/TCP/443


    Edge Server Web Conferencing Edge service

    Web Conferencing media

    Incoming SSL connection allows participation in conferences


    Edge Server A/V Edge service



    While Microsoft says these ports are only required for federation with Office Communications Server 2007, I have spoken directly with their support team and was told that these are REQUIRED for A/V services to work.

    Open these ports regardless of what Microsoft recommends or there will be problems with A/V services such as Desktop Sharing.


    Edge Server A/V Edge service



    While Microsoft says these ports are only required for federation with Office Communications Server 2007, I have spoken directly with their support team and was told that these are REQUIRED for A/V services to work.

    Open these ports regardless of what Microsoft recommends or there will be problems with A/V services such as Desktop Sharing.



    Edge Server A/V Edge service


    While Microsoft says these ports are only required for federation with Office Communications Server 2007, I have spoken directly with their support team and was told that these are REQUIRED for A/V services to work.

    Open these ports regardless of what Microsoft recommends or there will be problems with A/V services such as Desktop Sharing.



    Edge Server A/V Edge service


    While Microsoft says these ports are only required for federation with Office Communications Server 2007, I have spoken directly with their support team and was told that these are REQUIRED for A/V services to work.

    Open these ports regardless of what Microsoft recommends or there will be problems with A/V services such as Desktop Sharing.


    Edge Server A/V Edge service


    3478 outbound is used to determine the version of Edge Server that Lync Server is communicating with and also for media traffic from Edge Server-to-Edge Server.




    Edge Server A/V Edge service

    STUN/TURN negotiation of candidates over UDP/3478

    Negotiates A/V connections with federated peers.

    Handled services include Desktop Sharing and video meetings.



    Edge Server A/V Edge service

    STUN/TURN negotiation of candidates over TCP/443

    Negotiates A/V connections with external peers.

    Handled services include Desktop Sharing and video meetings.


    Edge Server A/V Edge service


    STUN/TURN negotiation of candidates over TCP/443

    Negotiates A/V connections with external peers.

    Handled services include Desktop Sharing and video meetings.

    Edge Internal Interface

    Protocol/TCP or UDP/Port Source IP address Destination IP address Comments


    Any (can be defined as Standard Edition server IP, Standard Edition server IP address, or pool IP address running the XMPP Gateway service)

    Edge Server internal interface

    Outbound XMPP traffic from XMPP Gateway service running on Front End Server or Front End pool

    Traffic originates from internal Lync FE server.

    Only necessary if federating with XMPP partners.


    Any (can be defined as Director, Director pool IP address, Front End Server or Front End pool IP address)

    Edge Server internal interface

    Outbound SIP traffic (from Director, Director pool IP address, Front End Server or Front End pool IP address) to Edge Server internal interface

    Traffic originates from internal Lync FE server.

    Forwards FE SIP communication to Federated/External Partners


    Edge Server internal interface

    Any (can be defined as Director, Director pool IP address, Front End Server or Front End pool IP address)

    Inbound SIP traffic (to Director, Director pool IP address, Front End Server or Front End pool IP address) from Edge Server internal interface

    Traffic originates from external, terminates at Lync FE server.

    Forwards Federated/External SIP communication to FE


    Any (can be defined as Front End Server IP address, or each Front End Server IP address in a Front End pool)

    Edge Server internal interface

    Web conferencing traffic from Front End Server, or each Front End Server if in a pool, to Edge Server internal interface

    Traffic originates from internal Lync FE server.


    Any (can be defined as Front End Server IP address, or Front End pool IP address or any Survivable Branch Appliance or Survivable Branch Server using this Edge Server)

    Edge Server internal interface

    Authentication of A/V users (A/V authentication service) from Front End Server or Front End pool IP address or any Survivable Branch Appliance or Survivable Branch Server using this Edge Server

    Authentication traffic for A/V services to Federated/External partners.

    Traffic originates from internal Lync FE server.



    Edge Server internal interface

    Preferred path for A/V media transfer between internal and external users, Survivable Branch Appliance or Survivable Branch Server

    A/V traffic originates from internal Lync FE server to use this preferred port.



    Edge Server internal interface

    Fallback path for A/V media transfer between internal and external users, Survivable Branch Appliance or Survivable Branch Server if UDP communication cannot be established, TCP is used for file transfer and desktop sharing

    A/V traffic originates from internal Lync FE server to use this fallback path if UDP is unavailable.

    TCP is always used for file transfer


    Any (can be defined as the Front End Server IP address, or pool that holds the Central Management store)

    Edge Server internal interface

    Replication of changes from the Central Management store to the Edge Server

    Replication traffic to/from Lync FE



    Edge Server internal interface

    Centralized Logging Service controller using Lync Server Management
    Shell and Centralized Logging Service cmdlets, ClsController command line
    (ClsController.exe) or agent (ClsAgent.exe) commands and log collection

    Centralized Logging



    Edge Server internal interface

    Centralized Logging Service controller using Lync Server Management
    Shell and Centralized Logging Service cmdlets, ClsController command line
    (ClsController.exe) or agent (ClsAgent.exe) commands and log collection

    Centralized Logging



    Edge Server internal interface

    Centralized Logging Service controller using Lync Server Management
    Shell and Centralized Logging Service cmdlets, ClsController command line
    (ClsController.exe) or agent (ClsAgent.exe) commands and log collection

    Centralized Logging

    Port Requirements – Reverse Proxy

    As mentioned above, the Reverse Proxy has very minimal requirements. The RP has a single external interface and address and a single internal interface for communicating traffic to the Front End.

    Please check out my Lync Mobility article for tips on setting up the reverse proxy with Microsoft TMG. Also please follow the links in the Reverse Proxy IPs and URLs section above for full steps on setting up a TMG server as the RP.

    Reverse Proxy External Interface

    Protocol/TCP or UDP/Port Source IP Address Destination IP Address Notes



    Reverse proxy listener

    (Optional) Redirection to HTTPS if user enters http://<publishedSiteFQDN>.

    Also required if using Office Web Apps for conferencing and the Autodiscover
    Service for mobile devices running Lync in situations where the organization
    does not want to modify the external web service publishing rule certificate.



    Reverse proxy listener

    Address book downloads, Address Book Web Query service, Autodiscover, client updates, meeting content, device updates, group expansion, Office Web Apps for conferencing, dial-in conferencing, and meetings.

    Be sure to open 443 bidirectionally through the firewall.

    Reverse Proxy Internal Interface

    Protocol/TCP or UDP/Port Source IP Address Destination IP Address Notes


    Internal reverse proxy interface

    Front End Server, Front End pool, Director, Director pool

    Required if using the Autodiscover Service for mobile devices running Lync in situations where the organization does not want to modify the external web service publishing rule certificate.

    Traffic sent to port 80 on the reverse proxy external interface is redirected to a pool on port 8080 from the reverse proxy internal interface so that the pool Web Services can distinguish it from internal web traffic.


    Internal reverse proxy interface

    Front End Server, Front End pool, Director, Director pool

    Traffic sent to port 443 on the reverse proxy external interface is redirected to a pool on port 4443 from the reverse proxy internal interface so that the pool web services can distinguish it from internal web traffic.


    Internal reverse proxy interface

    Office Web Apps for conferencing

    Port Diagram

    Here is another very useful port diagram. It’s a much simpler version of the Lync Protocol Poster, but is also very helpful for reviewing your port requirements at a glance.

    Lync Perimeter Network

    DNS Requirements

    Lync relies heavily on DNS. DNS is required for almost all of the primary Lync services such as: autodiscover, federation, mobility, joining meetings, initiating conferences, initiating A/V meetings, voice dial-in, etc.

    Be sure to use A Name records rather than CNAME records when registering the Edge and Simple URL entries.

    External DNS

    Type of Record FQDN IP Description  Endpoint
    A Access Edge Service – For Federation and External User access Edge
    A Web Conferencing Edge Service – For attending internal conferences externally Edge
    A A/V Edge Service – For initiating and relaying audio/video services Edge
    SRV 443 SRV record for resolving the SIP domain from TLS clients. The SRV should be pointed to port 443. Edge
    SRV SRV record for resolving SIP domain for Federated partners. Edge
    A Access point for external users to join meetings Reverse Proxy
    A Dial-in address for joining voice to a conference Reverse Proxy
    A Autodiscover for external and mobile clients Reverse Proxy
    A Lync External Front End Web Services URL Reverse Proxy

    Internal DNS

    The Internal DNS entries below are required if you have an internal authoritative zone for your domain’s public namespace.

    Be sure to add all of the following entries into the public zone DNS, internally.

    Type of Record FQDN IP Description  Endpoint
    A (internal DNS, public zone) Lync autodiscover URL Reverse Proxy
    A (internal DNS, public zone) Lync Internal autodiscover URL Reverse Proxy
    SRV (internal DNS, public zone) lyncprod.contoso.local:5061 Internal SIP SRV record for clients Internal Front End Interface
    SRV (internal DNS, public zone) lyncprod.contoso.local:5061 SRV record for resolving the SIP domain from TLS clients. The SRV should be pointed to port 443. Internal Front End Interface
    SRV (internal DNS, public zone) Domain Controller/Time Server:123 Updated time server Domain Controller

    Public Certificates

    The final piece of the puzzle is Certificate provisioning. Because the internal certificate structure is relatively straight forward to configure we will only be focusing on the public requirements.

    Required SANs

    A single certificate is needed in this deployment for each of the servers mentioned above. A public CA cert will need to be applied to the Front End External Web Services Site, Edge Server, and the Reverse Proxy for its mobility and Simple URLs.

    Here is a complete list of required SANs to include on the public certificate.

          1. (External Front End FQDN) – This should be the CN
          2. (Access Edge)
          3. (Web Conferencing Edge)
          4. (AV Edge)
          5. (Lync Autodiscover URL)
          6. (Meeting Simple URL)
          7. (Dial-in Simple URL for phone dial-in)

    Applying Certificates in Lync

    There may be a bit of confusion on how to apply or update certificates for the Lync FE web services. I’ve read some guides that say to apply the certificate to the IIS bindings directly to the External Web Services website, but this does not work correctly.

    In order to apply or change certificates in Lync, run the Lync Server 2013 – Deployment Wizard. Select the “Request, Install or Assign Certificates” option to update the certificates for both the Front End and Edge servers.



    Here are step by step instructions for running the Deployment Wizard to apply certificates:

          1. Log into the Lync FE (or Lync Standard Edition) server
          2. Make sure the public cert with private key is added to the Computer’s Personal store
          3. Run the Lync Server Deployment Wizard
          4. Select Install or Update Lync Server System
          5. On Step 3 of the deployment wizard, select Run or Run Again
          6. Click the drop down next to Default certificate and uncheck all boxes except Web services external”
          7. Click Assign to select your public CA cert and click Next all the way through
          8. Verify that the friendly name for “Web services external” is the name of your public cert
          9. Click Close to finish

    Applying Cumulative Updates

    The latest Lync 2013 CU was released in January of 2014. Please see the related KB Article. It is very important to install all of the latest updates as many fixes and tweaks have been provided in this release.

    The process is very straightforward and easy to perform. Microsoft has an update tool for Lync that checks installed versions and only applies patches to modules that are out of date.

    Updating Central Management Database

    The catch here is that there’s no clear direction of how to update the Central Management Database. The instructions in the KB say to run the following command once the CU patch is complete:

    Install-CsDatabase -CentralManagementDatabase -SqlServerFqdn CMS.FQDN -SqlInstanceName DBInstanceName -Verbose


    However, nowhere in the article does it say what the DBInstanceName will beTo answer that question, when updating the Central Management Database use the DBInstanceName of “rtc“.

    The final command should look something like this:

    Install-CsDatabase -CentralManagementDatabase -SqlServerFqdn LYNCPROD.CONTOSO.LOCAL -SqlInstanceName RTC -Verbose

    Lync should have more solid functionality and security once these updates have been applied to the services and backend databases.


    This is a very useful tool for testing opened ports to the Edge server from Internal, External, Client and Server locations.

    Lync Edge Testing Suite

    Follow up with your Network Engineer or investigate the firewall port rules if you encounter any failures.


    This is a very large undertaking and the components associated with the deployment can be difficult to understand at first glance. Digging a little deeper, though, we find there is a logical order to the layout.

    The toughest requirements to fulfill are the Network specifications. Remember that communication has to be symmetrical on both sides of the peer connection when communicating with users on the outside. Making sure that full bi-directional support is functional on all network interfaces and NAT translations is very important. Some network devices might refer to this as STUN or TURN, while others might not refer to it at all. Check with your firewall vendor to make sure this, or a similar setup, is available.

    Also keep in mind that some of the Port requirements given by Microsoft are listed as not needed when they are. A prime example of this is the 50,000-59,999 range of UDP/TCP ports. These ports are required for both inbound and outbound services such as Desktop Sharing to work regardless of who the partner or external user is.

    I hope this guide will help those out there who are experiencing the confusion that we faced while deploying Lync in our organization. After correctly configuring and opening the network, requesting and applying the proper certificates, and making sure DNS resolution is working from all locations, Lync should be fully functional. Any issues with Federated partners should be treated the same on both ends, and all of the areas mentioned above should be verified by both parties.

    Please leave any questions or comments below!



    I also wanted to give a big shout out to everyone on my team here at OMC for helping pull this together! Many long hours have paid off!

    If you found this article helpful or interesting, please donate a tip!
    (LTC): LYs82mDXPohGDCzeRct8HkJwUCfwveGH1t
    (BTC): 19JUVeefSBNbxUZNNmbDqfcctU6im6vsNg