Post Inactive Users as a Microsoft Teams Message with PowerShell
Table of Contents
Configure Incoming Webhook
To allow PowerShell to send data to your Teams Channel you will need to configure an incoming Webhook.- In your Team, click on the channel you want the messages to be sent to
- Click on the 3 dots underneath the chat window, and then select “Go to store”
- Search for Webhook and then select it to begin configuring the Webhook
- You can keep the settings as is and press “Install” button located at the bottom
- Select the channel you want the incoming webhook to use and then press “Set Up”
- Give you webhook a good name. This is what users will see in the Teams chat. Upload an image and then press “Create”
- Copy the URL and save it for later, it will be needed. Click “Done” when you have saved the URL in a safe spot.
- 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.- Download or copy the script here
- Put in the URL for your webhook that you save earlier, as the value for the variable, “$uri”
- 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.
- 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.
- Once you have made it fit your organizations needs, run the PowerShell script.
- In my example I ran it in ISE. At the bottom I can see it ran without any issues
- Back in Teams I can see my two users that need their passwords changed.
Configure Job as Scheduled Task
- In my environment I saved the script at C:\Automation
- In Task Scheduler I am going to create a basic task
- In the program/script, enter “Powershell -file “FILE LOCATION AND NAME.ps1″”
- 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'
My name is Bradley Wyatt; I am a 4x Microsoft Most Valuable Professional in Cloud and Datacenter Management. 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 am the 2022 North American Outstanding Contribution to the Microsoft Community winner.
14 thoughts on “Post Inactive Users as a Microsoft Teams Message with PowerShell”
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.
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/
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.
Yes you can store it somewhere and link to it
Nice script!
Replace Get-ADUser with Get-ADComputer and it will also show up computers who did not logon for “X” days.
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.
The message is too big (I have started running into this as well). I am working to see if this is a configurable limitation
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 !!
too large – looking at ways to resolve this
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
yep its too big – when I get some free time I am going to try to look at alternatives
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?
Yes you can use filter with Get-ADUser to filter to a OU