tl;dr
Therefore, try the following:
$Firstname = "Test"
$Lastname = "User"
$email= '[email protected]'
$json=@"
{\"user\": {\"name\": \"$Firstname $Lastname\", \"email\": \"$email\"}}
"@
curl.exe https://mydomain.zendesk.com/api/v2/users.json -d $json -H 'Content-Type: application/json' -X POST -v -u myuser:mypass
Using a double-quoted (expandable) here-string (@"<newline>...<newline>"@) makes specifying embedded " instances easy (no escaping for the sake of PowerShell's own syntax required), while still expanding variable references.
You're clearly aware of the - unfortunate - additional need to \-escape the " instances - update: no longer needed in PowerShell (Core) 7 v7.3+; see this answer - but just to explain why that is needed:
When passing arguments to an external program, PowerShell, after its own parsing and interpolation, wraps those resulting arguments that contain spaces in double quotes ("...") when concatenating them to form the process command line to launch the external utility with. Unfortunately, it does so without escaping any embedded " characters, which in effect results in their getting discarded; the only way to preserve them is to \-escape them - see this answer for more information.
If you wanted to do it inline with a regular double-quoted string, you'd have to escape the " instances for PowerShell too (as `"), resulting in the awkward combination \`":
"{\`"user\`": {\`"name\`": \`"$Firstname $Lastname\`", \`"email\`": \`"$email\`"}}"
Alternative:
Ryan himself points out in a comment that using a hashtable is the better alternative for constructing the data and then converting it to JSON with ConvertTo-Json and feeding it to curl via stdin is an alternative that avoids the quoting headaches:
# Create data as PS hashtable literal.
$data = @{ user = @{ name = "$Firstname $Lastname"; email = "[email protected]" } }
# Convert to JSON with ConvertTo-Json and pipe to `curl` via *stdin* (-d '@-')
$data |
ConvertTo-Json -Compress |
curl.exe mydomain.zendesk.com/api/v2/users.json -d '@-' -H "Content-Type: application/json" -X POST -v -u myuser:mypass