C# System.Management.Automation.Powershell class leaking memory on Invoke() call

2.3k Views Asked by At

I have code for a C# test app that queries system info using PowerShell, and in it I have a few simple functions like the following:

public void GetSystemInfo()
{
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddCommand("Get-Disk");      // Get-Disk is an example; this varies
        foreach (PSObject result in ps.Invoke())
        {
            // ...
            // Do work here. Process results, etc...
            // ...
        }
    }
}

This is straightforward and mostly taken from MSDN examples, like here: https://msdn.microsoft.com/en-us/library/dd182449(v=vs.85).aspx

The problem is that each time this function is called, I can see the app's memory footprint grow. The footprint grows right at the call to ps.Invoke() and never shrinks. It doesn't matter how I process the data; I can even comment the body of the foreach loop out completely and the memory is never garbage collected.

As far as I can tell from looking at the PowerShell class interface, there doesn't seem to be a way to force it to clean itself up, and Dispose() clearly doesn't work since the resources remain leaking in memory after the using block exits.

Is this a known bug in the C# PowerShell class implementation or PowerShell itself? Is anyone aware of a solution, or an alternative if possible?


EDIT

I've also tried the follow now, with the same results:

public void GetSystemInfo()
{
    Runspace rs = RunspaceFactory.CreateRunspace();
    rs.Open();

    PowerShell ps = PowerShell.Create();
    ps.Runspace = rs;
    ps.AddCommand("Get-Disk");      // Get-Disk is an example; this varies
    foreach (PSObject result in ps.Invoke())
    {
        // ...
        // Do work here. Process results, etc...
        // ...
    }

    rs.Close();
}

Again, super straightforward. Taken from the sample here.

I'm wondering if this is a know bug in the Powershell module. Perhaps I'll start looking into alternatives to the Powershell interface (WMI, etc) since I need to call these PS queries periodically over an indeterminately long duration.

1

There are 1 best solutions below

1
On BEST ANSWER

There does indeed appear to be an issue with the Powershell API in the C# library. Even forcing a garbage collect doesn't seem to free up the memory.

Replacing everything with WMI calls instead of Powershell eliminates the problem.