Skip to content
The Lazy Administrator
  • Home
  • Disclaimer
  • Contact
  • About Me
  • Search Icon

The Lazy Administrator

Finding ways to do the most work with the least effort possible

Post Inactive Users as a Microsoft Teams Message with PowerShell

Post Inactive Users as a Microsoft Teams Message with PowerShell

December 11, 2018 Brad Wyatt Comments 14 comments

Table of Contents

  • Configure Incoming Webhook
  • Configure PowerShell to Push to Webhook
  • Configure Job as Scheduled Task
  • Script / Download
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
$uri = "[INSERT TEAMS WEBHOOK URL]"

#Image on the left hand side, here I have a regular user picture
$ItemImage = 'https://img.icons8.com/color/1600/circled-user-male-skin-type-1-2.png'

#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' = $_.name
		'LastLogon' = $DaysSince
		'LastLogonDate' = (($_.LastLogonDate).ToShortDateString())
		'EmailAddress' = $_.emailaddress
		'LockedOut' = $_.LockedOut
		'UPN'  = $_.UserPrincipalName
		'Enabled' = $_.Enabled
		'PasswordNeverExpires' = $_.PasswordNeverExpires
		'SamAccountName' = $_.SamAccountName
	}
	
	$InactiveUsersTable.Add($obj)
}
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
			}
		)
	}
	$ArrayTable.add($section)
}

$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'
 
Brad Wyatt
Brad Wyatt

My name is Bradley Wyatt; I am a 5x Microsoft Most Valuable Professional (MVP) in Microsoft Azure and Microsoft 365. I have given talks at many different conferences, user groups, and companies throughout the United States, ranging from PowerShell to DevOps Security best practices, and I am the 2022 North American Outstanding Contribution to the Microsoft Community winner.


Microsoft Teams, Office 365, PowerShell
Automation, JSON, Microsoft Teams, Office 365, PowerShell, WebHook

Post navigation

PREVIOUS
Post Users with Expiring Passwords as Microsoft Teams Message with PowerShell
NEXT
Get a Teams Notification the Moment an Active Directory User gets Locked Out with PowerShell Using Webhooks

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

  1. John W. says:
    December 12, 2018 at 10:07 am

    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.

    Reply
    1. Brad Wyatt says:
      December 13, 2018 at 5:20 pm

      Great idea, let me know if this works for you

      https://thelazyadministrator.com/2018/12/13/get-a-teams-notification-the-moment-an-active-directory-user-gets-locked-out-with-powershell-using-webhooks/

      Reply
  2. James Draper says:
    December 20, 2018 at 2:28 am

    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.

    Reply
    1. Brad Wyatt says:
      February 7, 2019 at 10:03 am

      Yes you can store it somewhere and link to it

      Reply
  3. Jan says:
    January 14, 2019 at 6:06 am

    Nice script!
    Replace Get-ADUser with Get-ADComputer and it will also show up computers who did not logon for “X” days.

    Reply
  4. Binary says:
    May 4, 2019 at 2:36 am

    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.

    Reply
    1. Brad Wyatt says:
      May 14, 2019 at 8:09 am

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

      Reply
    2. Fran says:
      July 24, 2019 at 3:56 am

      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
      mKkBp5vjUayg.0..

      But awesome scripts, very helpful !!

      Reply
      1. Brad Wyatt says:
        August 27, 2019 at 8:37 am

        too large – looking at ways to resolve this

        Reply
  5. Elliott says:
    August 20, 2019 at 4:09 am

    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
    TIst4PCm4qQ.0..”
    The list is 70 people big, is this the reason.
    Kind Regards

    Reply
    1. Brad Wyatt says:
      August 20, 2019 at 8:11 am

      yep its too big – when I get some free time I am going to try to look at alternatives

      Reply
  6. Pingback: Posting Notifications About Inactive Mailboxes to Teams - Office 365 for IT Pros
  7. Billy says:
    November 8, 2019 at 10:55 am

    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?

    Reply
    1. Brad Wyatt says:
      November 18, 2019 at 9:57 am

      Yes you can use filter with Get-ADUser to filter to a OU

      Reply

Leave a Reply Cancel reply

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

Subscribe

Email


Categories

  • Active Directory (8)
  • AI (3)
  • API (1)
  • AutoPilot (2)
  • Azure (15)
  • Bicep (4)
  • Connectwise (1)
  • Defender for Cloud Apps (1)
  • Delegated Admin (1)
  • DevOps (6)
  • Graph (6)
  • Intune (15)
  • LabTech (1)
  • Microsoft Teams (6)
  • Office 365 (19)
  • Permissions (2)
  • PowerShell (50)
  • Security (1)
  • SharePoint (3)
  • Skype for Business (1)
  • Terraform (1)
  • Uncategorized (2)
  • Yammer (1)

Recent Comments

  • Kristopher Gates on Getting Started with GitHub Copilot in the CLI
  • MD SHARIQUE AKHTAR on Modern Active Directory – An update to PSHTML-AD-Report
  • TommyBoich on How The ConnectWise Manage API Handles Pagination with PowerShell
  • LOTTERY 365 LOGIN on Windows LAPS Management, Configuration and Troubleshooting Using Microsoft Intune
  • SPRUNKI PHASE 6 on Get a New Computer’s Auto Pilot Hash Without Going Through the Out of Box Experience (OOBE)

1,739,390 People Reached

© 2025   All Rights Reserved.