Otávio Caldonazo's helpful answer provides an effective solution, but it's worth explaining a few things:
Unless there are security concerns (someone having placed a nonstandard, malicious cmd.exe / powershell.exe executable in a folder listed in the %PATH% / $env:PATH environment variable that preempts the standard executables), it is simpler to use the executable file name alone, i.e., just cmd.exe / powershell.exe - this also avoids problems with non-standard Windows installations whose root is not C:\Windows.
- Also, given that you're specifying a full path via
.FileName, the .WorkingDirectory property is effectively ignored with .Verb set to runas, because .WorkingDirectory then doesn't actually set the working directory, but specifies where to find the executable, if specified by name only - however, lookups in %PATH% / $env:PATH are still performed.
While the /c parameter to pass a command to the shell invoked happens to work with PowerShell's CLI too, PowerShell generally use sigil - to prefix parameter names; thus,
-c (short for -Command) is the better choice.
- Additionally, given that PowerShell loads its
$PROFILE initialization file by default (even when invoked with -Command or -File, even though that is generally undesirable), it's best to use -NoProfile -Command ... instead.
Generally - if you don't need elevation (running as an admin) - as an alternative to the - slow - creation of a child process via powershell.exe, consider use of the PowerShell SDK (API), which enables faster in-process execution while also enabling more fine-grained capturing of output streams (which you don't seem to be interested in in your particular scenario; while System.Diagnostics.ProcessStartInfo allows you to capture stdout and stderr output via the .RedirectStandardOutput and .RedirectStandardError properties, note that PowerShell has additional output streams).
Based on the above, I suggest doing the following:
var proc = new System.Diagnostics.ProcessStartInfo();
proc.UseShellExecute = true;
proc.Verb = "runas";
proc.FileName = @"powershell.exe";
proc.Arguments = "-NoProfile -Command " + command;
proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
var p = System.Diagnostics.Process.Start(proc);
p.WaitForExit();
Or, more concisely:
using System;
using System.Diagnostics;
var proc = new ProcessStartInfo()
{
UseShellExecute = true,
Verb = "runas",
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "powershell.exe",
Arguments = "-NoProfile -Command " + command
};
Process.Start(proc).WaitForExit();