Post Inactive Users as a Microsoft Teams Message with PowerShell

Post Inactive Users as a Microsoft Teams Message with PowerShell

In my previous post I went through setting up a Team’s webhook to send a daily message / notification of all your Active Directory users that have their password expiring in a week or less. This is valuable for an IT team as they can review users and work together on the within the same work space (team). In this post I will be setting up another scheduled task to send a daily message on Active Directory accounts that have not logged on in 90 days or more. I am also returning attributes like LockedOut, LastLogon, Enabled and more. The array of users is sorted, showing the users that have not logged on in the longest to the shortest. You can change the sort order to fit the needs of your environment. By using the cmdlet, “New-Timespan” I can get the amount of days since the user last logged on. This gives a friendly number instead of a regular shortdate format.

Configure Incoming Webhook

To allow PowerShell to send data to your Teams Channel you will need to configure an incoming Webhook.
  1. In your Team, click on the channel you want the messages to be sent to
  2. Click on the 3 dots underneath the chat window, and then select “Go to store”
  3. Search for Webhook and then select it to begin configuring the Webhook
  4. You can keep the settings as is and press “Install” button located at the bottom
  5. Select the channel you want the incoming webhook to use and then press “Set Up”
  6. Give you webhook a good name. This is what users will see in the Teams chat. Upload an image and then press “Create”
  7. Copy the URL and save it for later, it will be needed. Click “Done” when you have saved the URL in a safe spot.
  8. Back in the Teams channel you can see that the webhook has been created.

Configure PowerShell to Push to Webhook

Now we will configure a PowerShell script to scrape Active Directory for users that match our query, and then send over items to Teams as a message.
  1. Download or copy the script here
  2. Put in the URL for your webhook that you save earlier, as the value for the variable, “$uri”
  3. In my environment I consider an account inactive if they have not logged on in 90 days or more. You can change this number to best fit your environment by changing the $90Days variable.
  4. In my notification message, the user avatar is a red haired “person”. But you can make it whatever you want by modifying the ItemImage variable.
  5. Once you have made it fit your organizations needs, run the PowerShell script.
  6. In my example I ran it in ISE. At the bottom I can see it ran without any issues
  7. Back in Teams I can see my two users that need their passwords changed.

Configure Job as Scheduled Task

  1. In my environment I saved the script at C:\Automation
  2. In Task Scheduler I am going to create a basic task
  3. In the program/script, enter “Powershell -file “FILE LOCATION AND NAME.ps1″”
  4. Save the scheduled task. Back in general make sure it will run if you are logged in or not. Also modify the privileges to best fir your environment.

Script / Download

You can download or copy the script below or on GitHub
#Teams webhook url

#Image on the left hand side, here I have a regular user picture
$ItemImage = ''

#Get the date.time object for XX days ago
$90Days = (get-date).adddays(-90)

$InactiveUsersTable = New-Object 'System.Collections.Generic.List[System.Object]'
$ArrayTable = New-Object 'System.Collections.Generic.List[System.Object]'

#If lastlogondate is not empty, and less than or equal to XX days and enabled
Get-ADUser -properties * -filter { (lastlogondate -like "*" -and lastlogondate -le $90days) -AND (enabled -eq $True) } | ForEach-Object{
	Write-Host "Working on $($_.Name)" -ForegroundColor White
	$LastLogonDate = $_.LastLogonDate
	$Today = (GET-DATE)
	$DaysSince = ((NEW-TIMESPAN –Start $LastLogonDate –End $Today).Days).ToString() + " Days ago"
	$obj = [PSCustomObject]@{
		'Name' = $
		'LastLogon' = $DaysSince
		'LastLogonDate' = (($_.LastLogonDate).ToShortDateString())
		'EmailAddress' = $_.emailaddress
		'LockedOut' = $_.LockedOut
		'UPN'  = $_.UserPrincipalName
		'Enabled' = $_.Enabled
		'PasswordNeverExpires' = $_.PasswordNeverExpires
		'SamAccountName' = $_.SamAccountName
Write-Host "Inactive users $($($InactiveUsersTable).count)"

$InactiveUsersTable | ForEach-Object {
	$Section = @{
		activityTitle = "$($_.Name)"
		activitySubtitle = "$($_.EmailAddress)"
		activityText  = "$($_.Name)'s last logon was $($_.LastLogon)"
		activityImage = $ItemImage
		facts		  = @(
				name  = 'Last Logon Date:'
				value = $_.LastLogonDate
				name  = 'Enabled:'
				value = $_.Enabled
				name  = 'Locked Out:'
				value = $_.LockedOut
				name  = 'SamAccountName:'
				value = $_.SamAccountName

$body = ConvertTo-Json -Depth 8 @{
	title = "Inactive Users - Notification"
	text  = "There are $($ArrayTable.Count) users who have not logged in since $($90Days.ToShortDateString()) or earlier"
	sections = $ArrayTable
Write-Host "Sending inactive account POST" -ForegroundColor Green
Invoke-RestMethod -uri $uri -Method Post -body $body -ContentType 'application/json'

14 thoughts on “Post Inactive Users as a Microsoft Teams Message with PowerShell

  1. I’ve appreciated the couple of articles I’ve read that you’ve done on Teams – very helpful and detailed.

    What I’d like to see is a task that reports users that have been locked out to a teams Webhook – I imagine in some organizations that would be rather chatty, but in others, it could be kind of useful.

  2. Is it possible to attach a report to the Teams post?

    My report is 20 odd users long and it appears to limit the teams post to show 11 users.

  3. I have an environment where I have 62 users that meet this, I’m trying to pump this out to teams but can’t due to error 413, how could I rectify this in your script? Like maybe breaking it up into multiple posts. I tried editing the depth, but thats not working, and if I edit the days, it does work but I need to set the days to 300 so that it only winds up catching like 7 machines. Thanks in advance all of your scripts have been game changer.

    1. The message is too big (I have started running into this as well). I am working to see if this is a configurable limitation

    2. Same here

      Inactive computers 51
      Sending inactive account POST
      Webhook message delivery failed with error: Microsoft Teams endpoint returned HTTP error 413 with ContextId tcid=2762751037186507618,server=AM3PEPF00000B31,cv=iu8wkUrfSk

      But awesome scripts, very helpful !!

  4. Hi all,
    I have just attempted to use the script, it works on the command line but i get this error as it tries to send the webhook.
    “Webhook message delivery failed with error: Microsoft Teams endpoint returned HTTP error 413 with ContextId tcid=7095966227784079461,server=CW2PEPF0000004A,cv=fOTy0MHGl0O
    The list is 70 people big, is this the reason.
    Kind Regards

  5. This is great, really appreciate sharing this. however, this looks at every account in AD can we point this to only look at a particular OU?

Leave a Reply

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