An alternative check, less "clean" but closer to what the question tried to achieve.
Remember that [ at its core is just a command. It always accepts a specific number of parameters, and exits with either 0 (success) or 1 (failure) exit status, as all other commands do. For example, when you're comparing two strings, the syntax is[, string 1, ==, string 2, ].
Right now you're using this as the if condition:
[ prlctl list --info ubuntu-vm | grep State == "State: running" ]
But it's ambiguous in several ways. How would [ know that on the left you have a command to run and not a fixed string? How would it know that the == is the string comparison operator, rather than just an argument to grep? How would it know that the | is part of the left-hand value, rather than separating the command into [ prlctl list --info ubuntu-vm and grep State == "State: running" ]?
So the left side needs to be quoted as well. Also, since you want to compare the output of that command, rather than the worlds "prctl list --info..." themselves, you need the $(…) operator:
[ "$(prlctl list --info ubuntu-vm | grep State)" == "State: running" ]