How to Send a Microsoft Teams Message from a Batch Script
If your organization uses Office 365, Microsoft Teams is the central hub for collaboration and alerts. Just like Slack, Microsoft Teams allows external scripts to send automated messages directly to a channel using an Incoming Webhook. This is the perfect tool for notifying administrators about server statuses, backup completions, or build deployments.
In this guide, we will demonstrate how to post rich-text alerts to Microsoft Teams using curl.exe.
The Strategy: Webhooks and Adaptive Cards
- Configure an "Incoming Webhook" connector for your specific Teams channel.
- Format your message. Teams accepts a slightly different JSON structure than Slack, using the "MessageCard" standard.
- Use the native
curl.execommand to POST that JSON to the Microsoft endpoint.
Setup: Getting the Teams Webhook URL
- In Microsoft Teams, right-click the channel name and select Connectors.
- Find Incoming Webhook and click Add or Configure.
- Give the webhook a name (e.g., "Server Monitor") and optionally upload an icon.
- Copy the generated URL (it usually starts with
https://[tenant].webhook.office.com/...).
Implementation Script
@echo off
setlocal enabledelayedexpansion
:: 1. Define the Webhook URL
set "webhookUrl=https://YOUR_TENANT.webhook.office.com/webhookb2/YOUR_WEBHOOK_URL_HERE"
:: 2. Define the Message Content
set "alertTitle=Nightly Backup Status"
set "messageText=The database backup completed successfully in 14 minutes."
:: Use a hex color code for the border stripe (e.g., 28A745 for Green, DC3545 for Red)
set "themeColor=28A745"
:: 3. Construct the MessageCard JSON Payload
:: We use carets (^) to continue the line for readability,
:: and escape internal double-quotes with backslashes (\")
set "json={" ^
"\"@type\": \"MessageCard\"," ^
"\"@context\": \"http://schema.org/extensions\"," ^
"\"themeColor\": \"%themeColor%\"," ^
"\"title\": \"%alertTitle%\"," ^
"\"text\": \"%messageText%\"" ^
"}"
echo Sending alert to Microsoft Teams...
:: 4. POST the payload via curl
:: Use curl.exe explicitly to avoid the PowerShell alias conflict
curl.exe -s -o nul -w "%%{http_code}" -X POST -H "Content-type: application/json" -d "%json%" "%webhookUrl%" > "%TEMP%\teams_response.tmp"
:: Capture the exit code immediately
set "curlResult=!errorlevel!"
:: 5. Validate the result
if !curlResult! neq 0 (
echo [ERROR] curl failed with exit code !curlResult!. Check network connectivity.
del "%TEMP%\teams_response.tmp" 2>nul
pause
exit /b 1
)
:: Read the HTTP status code returned by curl
set /p "httpCode=" < "%TEMP%\teams_response.tmp"
del "%TEMP%\teams_response.tmp" 2>nul
if "!httpCode!"=="200" (
echo [SUCCESS] Alert sent to Microsoft Teams.
) else (
echo [ERROR] Teams returned HTTP status !httpCode!. Verify your webhook URL and JSON payload.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Adding Action Buttons (MessageCard Details)
Teams messages can include clickable buttons and markdown formatting. Here is how to construct a more complex JSON payload that includes a link to a log file:
@echo off
setlocal enabledelayedexpansion
set "webhookUrl=https://YOUR_TENANT.webhook.office.com/webhookb2/YOUR_WEBHOOK_URL_HERE"
set "server=SRV-EXCHANGE-01"
:: Markdown bold (**text**)
set "json={ \"@type\": \"MessageCard\", \"themeColor\": \"DC3545\", \"title\": \"Service Down Alert\", \"text\": \"**%server%** is not responding to ping requests.\", \"potentialAction\": [ { \"@type\": \"OpenUri\", \"name\": \"View Monitoring Dashboard\", \"targets\": [ { \"os\": \"default\", \"uri\": \"http://monitor.local\" } ] } ] }"
echo Sending alert to Microsoft Teams...
:: Use curl.exe explicitly to avoid the PowerShell alias conflict
curl.exe -s -o nul -w "%%{http_code}" -X POST -H "Content-type: application/json" -d "%json%" "%webhookUrl%" > "%TEMP%\teams_response.tmp"
:: Capture the exit code immediately
set "curlResult=!errorlevel!"
if !curlResult! neq 0 (
echo [ERROR] curl failed with exit code !curlResult!. Check network connectivity.
del "%TEMP%\teams_response.tmp" 2>nul
pause
exit /b 1
)
set /p "httpCode=" < "%TEMP%\teams_response.tmp"
del "%TEMP%\teams_response.tmp" 2>nul
if "!httpCode!"=="200" (
echo [SUCCESS] Alert sent to Microsoft Teams.
) else (
echo [ERROR] Teams returned HTTP status !httpCode!. Verify your webhook URL and JSON payload.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Why Send Teams Messages from Batch?
- IT Operations Integration: Many enterprise IT departments live in Teams. Script failures route directly to the Tier 1 support channel rather than getting lost in generic email inboxes.
- Color-Coded Status: Using the
themeColorparameter, you can send visual cues: green for success logs, red for critical errors, and yellow for capacity warnings. - Actionable Alerts: Adding
potentialActionbuttons allows administrators to directly click through to a restart portal or log viewer straight from the chat interface.
Important Considerations
- JSON Precision: The Teams MessageCard format is strict. Missing commas or unescaped quotes in your message text will cause the POST action to receive a
400 Bad Requestor simply fail silently. - Security: Like any webhook, the URL contains the authentication token. Restrict read access to scripts containing Teams webhook URLs so unauthorized users cannot spam your channels.
- PowerShell Alternative: If you encounter issues escaping complex JSON quotes in Batch, transitioning the payload construction and
Invoke-RestMethodto PowerShell significantly simplifies the syntax.
Conclusion
Transmitting Microsoft Teams messages from a Batch script guarantees that critical infrastructure updates reach the right groups instantly. By utilizing the Office 365 Incoming Webhook standard and native HTTP tools, you enhance your automated tasks with highly visible, color-coded, and interactive communication.