The script block that is executed via Invoke-Command does not have access to the current environment state, it is run in a separate process. If you were running the command on your local computer it would work.
The issue is that the string "select volume $volumeNum" is not being evaluated until it is executed on the remote machine. So it is looking for the value in the environment of the current process on the remote machine and $volumeNum is not defined there.
PowerShell provides a mechanism for passing arguments via Invoke-Command. This works from my local machine to a remote:
Invoke-Command -ComputerName $ip -ScriptBlock { param($x) "hello $x" } -ArgumentList "world"
I believe a similar approach would work for you:
Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {param($volumeNum) "select volume $volumeNum" | diskpart} -ArgumentList $volumeNum