Workflow Automation

Building a ticketing workflow in Microsoft Teams

Support-style workspace with headphones and a laptop

I am Priya Shah. This essay is about a ticketing workflow that lives inside Microsoft Teams without pretending Teams is a full ITSM suite. A List or a Form holds the ticket. A channel gets the signal. Someone owns the work. Status is visible. An age clock shows how long the ticket has been open. The requester hears when it closes. I am writing as an independent practitioner, not as Microsoft and not as a partner.

Email still sneaks in. People love a personal thread they can bury. That habit is exactly why tickets vanish.

Why email fails as a ticket store

I watched a facilities team at Harborline Labs lose three requests in one week. Not dramatic outages. Small things. A badge printer jammed. A meeting room thermostat stuck on arctic. A visitor laptop needed a guest network voucher. Each request started as an email to whoever felt approachable that morning. Replies forked. Someone said they would handle it and then left for a conference. The requester followed up in a different thread. Nobody could answer a simple question: what is open, who owns it, and how old is it?

Email is great for conversation. It is a weak queue. Search depends on memory. Ownership is implied. Status lives in prose. You cannot sort by age without inventing a spreadsheet on the side, and that spreadsheet becomes a second source of truth that drifts within days.

Teams is not magic. It becomes useful when you give tickets a structured home and use channels as the notification surface, not as the only database.

Pick a ticket store: List or Forms

For most internal request desks I prefer a Microsoft List. Columns I tend to start with:

  • Title, short and concrete
  • Requester, person column
  • Category, choice field
  • Priority, choice field with a small fixed set
  • Status, choice: New, Assigned, In progress, Waiting on requester, Closed
  • Assignee, person column
  • Created, automatic
  • ClosedOn, date, empty until close
  • Resolution notes, multiline text

Forms work when intake needs a friendlier face for people who never open a List. A Form can write into a List or Excel. I still want the durable store to be something you can filter, sort, and automate against. If Form answers dump into a personal OneDrive workbook that only one coordinator owns, you rebuilt email with extra steps.

Keep categories boring and few. Hardware, Access, Facilities, Other is enough for a first month. Fancy taxonomies arrive later, after you see what people actually type.

Required fields matter. If Assignee can be blank forever, the queue becomes a wish list. If Status can be free text, reporting dies. Constrain the choices.

Channel notification without drowning people

When a new item lands, post a short message to a dedicated tickets channel. Include the title, requester, category, link to the List item, and current status. One Adaptive Card style message is nicer than a wall of raw field dumps, but even a plain message with a deep link beats silence.

Choose the channel carefully. A #desk-tickets channel that only exists for this purpose is healthier than posting into #general. People mute general. They will mute you too if every printer jam becomes a party announcement.

Do not @everyone for routine tickets. Mention the assignee after assignment, or mention a rota group if you use one. Noise trains people to ignore the channel, and then you are back to email.

At Harborline Labs we started with a flow that posted every field including an essay-length description. The channel became unreadable by Wednesday. We cut the post to five lines and moved detail behind the List link. Volume dropped. Attention rose. Weird how that works.

Status cards and assignment

Status should change in the List first. The card or channel message is a mirror, not a second ledger. When someone claims a ticket, they set Assignee to themselves and Status to Assigned or In progress. A follow-up message can say who took it. If your automation can update the original card, great. If not, a reply in the thread with the new status is fine. Consistency beats elegance.

Assignment rules I like in practice:

  1. Unassigned New items sit in a morning triage pass.
  2. One person owns triage that day, rotating weekly.
  3. Triage sets category if blank, sets priority if blank, assigns an owner.
  4. The owner moves Status as work progresses.
  5. Waiting on requester pauses active work without closing.

Waiting on requester is the status people forget. Without it, age clocks look terrifying for tickets that are blocked on a screenshot the user never sent. Teach the team that Waiting is honest, not lazy.

Private details stay in the List or in a private reply to the requester. Public channel text should not include passwords, badge numbers, or medical-sounding anything. This is an office ticket desk, not a dumping ground.

A simple age clock, not an SLA product promise

Age is just time since Created while Status is not Closed. You can show it in a List view with a calculated column, or compute it in a weekly digest, or glance at Created and do the math like a human. What I refuse to do in a first rollout is brand that number as a contractual SLA.

Why the caution? Because the moment you publish "all tickets close in four hours," someone will treat a cosmetic request like a fire. Then leadership asks for dashboards, green and red tiles, and suddenly your helpful Teams lane is a political scoreboard. Start with visibility. "This request is three days old" is useful. "We violated tier-two platinum response" is theater unless you already have a real service catalog and staffing model.

A practical age habit: every Monday the triage owner sorts open items by Created ascending and clears or assigns the oldest five before touching anything new. That single ritual does more than a fancy chart.

If you later need targets, write them as internal working goals for specific categories, with exceptions for Waiting on requester. Put that in a team wiki tab. Do not stamp it on every Adaptive Card like a marketing badge.

Closing the loop with the requester

Closed is not Closed until the requester knows. Update Status to Closed, set ClosedOn, write Resolution notes in plain language, then notify the requester in chat or by posting in the original thread with a short summary and the List link. Ask one question if needed: does this match what you needed? Then stop. Do not open a satisfaction survey empire on day one.

I have seen teams close tickets in the List and never tell anyone. Requesters reopen the same issue by email. The age clock looks great. Reality looks like duplicate work.

Also close the loop when you cannot help. "This needs a facilities vendor; here is who owns that" is a valid close if you transfer ownership clearly. Orphaned tickets that sit In progress forever are worse than an honest Close with a pointer.

Harborline's thermostat ticket finally closed when the assignee posted: adjusted setpoint, room B12, asked requester to confirm by Friday. Requester replied thanks. Status Closed. Age was four days, mostly Waiting on building access. Nobody pretended it was a two-hour miracle. People trusted the desk more after that than after any slogan about lightning response.

Automation shape that stays maintainable

A flow on item created posts to the channel. A flow on Status or Assignee change can notify the assignee and optionally the requester. A scheduled flow can list open items older than seven days into a digest message for the triage owner. Keep identities stable: prefer a service account or team-owned connection, not a single hero's personal credentials that die when they leave.

Test with fake tickets. Break the Form. Leave Assignee empty on purpose. Make sure the channel post still includes a link. Make sure ClosedOn only fills on close. Then train the desk for thirty minutes with three sample scenarios. Record the session. Pin it in the channel.

Resist the urge to integrate six systems in week one. Teams plus List plus light Power Automate is already a complete story for many internal desks. Add ServiceNow later if you truly need it, not because a vendor slide said so.

Habits that keep the queue honest

Publish a one-page "how to request help" note: use the Form or List, do not email individuals, include location and screenshots when relevant. When someone emails anyway, reply with the Form link and create the ticket for them once as a courtesy. The second time, still be kind, but do not become their private inbox.

Managers will ask for reports. Give them a List view: open by assignee, closed last week, oldest open. Views beat exported mystery spreadsheets that go stale by lunch.

Review categories monthly. If Other is half the queue, your choices are wrong. Split what people actually need. Merge ghosts nobody uses.

Archive closed items with List views filtered to open work for daily operators. Keep Closed visible for search and audit, just not in the primary working view.

That is the ticketing pattern I trust inside Teams. Structured store. Quiet channel signal. Clear assignment. Honest status. Simple age awareness without faux SLA theater. A human close message to the requester. Email remains for conversation when needed. It stops being the place where work goes to disappear.

One more Harborline detail because specifics stick. Their Form asked for building and floor. That alone cut half the clarifying chats. The List view for triage sorted New first, then Waiting. Assignees got a personal chat only when a ticket sat Assigned more than two business days with no Status change. Not a punishment. A nudge. The team of four handled the volume without hiring a coordinator, which was the quiet win. No income fantasy attached. Just fewer lost requests and fewer awkward "did you see my email" moments in the hallway.

If you copy this, start smaller than you want. One Form, one List, one channel, one triage owner, one close message template. Expand after two calm weeks. Calm is the metric. Not ticket count vanity.