When writing a PowerShell module in C#, how do I store module state? : <p>I'm writing a PowerShell module in C# that connects to a database. The module has a <code>Get-MyDatabaseRecord</code> cmdlet which can be used to query the database. If you have a <code>PSCredential</code> object in the variable <code>$MyCredentials</code>, you can call the cmdlet like so:</p>

<pre><code>PS C:\&gt; Get-MyDatabaseRecord -Credential $MyCredentials -Id 3


MyRecordId    : 3
MyRecordValue : test_value
</code></pre>

<p>The problem is, having to specify the <code>Credential</code> parameter every time that you call <code>Get-MyDatabaseRecord</code> is tedious and inefficient. It would be better if you could just call one cmdlet to connect to the database, and then another to get the record:</p>

<pre><code>PS C:\&gt; Connect-MyDatabase -Credential $MyCredentials
PS C:\&gt; Get-MyDatabaseRecord -Id 3


MyRecordId    : 3
MyRecordValue : test_value
</code></pre>

<p>In order for that to be possible, the <code>Connect-MyDatabase</code> cmdlet has to store the database connection object somewhere so that the <code>Get-MyDatabaseRecord</code> cmdlet can obtain that object. How should I do this?</p>

<h2>Ideas I've thought of</h2>

<h3>Use a static variable</h3>

<p>I could just define a static variable somewhere to contain the database connection:</p>

<pre><code>static class ModuleState
{
    internal static IDbConnection CurrentConnection { get; set; }
}
</code></pre>

<p>However, global mutable state is usually a bad idea. Could this cause problems somehow, or is this a good solution?</p>

<p>(One example of a problem would be if multiple PowerShell sessions somehow shared the same instance of my assembly. Then all of the sessions would inadvertently share a single <code>CurrentConnection</code> property. But I don't know if this is actually possible.)</p>

<h3>Use PowerShell module session state</h3>

<p>The MSDN page "<a href="https://msdn.microsoft.com/en-us/library/ms714451%28v=vs.85%29.aspx">Windows PowerShell Session State</a>" talks about something called session state. The page says that "session-state data" contains "session-state variable information", but it doesn't go into detail about what this information is or how to access it.</p>

<p>The page also says that <a href="https://msdn.microsoft.com/en-us/library/system.management.automation.sessionstate%28v=vs.85%29.aspx">the <code>SessionState</code> class</a> can be used to access session-state data. This class contains a property called <a href="https://msdn.microsoft.com/en-us/library/system.management.automation.sessionstate.psvariable%28v=vs.85%29.aspx"><code>PSVariable</code></a>, of type <a href="https://msdn.microsoft.com/en-us/library/system.management.automation.psvariableintrinsics%28v=vs.85%29.aspx"><code>PSVariableIntrinsics</code></a>.</p>

<p>However, I have two problems with this. The first problem is that accessing the <code>SessionState</code> property requires me to inherit from <code>PSCmdlet</code> instead of <code>Cmdlet</code>, and I'm not sure if I want to do that.</p>

<p>The second problem is that I can't figure out how to make the variable private. Here's the code that I'm trying:</p>

<pre><code>const int TestVariableDefault = 10;
const string TestVariableName = "TestVariable";

int TestVariable
{
    get
    {
        return (int)SessionState.PSVariable.GetValue(TestVariableName,
            TestVariableDefault);
    }
    set
    {
        PSVariable testVariable = new PSVariable(TestVariableName, value,
            ScopedItemOptions.Private);
        SessionState.PSVariable.Set(testVariable);
    }
}
</code></pre>

<p>The <code>TestVariable</code> property works just as I would expect. But despite the fact that I'm using <code>ScopedItemOptions.Private</code>, I can still access this variable at the prompt by typing in <code>$TestVariable</code>, and the variable is listed in the output of <code>Get-Variable</code>. I want my variable to be hidden from the user.</p>
