Microsoft Teams Status

I’m using the Windows Task Scheduler for the moment. I scheduled my script to be launched at logon as SYSTEM, so that the console is hidden. The whole thing is completely invisible and works fine, so I don’t see the point of doing anything else! :stuck_out_tongue:

1 Like

This is a great solution!

It works fine for me when I run the ps1 manually, but via Windows Task Scheduler not so much.
Also when I run the task manually from Windows Task Scheduler, it does not work.

Could you share how you set it up?

I am using the following parameters to the powershell command in the task scheduler.

-noprofile -executionpolicy bypass -windowstyle hidden -file c:\Scripts\GetTeamStatus.ps1

This way the Powershell windows closes automatically. I also added the second command because otherwise my laptop didn’t execute the TeamsColor.ps1 script due to execution policies for local scripts.

@Egglestron it is working great and is really fast. Thanks again for sharing this solution :smiley:

3 Likes

I’ve just something similair as well, I use IOTLink for that.
IOTLink provides a idle seconds sensor for your laptop. I convert this to a laptop active/inactive sensor like this:

automation:
  - alias: 'Set personal laptop active based on idle time'
    initial_state: true
    trigger:
      platform: template
      value_template: '{{ (states.sensor.desktop_system_idle_time.state | int < states.input_number.win10_laptop_inactive_timout.state | int * 60) and states.sensor.desktop_system_idle_time.state != "unavailable"}}'
    condition:
      condition: state
      entity_id: input_boolean.win10_laptop_active
      state: 'off'
    action:
    - service: input_boolean.turn_on
      entity_id: input_boolean.win10_laptop_active

  - alias: 'Set personal laptop inactive based on idle time'
    initial_state: true
    trigger:
      platform: template
      value_template: '{{ (states.sensor.desktop_system_idle_time.state | int > states.input_number.win10_laptop_inactive_timout.state | int * 60) or states.sensor.desktop_system_idle_time.state == "unavailable"}}'
    condition:
      condition: state
      entity_id: input_boolean.win10_laptop_active
      state: 'on'
    action:
    - service: input_boolean.turn_off
      entity_id: input_boolean.win10_laptop_active

I then use this automation to turn off the indicator light:

automation:
  - alias: Update status light when work PC inactive
    description: ''
    trigger:
    - platform: state
      entity_id: input_boolean.win10_work_laptop_active
      to: 'off'
    action:
    - service: light.turn_off
      entity_id: light.statuslamp
    mode: single

IOTLink looks very interesting for my personal computer!
Unfortunately, I don’t have administrator rights on my work computer… Thus, for me, a ping binary_sensor works best for the Teams status.

Regarding the automation of the script, I have a startup.bat file in which I added this line:

:: Other commands
START pwsh -Command "& C:\Scripts\TeamsStatus.ps1"

As stated before, this bat file is launched as the SYSTEM user, with the trigger “At log on of any user”.

1 Like

Hi @EBOOZ
I hacked your powershell so it can deal with rapid update changes by only looking at the very last presence update. I chose to only look for the string “Setting the taskbar overlay icon”, but maybe that’s limiting me somehow. Seems to work ok, I use MQTT to update HA and have ordered a Unicorn mini HAT for a Pi Zero WH to create my status lamp (this will listen to an MQTT topic that HA will be in control of, turning lamp off when outside of working hours etc)
What do you think ?

DO {

$fileContents = Get-Content -Path “C:\Users\zzzz\AppData\Roaming\Microsoft\Teams\logs.txt” -Tail 100
$lineNum = (($fileContents | Select-String ‘Setting the taskbar overlay icon’)[-1].LineNumber) - 1
$TeamsLog = $fileContents | Select -Index $lineNum

If ($TeamsLog -like “Available”) {
$TeamsStatus = “Available”

}
ElseIf ($TeamsLog -like “Busy”) {
$TeamsStatus = “Busy”

}
ElseIf ($TeamsLog -like “Away” -or $TeamsLog -like “Be Right Back”) {
$TeamsStatus = “Away”

}
ElseIf ($TeamsLog -like “Do not disturb”) {
$TeamsStatus = “Do not disturb”

}
ElseIf ($TeamsLog -like “In a meeting” -or $TeamsLog -like “InAMeeting”) {
$TeamsStatus = “In a meeting”

}
ElseIf ($TeamsLog -like “On the phone”) {
$TeamsStatus = “In a call”

}
ElseIf ($TeamsLog -like “ain window” -or $TeamsLog -like “Offline”) {
$TeamsStatus = “Offline”

}

If ($CurrentState -ne $TeamsStatus) {
$CurrentState = $TeamsStatus
Write-Host $CurrentState

 $app = "C:\Program Files\mosquitto\mosquitto_pub.exe" 
 $arg1 = "-h 10.10.10.10 -u user -P password -t teams/presence -m ";
 $arg2 = $CurrentState;
 $arg=$arg1+"""$arg2"""
 Start-Process $app -ArgumentList $arg

}
Sleep 2
} Until ($Enable -eq 0)

So, seeing as the HACS o365 addon already figures out all of the login an token stuff.

I’ve made this PR on the underlying library to allow fetching your teams status.

Now I just need it to be merged…

4 Likes

@EBOOZ, Brilliant work. Thanks so much for this, will come in very handy for informing the family. I’ve been waiting for something like this.

1 Like

Maybe you were using an old version of the script. Selecting only the last line that matches the search string has been implemented a while ago:

$TeamsStatus = Get-Content -Path "C:\Users\$UserName\AppData\Roaming\Microsoft\Teams\logs.txt" -Tail 100 | Select-String -Pattern `
  'Setting the taskbar overlay icon -',`
  'StatusIndicatorStateService: Added' | Select-Object -Last 1
# Get Teams Logfile and last app update deamon status
$TeamsActivity = Get-Content -Path "C:\Users\$UserName\AppData\Roaming\Microsoft\Teams\logs.txt" -Tail 100 | Select-String -Pattern `
  'Resuming daemon App updates',`
  'Pausing daemon App updates',`
  'SfB:TeamsNoCall',`
  'SfB:TeamsPendingCall',`
  'SfB:TeamsActiveCall' | Select-Object -Last 1

You should not forget to include your search with StatusIndicatorStateService: Added, because otherwise the status won’t be updated when the icon in the taskbar has a NewActivity badge on it (like 1 new message, mention, etc.).

You can download the latest version at: https://github.com/EBOOZ/TeamsStatus

Do you know if this one supports refresh-tokens? My previous attempt to get this up and running failed because my token expired and didn’t refresh. This was a known REST-API in HA at that moment.

@Mey Any idea when this will get merged?

Getting the following warning:

2021-01-26 11:00:35 WARNING (MainThread) [homeassistant.components.template.template_entity] Template loop detected while processing event: <Event state_changed[L]: entity_id=sensor.teams_activity, old_state=<state sensor.teams_activity=; friendly_name=Microsoft Teams activity, icon= @ 2021-01-26T10:29:00.470623-06:00>, new_state=<state sensor.teams_activity=Not in a call; friendly_name=Microsoft Teams activity, icon=mdi:phone-off @ 2021-01-26T11:00:35.097926-06:00>>, skipping template render for Template[{% if states('sensor.teams_activity') == '' -%}
  Offline
{%- endif %}]
2021-01-26 11:00:35 WARNING (MainThread) [homeassistant.components.template.template_entity] Template loop detected while processing event: <Event state_changed[L]: entity_id=sensor.teams_activity, old_state=<state sensor.teams_activity=; friendly_name=Microsoft Teams activity, icon= @ 2021-01-26T10:29:00.470623-06:00>, new_state=<state sensor.teams_activity=Not in a call; friendly_name=Microsoft Teams activity, icon=mdi:phone-off @ 2021-01-26T11:00:35.097926-06:00>>, skipping template render for Template[{% if states('sensor.teams_activity') == '' -%}
  mdi:microsoft-teams
{%- endif %}]

Issue with creating sensors - log attached · Issue #2 · EBOOZ/TeamsStatus (github.com) :slight_smile:

1 Like

A potential workaround for self-referencing template sensors would be to have the PowerShell script set the value of an input helper (input_text or input_select). For the UI etc. you could then (also) create a template sensor that inherits the input helper entity.

Hey guys,

this looks amazing! Unfortunately my organisation also doesn’t allow access to the API and I also don’t have elevated rights on my machine. The elevated rights are needed to access the teams logfile, right?

So, without these, it is not going to be possible to get the status from teams?

I have it running without admin rights. https://github.com/EBOOZ/TeamsStatus requires admin rights only because he wants to use a service daemon. Another option is to take the guts of his script and schedule tasks via task scheduler.

  1. Download https://github.com/EBOOZ/TeamsStatus/blob/ec83df37311f26493f3034c1303f73e2d177f673/Get-TeamsStatus.ps1 and https://github.com/EBOOZ/TeamsStatus/blob/ec83df37311f26493f3034c1303f73e2d177f673/Settings.ps1
  2. Place into a folder in your user directory, wherever you wish (desktop, docs, whatever)
  3. Edit settings as needed
  4. Create the entities in Home Assistant as documented by EBOOZ
  5. Test the script by running Get-TeamsStatus.ps1 with PowerShell. Ctrl+c to kill it
  6. Open task scheduler - you can create tasks as you without any admin rights required, in most orgs (may depend on GPO)
  7. Set action to start a program, “powershell.exe”. Set arguments to be -WindowStyle Hidden -File “C:\Users\UserID\pathToFolder\Get-TeamsStatus.ps1”
  8. Set triggers; I did two triggers, one at login, and one at workstation unlock. Make sure it won’t run if already running, make sure it runs on battery, and on settings tab make sure it won’t stop the task.

Hopefully you’re familiar with task scheduler… if not, google. :slight_smile:

6 Likes

Awesome man!. I’ll try this out either today or tomorrow!

Thanks for the info.

So, for what it’s worth, I created a pull request on EBOOZ’s repo to add in a webcam monitor capability with registry key. Basically it monitors the following key which is “0” if the camera is on (replace username):

Get-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam\NonPackaged\C:#Users#USERNAME#AppData#Local#Microsoft#Teams#current#Teams.exe -Name LastUsedTimeStop | select LastUsedTimeStop

You can add in to his script in the elseif block at line 136.

    ElseIf ($TeamsActivity -like "*Pausing daemon App updates*" -or `
        $TeamsActivity -like "*SfB:TeamsActiveCall*" -or `
        $TeamsActivity -like "*name: desktop_call_state_change_send, isOngoing: true*") {
        
		$webcam = Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam\NonPackaged\C:#Users#$UserName#AppData#Local#Microsoft#Teams#current#Teams.exe" -Name LastUsedTimeStop | select LastUsedTimeStop
		
		if ($webcam.LastUsedTimeStop -eq 0){
			$Activity = $lgInACallWebcamOn
			$ActivityIcon = $iconInACall
		}
		else {
			$Activity = $lgInACall
			$ActivityIcon = $iconInACall
		}
        Write-Host $Activity
    }

In settings, replace line 18 with these two lines:

$lgInACall = "In a call - camera off"
$lgInACallWebcamOn = "In a call - camera on"
1 Like

Hello all!

As my teams state from the log file no longer works, I have built a python application to fetch the teams state directly from MS Graph api.
Its available as docker image!

Have a look at here:

@EBOOZ Thanks for your great PowerShell solution for Teams. I have used this one to control my sonos in my home office. It will pause and then resume after a call/meeting. Works splended!

I have creeated a Gist for others if they are interested: https://gist.github.com/mark-veenstra/01aeccf357ced3c5be048f6b2c704e97

1 Like