4

When I run the following command via the PowerShell console, it works just fine:

Get-ProcessMitigation -Name iexplore.exe | Select-Object -ExpandProperty ASLR | Select-Object -ExpandProperty BottomUp

However, if I run the same command within a C# method like the following:

public static List<PSObject> RunLocalPowerShellScript(string p_script)
        {
            using var psInstance = PowerShell.Create();
            psInstance.AddScript(p_script);

            IEnumerable<PSObject> commandOutput = null;
            try
            {
                commandOutput = psInstance.Invoke();
            }
            catch (Exception e)
            {
                var exc = e.Message;
            }

            if (psInstance.HadErrors)
            {
                var errorOutput = string.Join(Environment.NewLine, psInstance.Streams.Error.Select(e => e.ToString()));
            }

            return commandOutput.ToList();
        }

and pass the command as the argument, it fails (note the above code needs C# 8 to run properly, but wrapping it in a using block C# 7-style causes the same issue).

The error says This script must be run on Windows 10 or greater.. The issue being that I'm running on Windows 10 1903. It happens both in a .NET Framework project using the Microsoft.PowerShell.5.ReferenceAssemblies package from NuGet, and in .NET Core 3 using the Microsoft.PowerShell.SDK package from NuGet. Other PowerShell commands run without any issue using the exact same method, and the same command runs without issues in a slightly tweaked remote version of our method where we set the remote runspace to run against remote machines. This problem seems to only be limited to running on the local machine.

Does anyone have any insight on this issue? It wouldn't be the first bug we've found at the office in the Get/Set-ProcessMitigation modules, but I figure it's always good to get some outside eyes looking at things.

Matthew Heimlich
  • 343
  • 2
  • 13
  • Out of curiosity, what do you get when invoking `psInstance.AddScript("[System.Environment]::OSVersion");`? – Jonathon Chase Oct 15 '19 at 22:05
  • Interesting. Run from the shell it returns Microsoft Windows NT 10.0.18362.0, run from my method it returns Microsoft Windows NT 6.2.9200.0. Any ideas what might be causing the discrepancy? – Matthew Heimlich Oct 16 '19 at 15:48

1 Answers1

4

Seems the Get-ProcessMitigation cmdlet checks the OS version before executing. This would be reasonable, as it might need a new library or is dealing with some new features, but the problem is that by default your app is being told it is running on Windows 8 (6.2), even when the OS is really Windows 10:

Targeting your application for Windows

To get around this, add an app.manifest to your project and uncomment this section:

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
boxdog
  • 7,894
  • 2
  • 18
  • 27