0

I'm trying to run this command using Power shell:

Get-WmiObject Win32_PnPSignedDriver -filter "DeviceName = 'Microsoft Bluetooth LE Enumerator'" | select -ExpandProperty driverversion

When running it manually, it works fine, but when I run it via the code, I'm receiving this error:

Get-WmiObject : A positional parameter cannot be found that accepts argument 'Microsoft Bluetooth LE Enumerator'.
At line:1 char:1
+ Get-WmiObject Win32_PnPSignedDriver -filter DeviceName = 'Microsoft B ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Here is my code:

public static string PlatformModelCommand => $ "Get-WmiObject Win32_PnPSignedDriver -filter \"DeviceName = \'Microsoft Bluetooth LE Enumerator\'\" | select -ExpandProperty driverversion";


string projectName = RunCommandUtil.RunPsProcess(PlatformModelCommand);

public static string RunPsProcess(string arguments)
        {
            return RunProcess("powershell.exe", arguments);
        }

public static string RunProcess(string fileName, string arguments) {
  Process process = new Process();
  process.StartInfo.FileName = fileName;
  process.StartInfo.UseShellExecute = false;
  process.StartInfo.Arguments = arguments;
  process.StartInfo.RedirectStandardOutput = true;
  process.StartInfo.RedirectStandardError = true;
  process.Start();
  var output = process.StandardOutput.ReadToEnd();
  output += process.StandardError.ReadToEnd();
  process.WaitForExit();
  return output;
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
user
  • 136
  • 2
  • 16
  • What does `RunPsProcess` do? Why did you post the source of `RunProcess` when that isn't being used? Also, are you running PowerShell in-proc or not? – Dai Jun 06 '21 at 15:21
  • Sorry, forgot to add one func, edit my question – user Jun 06 '21 at 15:26

2 Answers2

1

If you run this in Powershell:

Get-WmiObject Win32_PnPSignedDriver -filter "DeviceName = \'Microsoft Bluetooth LE Enumerator\'" | select -ExpandProperty driverversion

you will also get an error:

Get-WmiObject : Invalid query "select * from Win32_PnPSignedDriver where DeviceName = \'Microsoft Bluetooth LE Enumerat
or\'"
At line:1 char:1
+ Get-WmiObject Win32_PnPSignedDriver -filter "DeviceName = \'Microsoft ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

I do not know why you did put \ before the single quotes?

But maybe you should have used System.Management.Automation.Powershell, which seems to better fit the task ?

Luuk
  • 12,245
  • 5
  • 22
  • 33
  • I upvoted this answer because PowerShell should be invoked via `System.Management.Automation.Powershell` instead of `Process`. – Dai Jun 06 '21 at 16:33
1

If I understood correctly, you just want to pass the literal command to PS. If that's so you could drop the interpolation and the single quotes' escaping:

public static string PlatformModelCommand => @"""Get-WmiObject Win32_PnPSignedDriver -filter \""DeviceName = 'Microsoft Bluetooth LE Enumerator'\"" | select -ExpandProperty driverversion""";

EDIT. Since you're passing the command as an argument to powershell.exe, you'll have to escape the inner quotes. I agree with Luuk in that you might have a better time using MS's abstractions for this problem. There are some good examples of that approach on SO as well.