Background

As mentioned in Part 1 – We are going to be setting up a script to create firewall rules for Teams per user instance installations on machines.

We will be using the Microsoft recommended script as our baseline but modifying it to include some more functionality.

The Microsoft Code:

<#
.SYNOPSIS
   Creates firewall rules for Teams.
.DESCRIPTION
   (c) Microsoft Corporation 2018. All rights reserved. Script provided as-is without any warranty of any kind. Use it freely at your own risks.
   Must be run with elevated permissions. Can be run as a GPO Computer Startup script, or as a Scheduled Task with elevated permissions.
   The script will create a new inbound firewall rule for each user folder found in c:\users.
   Requires PowerShell 3.0.
#>

#Requires -Version 3

$users = Get-ChildItem (Join-Path -Path $env:SystemDrive -ChildPath 'Users') -Exclude 'Public', 'ADMINI~*'
if ($null -ne $users) {
    foreach ($user in $users) {
        $progPath = Join-Path -Path $user.FullName -ChildPath "AppData\Local\Microsoft\Teams\Current\Teams.exe"
        if (Test-Path $progPath) {
            if (-not (Get-NetFirewallApplicationFilter -Program $progPath -ErrorAction SilentlyContinue)) {
                $ruleName = "Teams.exe for user $($user.Name)"
                "UDP", "TCP" | ForEach-Object { New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Profile Domain -Program $progPath -Action Allow -Protocol $_ }
                Clear-Variable ruleName
            }
        }
        Clear-Variable progPath
    }
}

Our Code

The first step we want to address is adding logging, we will do this by using the start-transcript cmdlet but will write it to the C:\ Logs folder with the proper name. In order to do so, we will first test the path exists and if it doesn’t create it.

$LogPath = 'C:\Logs'
$LogName = $LogPath + "\Set-TeamsFirewallRule.log"

If ((Test-Path $LogPath) -eq $false)
{
    New-Item -Path c:\Logs -ItemType Directory
}

Start-Transcript -Path $LogName -Force

Next we will get all accounts but exclude accounts that are stale ( haven’t logged on in 6 months, no need to make firewall rules for those), accounts the are Public or Admin/Helpdesk accounts or service accounts that may be on the machine for various reasons.

#Get all the user profiles that are on the system
$users = Get-ChildItem (Join-Path -Path $env:SystemDrive -ChildPath 'Users') -Exclude 'Public', 'ADMIN*','Help*','svc*' 

#Generate a date code for accounts that have had activity in the last 180 days
$StaleAccountDate = (Get-Date).AddDays(-180)

If we find some users that match that criteria, go into the loop and start working through them.

if ($null -ne $users) 
    {
    
    #Check for any firewall rules that block Teams access and disable them
    Write-Output "Checking for firewall rules that block Teams Access"
    $TeamsBlock = Get-NetFirewallRule -Name *Teams* | Where-Object {($_.action -eq "Block") -and ($_.Enabled -eq 'True')}
    If ($null -ne $TeamsBlock)
    {
        Foreach ($Rule in $TeamsBlock)
        {
            Write-Output "Disabling blocking firewall rule $($Rule.DisplayName)"
            Set-NetFirewallRule $Rule.Name -Enabled False
        }
    }

    foreach ($user in $users) 
        {
            #Check the last time something was written to the file path for the user we are checking
            $LastAccessTime = Get-ChildItem $user.FullName | sort lastwritetime -Descending

            If ($LastAccessTime[0].LastWriteTime -le $StaleAccountDate)
            {
                Write-Output "Skipping $($user) because the last access time on the account is too old"
            }

            If ($LastAccessTime[0].LastWriteTime -ge $StaleAccountDate)
            {
                Write-Output "Checking $($user.FullName)"
                #Generate the path that will be checked
                $progPath = Join-Path -Path $user.FullName -ChildPath "AppData\Local\Microsoft\Teams\Current\Teams.exe"
                    
                    if (Test-Path $progPath) 
                    {
                        #Check that the firewall rule already exists, if it does skip, if not, add it
                        $RuleCheck = Get-NetFirewallApplicationFilter -Program $progPath -ErrorAction SilentlyContinue

                        if ($Null -eq $RuleCheck) 
                        {
                            Write-Output "Creating new firewall rules for $($user)"
                            $ruleName = "Teams.exe for user $($user.Name)"
                            
                            #Here we add some things into the actual Rule name so that it is friendly and easily searchable.  We also want the rule name and display name to match.
                            "UDP", "TCP" | ForEach-Object { New-NetFirewallRule -Name ($RuleName + " " + $_.ToString()) -DisplayName ($RuleName + " " + $_.ToString()) -Direction Inbound -Profile Any -Program $progPath -Action Allow -Protocol $_ }
                            Clear-Variable ruleName
                        }

                        If ($Null -ne $RuleCheck)
                        {
                            Write-Output "Looks like there are already rules in place for $($user) so we will not add any"
                        }
                    }

                    if ((Test-Path $progPath) -eq $false)
                    {
                        Write-Output "Looks like $($user) has not launched Teams, we will be skipping"
                    }
            }
        #Clear the variables for the next user run
        Clear-Variable TeamsBlock
        Clear-Variable RuleCheck
        Clear-Variable progPath
            
    }
}


Stop-Transcript

And that is it! As you can see we really just took the original Microsoft script and added on some more advanced pieces to make it match our environment and act a bit more intelligently.

Next up… Writing the setup script!

  1. Intro
  2. The actual script
  3. Setup and Uninstall scripts
  4. Intune magic

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *