Keep in mind that PowerShell handles objects and not just text. While in normal batch files you could set a variable to a string and then just use it as a command:
set Foo=dir /b
%Foo%
... this doesn't work in PowerShell. Thus your assignment of $Start already creates the new process since the command after the = is run and its result assigned to $Start.
Furthermore you're complicating things needlessly. I'd suggest the following instead:
$Running = Get-Process prog -ErrorAction SilentlyContinue
if (!$Running) { Start-Process C:\utilities\prog.exe }
Since Get-Process returns an object (which evaluates to $true) or $null (which evaluates to $false) you can simplify the check like shown above. This is called type coercion, since the if statement expects a boolean value and the rules on what will be treated as $true and $false are very consistent in such cases as above. And it reads nicer.
I also used the Start-Process cmdlet instead of WMI to create the new process. You could even use the following:
if (!$Running) { C:\utilities\prog.exe }
if the application is not a console application (and thus would block the PowerShell script until it exits). PowerShell is still a shell, so starting programs is something that works natively very well :-)
You could even inline the $running variable, but I guess a comment would be in order to clarify what you do, then.