@ShanePerrien
Four things jump out, but I'm not sure that any of them are the culprit. The fourth one has a higher probability of being the issue than the first three.
You are not encoding your query string -- or at least not when you're logging it. That may not be the issue, though. I just tested the API call (not using Powershell) and it worked. I did have to convert my \r\n to %0D%0A to get it to recognize it. If my URL contained a question mark, it was okay, but if there was an ampersand, then it would have to be encoded, otherwise anything after it gets stripped. Your example NSSE code looks like it should be fine.
The second thing that jumps out is to make sure that you are using your school's Canvas hostname. You put yourschool.test.instructure.com. At first, I just figured you were doing that to hide your school's domain, but then you just posted an access token in a public forum, so I'm not sure. If that is a long term token, it should be immediately deleted. I still don't think this is it, the message that I sent successfully in the first part failed with a 404 error (not found) rather than a 400 (bad request) when I tried using it.
The third thing is to make sure that person the token belongs to has a relationship with the person you're sending it to. My token is to an admin account and can see everyone. But if I was a non-admin teacher trying to send to a student, it wouldn't work. I would probably get a 401 code (unauthorized) rather than 400 if this happened. I did test sending with a bogus token and got the 401 error.
The fourth thing I would check is to make sure there is not an embedded newline in what you are sending. I don't know if it's the way you pasted into the Community or the way it is in your code, but you have a line break after the ? before the recipients parameter. I would make sure that everything within a double quotes is on a single line, using a + to concatenate multiple strings together if necessary. Of all the things I've seen and considered, this is the most likely to generate a 400 (bad request) code instead of a different message.
Here's what I would do.
Make sure there are not multiple lines within double quotes and try it again. If that doesn't work, then try this:
Send yourself (rather than someone else) a very simple message. Don't make it part of a CSV import, just a very short script to test the sending. Don't put in any newlines don't put in the link. I used something like this (but with my real Canvas ID). Not shown, but you do need the authorization header in there.
POST <instance>/api/v1/conversations?recipients[]=12345&subject=test&body=test+message
If that works, then start making it more complex. Add in the new lines and test again. If that works, then add in the link. If it breaks somewhere along the way, then we know where to look.