In my opinion the reason $bytes ends up empty is that if your attachment file is over about 3-4MB, Microsoft Graph just skips filling in the ContentBytes to avoid making the response too heavy.
Can you try with a smaller file (under 3MB) to see if ContentBytes gets populated?