top of page
Writer's pictureChristopher Lee

Deploying Teams Firewall Rules via PS Script and Intune

Updated: Apr 7, 2021

As part of the surge in demand for "work from home" capabilities at the beginning of 2020, I came across an interesting challenge with managing Windows 10 Defender Firewall configurations from Intune and the Teams desktop client. The Teams client does not actually create some necessary firewall rules at the time of installation. The missing rules apply specifically to making an outbound call from Teams.


Microsoft actually has this documented in their Docs and have even gone so far as to provide a script that will create the necessary rules. This works great if you are configuring devices through Group Policy or some other on-premises management tools, but not so easily when being deployed via Intune.


Problem Background

Like it or hate it, Teams installs into the user profile of the user, therefore resulting in a unique executable path for each user on a computer. Microsoft justifies this location as Teams is self-updating and by placing the installation in the user profile (..\AppData\local\Microsoft\Teams\Current\Teams.exe), the user does not require administrative rights to install or update Teams. Even though a standard user has full rights over their profile, it does not give them rights to modify the Windows Defender Firewall and it's rule configurations.


When a user goes to make their first call, they receive an admin prompt as shown below. This typically will reflect the Domain profile, but in my case users were working from home already and therefore their prompts were reflecting the Public firewall network profile.

To add complexity, in my case as well, Teams installations across the users was not in the typical installation location in the user profile. Instead, my users had Teams installed under the ProgramData directory using a subfolder reflecting username.


So why is this a problem? In my case, the script provided by Microsoft would have worked fine, but Teams was installed under the ProgramData directory for my users, not under the 'Users' directory that would have only contained subfolders representing only users. Therefore, I couldn't use all the subfolders of ProgramData to easily identify users, but instead had to run this based on the currently logged in user.

The Script

I've done ahead and made the script available from my GitHub repository and will reference code blocks below to help explain.


When deploying a script for Intune, the default run context is the local SYSTEM account on the workstation. Therefore, using variables referencing user-specific paths (such as $env:USERPROFILE) cannot be used as these would return values relating to the SYSTEM account and not the currently logged in user. In a way this is actually a good thing as if the script ran under the currently logged in user context, it most likely would not have the necessary rights to make firewall changes.


To get the currently logged in user, rather than rely on the environment variables, I relied on a WMI query instead.


Get-WMIObject -Class Win32_ComputerSystem | Select Username -ExpandProperty Username

This will return the user currently logged into the console of the machine, not via terminal services or Remote Desktop. Using this value, I can grab the path of the user profile and get the username of the user.


Even though in my case, the user profile did not have Teams installed, this should be the default location. Therefore, I am accounting for it in my script to create the rules for both the profile installation path as well as the ProgramData installation path. Chances are, you should only need the profile path.


Creating the rule works if there are no previously existing rules to conflict with. When the user receives the admin prompt shown above, if they do not have the necessary administrative rights, they really can only click Cancel. Oddly enough, when they click Cancel, two explicit BLOCK rules are created in the firewall. Therefore, any user who had received this prompt before would have conflicting rules. These rules need to be removed before creating our ALLOW rules. To do this, I simply check if any rules exist for the Teams executable paths unique to the user.


# Check if rules exist
If (Get-NetFirewallApplicationFilter -Program $profPath {...}

# Remove existing firewall rules
Get-NetFirewallApplicationFilter -Program $profPath | Remove-NetFirewallRule

The $profPath variable references the file path to the Teams.exe file unique to the user, which is generated using the previous code blocks.


Now that the previous rules matching the Teams.exe path have been removed, I create new rules for both TCP and UDP for the paths. In my example, I am applying the rule to ALL network profiles. Because my users are mostly working from home, their network profiles will mostly be Public. But I also want to account for when they come back into the office. You could modify the script to use specific network profiles with the values Domain, Private and Public instead of All.


"UDP","TCP" | ForeEach-Object { New-NetFirewalRule -DisplayName $ruleName -Direction Inbound -Profile Any -Program $profPath -Action Allow -Protocol $_ }

I repeat these same blocks to apply to the ProgramData file path too unique to the user as well.


The script does have a dedicated logging function as logging is critical to troubleshooting scripts deployed via Intune. From Intune's perspective, unless you explicitly give it an exit code other than '0', then the script is considered to have run successfully... even if our Try-Catch blocks had errors and the Catch blocks were executed. To account for this, I track a Boolean variable named $status that at the very end is checked, and if set for an error, executes and Throw statement to exit with an error, which Intune will detect.


Throw "Errors encountered prevented desired end-state."

Configuring Intune

Now that we have a script, we need to configure Intune to deploy it to all of the managed endpoints. To do this, we start with a Device Configuration Profile and select the option for Scripts.


Note: When troubleshooting, you should delete the previous script and create a new object in Intune. The reason for this is because Intune scripts only apply once when successful. This means that even if you modify the script file itself, it will not run again on any computer that has already successfully run it (remember success is based on what Intune sees, so it may report a successful run even if the script did not work the way you wanted it to). By deleting it and creating a new object, it receives a new unique identifier and therefore is treated as a completely new script across all computers.


If a script fails, it will retry every hour, but only 3 times total. If the script is not successful after the 3 retries, it stays in an unsuccessful state and never tries again (can be manually tricked by deleting registry keys). Therefore, another reason why you should delete your previous script and deploy a new object entirely when troubleshooting.


When setting up the script object, select the PS1 file to upload. If the script did not make changes that required elevated permissions, using the option to Run this script using the logged on credentials would make life a lot easier to find the user-specific paths. But, since we need elevated rights, the script must run using the SYSTEM account.


Also, because all Windows 10 installs should be 64-bit, use the option to run the script in the 64-bit PowerShell Host. This would be the the same as opening a PowerShell console directly on the computer as they default to 64-bit.



Running the Script

After creating the Intune script object, you could wait for it to sync and check in. Alternatively, you could force a manual sync. This can be done directly from Intune, using the Intune Company Portal app on the device or the Settings app for the user account on the device.


The preferred way to ensure the new policy gets applies is actually to restart the Microsoft Intune Management Extension service. Restarting this service simulates the same condition that would occur for a computer restart, resulting in the computer checking in with Intune, pulling down policy changes and then applying them as quickly as possible.



1,866 views0 comments

Recent Posts

See All

Comments


bottom of page