Source: https://cli.nylas.com/guides/new-mgusermessage-powershell

# New-MgUserMessage: Create Outlook Drafts

You typed Send-MgMessage and PowerShell said the term is not recognized. The cmdlet doesn't exist. Microsoft Graph PowerShell splits draft email work across New-MgUserMessage (create the draft), Update-MgUserMessage (edit it), and Send-MgUserMessage (dispatch it). This guide walks the full draft workflow: hashtable parameters, the scopes each step needs, attachments, and the 2-command CLI equivalent.

Written by [Prem Keshari](https://cli.nylas.com/authors/prem-keshari) Senior SRE

Updated June 6, 2026

> **TL;DR:** `New-MgUserMessage` creates a draft in the Drafts folder (Graph returns `201 Created`, scope `Mail.ReadWrite`). `Send-MgUserMessage` sends that draft (`202 Accepted`, scope `Mail.Send`). `Send-MgMessage` is not a real cmdlet. From the terminal, [`nylas email drafts create`](https://cli.nylas.com/docs/commands/email-drafts-create) and `drafts send` do the same in 2 commands.

Command references used in this guide: [`nylas email drafts create`](https://cli.nylas.com/docs/commands/email-drafts-create), [`nylas email drafts list`](https://cli.nylas.com/docs/commands/email-drafts-list), and [`nylas email drafts send`](https://cli.nylas.com/docs/commands/email-drafts-send).

## What does New-MgUserMessage do?

`New-MgUserMessage` is the Microsoft Graph PowerShell cmdlet that creates a draft email in a mailbox without sending it. It wraps the Graph endpoint `POST /users/{id}/messages`, which per the [create message reference](https://learn.microsoft.com/en-us/graph/api/user-post-messages) lets you "create a draft of a new message in either JSON or MIME format" and "update the draft later to add content to the body or change other message properties." On success Graph returns `201 Created` plus the full message object, including the draft's ID — the handle every later step uses.

The required permission is `Mail.ReadWrite` for delegated and application auth alike. That split matters for least-privilege setups: a script that only stages drafts for human review never needs `Mail.Send` at all. The [Send-MgUserMail guide](https://cli.nylas.com/guides/send-mgusermail-powershell) covers the immediate-send path; this page covers the 2-step draft workflow.

## Why is Send-MgMessage not recognized?

`Send-MgMessage` doesn't exist in any Microsoft.Graph module, which is why PowerShell answers with `CommandNotFoundException`. Graph PowerShell cmdlet names encode the full resource path, and messages live under users — so every mail cmdlet carries the `User` segment. Three real cmdlets cover sending and drafting, and the wrong guess is usually a blend of two of them.

| Cmdlet | Graph endpoint | What it does |
| --- | --- | --- |
| `New-MgUserMessage` | `POST /users/{id}/messages` | Creates a draft; returns the message object (201) |
| `Send-MgUserMessage` | `POST /users/{id}/messages/{id}/send` | Sends an existing draft (202, empty body) |
| `Send-MgUserMail` | `POST /users/{id}/sendMail` | Composes and sends in one call — no draft step |
| `Send-MgMessage` | — | Does not exist; `CommandNotFoundException` |

Quick disambiguation: sending one email now means `Send-MgUserMail`. Staging email for review before it leaves the mailbox means `New-MgUserMessage` followed by `Send-MgUserMessage`. Run `Get-Command -Module Microsoft.Graph.Mail` to list the roughly two dozen mail cmdlets actually installed and stop guessing names.

## How do you create a draft with New-MgUserMessage?

Creating a draft takes 1 cmdlet call with hashtable parameters for the body and recipients. The draft appears in the mailbox's Drafts folder immediately, visible in Outlook, and stays there until something sends or deletes it. Capture the return value — the draft ID in `$draft.Id` is required for every follow-up step.

```powershell
Connect-MgGraph -Scopes "Mail.ReadWrite"

$draft = New-MgUserMessage -UserId "me@contoso.com" `
  -Subject "Q3 capacity plan — for review" `
  -Body @{
    ContentType = "Text"
    Content     = "Draft of the capacity plan summary. Numbers attached."
  } `
  -ToRecipients @(
    @{ EmailAddress = @{ Address = "ops-lead@contoso.com" } }
  )

$draft.Id   # e.g. AAMkAGI2...  — keep this
```

Editing the draft later uses `Update-MgUserMessage` with the same hashtable shapes (its [cmdlet reference](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.mail/update-mgusermessage) documents every updatable property). That two-phase pattern (create now, refine later) is what the draft endpoint exists for, and it's the property the one-shot `Send-MgUserMail` can't give you.

## How do you add an attachment to the draft?

Attachments are added to an existing draft with `New-MgUserMessageAttachment`, documented in its [cmdlet reference](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.mail/new-mgusermessageattachment). The file content travels base64-encoded inside a `#microsoft.graph.fileAttachment` object, so the 2 lines below read the file as bytes and encode them with `[Convert]::ToBase64String` before the upload.

```powershell
$bytes = [System.IO.File]::ReadAllBytes("C:\reports\capacity.xlsx")

New-MgUserMessageAttachment -UserId "me@contoso.com" -MessageId $draft.Id `
  -BodyParameter @{
    "@odata.type" = "#microsoft.graph.fileAttachment"
    Name          = "capacity.xlsx"
    ContentBytes  = [Convert]::ToBase64String($bytes)
  }
```

## How do you send the draft with Send-MgUserMessage?

`Send-MgUserMessage` dispatches the draft by ID. The underlying [message: send reference](https://learn.microsoft.com/en-us/graph/api/message-send) states it sends "an existing draft message" (new, reply, reply-all, and forward drafts all qualify) and "saves the message in the Sent Items folder." Success returns `202 Accepted` with an empty response body, so don't parse the output for a message object that isn't there.

```powershell
# Requires the Mail.Send scope (Mail.ReadWrite alone cannot send)
Connect-MgGraph -Scopes "Mail.ReadWrite", "Mail.Send"

Send-MgUserMessage -UserId "me@contoso.com" -MessageId $draft.Id
```

The scope boundary is the workflow's security feature. A nightly report generator can run under `Mail.ReadWrite` and produce drafts all week, while the send step lives in a separate session, or with a separate human, holding `Mail.Send`. Calling `Send-MgUserMessage` without that scope fails with `ErrorAccessDenied`, which is exactly the failure you want from a compromised draft generator.

## How does the CLI handle the same draft workflow?

The `nylas email drafts` command group covers the create-review-send loop in 2 commands with no hashtable scaffolding, and the same syntax works on Gmail, iCloud, and IMAP accounts, not just Outlook. Authentication is one `nylas auth login` instead of an Entra app registration. The hashtable draft above becomes a single flag-based call.

```bash
# Create the draft
nylas email drafts create \
  --to ops-lead@contoso.com \
  --subject "Q3 capacity plan — for review" \
  --body "Draft of the capacity plan summary."

# List pending drafts, grab the ID
nylas email drafts list --json | jq -r '.[] | "\(.id)  \(.subject)"'

# Send after review
nylas email drafts send DRAFT_ID
```

This draft-then-send separation is also the human-in-the-loop pattern for AI agents: the agent holds only the draft tool, a person runs the send. The [prompt injection defense guide](https://cli.nylas.com/guides/email-prompt-injection-defense) builds that argument in full.

## Next steps

- [Send-MgUserMail: Graph Email in PowerShell](https://cli.nylas.com/guides/send-mgusermail-powershell) — the one-call send path, delegated and app-only auth
- [Replace Send-MgUserMessage](https://cli.nylas.com/guides/replace-send-mgusermessage) — migrate draft-send scripts to a shorter CLI pipeline
- [Manage email drafts from the CLI](https://cli.nylas.com/guides/manage-email-drafts-cli) — list, edit, and batch-send drafts across providers
- [PowerShell email guide](https://cli.nylas.com/guides/powershell-email-guide) — every method for sending email from PowerShell, compared
- [Full command reference](https://cli.nylas.com/docs/commands) — flags and examples for every drafts subcommand
