AI Tools Academy
Power Automate 0/18

Phase 5 · Power Automate · Level 2 · Practitioner

Just enough expressions to unblock yourself

Concept · 11 minLast checked against the live product: 13 July 2026

30-second recall from earlier lessons
You show a colleague the Ask Gemini side panel in Gmail, but on their account there's no such button anywhere. What's the most likely explanation?
The Ask Gemini panel summarises an open email thread and confidently states the deadline was moved to 25 August. You're about to act on it. What's the wise habit?

By the end, you'll be able to…

  • Recognise when a dynamic-content chip isn't enough and an expression is needed
  • Write simple expressions for dates, text and conditions from a small toolkit
  • Read an expression someone else wrote and work out what it does

Why it matters

Most flows never need an expression; dynamic content covers them. But every so often you hit a wall: you need today's date plus seven days, or a name in capitals, or 'is this field empty'. Expressions are the small formulas that get you past those walls. You don't need to learn hundreds; a dozen cover almost everything a practitioner meets. This lesson gives you that dozen, with worked examples you can adapt.

When you actually need an expression

Ninety per cent of the time, you build a flow by picking dynamic content, the chips that stand for "the sender's email", "the attachment's name", "today's response". Chips are enough because you're just moving a value from one step to another unchanged.

An expression is what you reach for when you need to transform a value rather than just pass it along. Three situations cover nearly all of them:

  • Dates and times: "seven days from now", "the date only, no time", "the year".
  • Text: "in capitals", "trimmed of spaces", "joined together", "just the bit before the @".
  • Conditions: "is this empty?", "does this contain that?", combined with "and"/"or".

An expression is a small formula written with a function (a named operation like addDays or toUpper) followed by its inputs in brackets. You type them into the same fields where you'd otherwise drop a chip, using the expression tab of the content picker. That's the whole idea: same slot, but a formula instead of a raw value.

Dates: the most common wall

Date maths is where new builders hit the wall first, because "today plus a week" isn't a chip; you have to compute it. The building block is utcNow(), which is the current date and time. From there:

A due date seven days from nowPower Automate
addDays(utcNow(), 7)

Why this works: addDays takes a starting date and a number of days. Wrapping utcNow() as the start means 'seven days from whenever this runs', exactly what a 'respond within a week' due date needs. This one expression solves a huge share of real date problems.

Raw dates from utcNow() come with a full timestamp and are in an international format, which looks wrong in a UK-facing email. formatDateTime fixes both, reshaping a date into the pattern you specify:

Today's date as UK-style day/month/yearPower Automate
formatDateTime(utcNow(), 'dd/MM/yyyy')

Why this works: formatDateTime reshapes a date using a pattern: 'dd/MM/yyyy' gives 13/07/2026. Capital MM is the month; lowercase mm would be minutes, a classic mix-up. Use this whenever a date is going in front of a person rather than another system.

You can combine them: formatDateTime(addDays(utcNow(), 7), 'dd/MM/yyyy') gives a tidy UK date one week out. Nesting one function inside another, inner brackets first, is how expressions grow. Other useful date functions: addDays also takes negatives (addDays(utcNow(), -1) is yesterday), and there are addHours and addMinutes for finer control.

Text: tidy it, join it, slice it

Text expressions clean up and reshape strings. The four you'll use most:

A name forced to capitalsPower Automate
toUpper('leah bennett')

Why this works: toUpper turns text into capitals (toLower does the reverse). Handy for a reference code or a heading where you want consistent case regardless of how someone typed it. Point it at a dynamic-content value in place of the example text.

Two pieces of text joined togetherPower Automate
concat('New leave request from ', 'Leah Bennett')

Why this works: concat glues values end to end, in order. Here it builds a subject line by joining a fixed label and a name; in a real flow you'd replace the second part with a dynamic-content value. It's how you assemble sentences from parts.

trim(...) strips stray spaces from the start and end of text, invaluable when data comes from a form where people add accidental spaces. And when you need only part of a string, split breaks it up: split('leah.bennett@fernway.example', '@') cuts an email at the @ into two pieces, so you can take the name part before it. You won't memorise these; you'll recognise the shape and look up the exact one.

Conditions: asking yes/no questions

Conditions decide which way a flow branches, and a few functions make them precise. The most useful is empty(...), which answers "is this blank?", perfect for catching a form field nobody filled in:

Is a field empty?Power Automate
empty('')

Why this works: empty returns true when a value is blank. Used in a condition, it lets a flow treat 'no comment supplied' differently from a real comment, for instance skipping a step or flagging the gap. Replace the example text with the field you're checking.

contains(...) asks whether one piece of text appears inside another: contains('urgent: server down', 'urgent') is true. And you combine tests with and(...) and or(...), each taking two or more conditions: and(...) is true only when every part is true, or(...) when any part is. if(...) goes one step further and picks between two results: if(empty(comment), 'No comment', comment) returns a friendly placeholder when the field is blank and the real comment otherwise.

Combining two conditionsPower Automate
and(greater(amount, 500), equals(category, 'Travel'))

Why this works: and takes two tests and is true only if both are. Here it checks an amount is over 500 AND a category equals 'Travel', the kind of compound rule real approvals need. Swap the literals for dynamic-content values; the structure is what to learn.

Reading someone else's expression

Half of practitioner-level skill is reading expressions, because you'll inherit flows and Copilot writes expressions too. The trick is to work from the inside out. Take formatDateTime(addDays(utcNow(), -7), 'dd/MM/yyyy'): the innermost part is utcNow() (now), then addDays(..., -7) (seven days ago), then formatDateTime(..., 'dd/MM/yyyy') (that date, UK-formatted). Read inner brackets first and each layer explains the next. If you can narrate an expression back in plain English like that, you can trust it, or spot that it's wrong.

A practical tip: in the designer you can switch a step to view its underlying definition ("peek code" or the code view), which reveals the real internal names of dynamic-content values, useful when an expression needs to refer to a value the chip picker hides. You rarely need it, but knowing it exists means an unusual field never fully blocks you.

Try it now

Common mistakes

  • Using an expression when a chip would do. If you only need to pass a value along unchanged, use the dynamic-content chip. Expressions are for transforming values, not moving them.
  • Lowercase mm for the month. In formatDateTime, MM is the month and mm is minutes. It's the single most common date bug, and it produces a plausible-looking wrong date.
  • Mismatched brackets. Every ( needs its ). A nested expression with a missing bracket won't save; count them from the inside out if the editor complains.
  • Trusting an expression you can't read. Copilot and colleagues both write expressions, and a formula you paste in without understanding might compute the wrong thing perfectly quietly: an off-by-one date, the wrong field. If you can't narrate it back in plain English, test it in a Compose step with known inputs before you rely on it. A confident-looking expression is not a correct one.

Keeping current

The function names here are long-standing and shared with Azure Logic Apps, so they change little. For the full list and more worked patterns, see Microsoft's Use expressions in conditions and the Expression cookbook on Microsoft Learn, plus the complete reference for functions in expressions. Accurate as of 13 July 2026.