Search code examples
powershellstrong-typing

Powershell strongly typed environment variable


I want to set a strongly typed environment variable and it seems to "lose" its type when I use $env:

Within the original function it works fine:


function Create-ThisCrap(){

[Microsoft.ApplicationInsights.TelemetryClient] $mytest = New-Object -TypeName  Microsoft.ApplicationInsights.TelemetryClient
$mytest.InstrumentationKey = "213-123"
$mytest.TrackTrace("something")

}

But this already doesn't :


function Create-ThisCrap(){

[Microsoft.ApplicationInsights.TelemetryClient] $env:mytest = New-Object -TypeName  Microsoft.ApplicationInsights.TelemetryClient
$env:mytest.InstrumentationKey = "213-123"
$env:mytest.TrackTrace("something")

}

with errors:

  • The property 'InstrumentationKey' cannot be found on this object.

  • Method invocation failed because [System.String] does not contain a method named 'TrackTrace'.

I tried cheating a bit:


function Create-ThisCrap(){

[Microsoft.ApplicationInsights.TelemetryClient] $mytest = New-Object -TypeName  Microsoft.ApplicationInsights.TelemetryClient
$mytest.InstrumentationKey = "213-123"
$mytest.TrackTrace("something")


return $mytest
}



function FROMAnotherScript(){

[Microsoft.ApplicationInsights.TelemetryClient] $env:HopeItWorks = Create-ThisCrap
$env:HopeItWorks.TrackTrace('whatever')

}

but it gave the same effects.


I am roughly aware of the issues when it comes to Powershell passing classes (obviously not enough), but I thought that as long as it is within one function it should work and the $env issue stumps me.


Solution

  • Environment variables are only allowed to be strings. If you need to store more than one value, you can use more than one environment variable, but the data type is always string. Environment variables date from MS-DOS, meaning they're from the 1980s and are meant to be used with batch files and DOS commands. They're a very old legacy component.

    Furthermore, setting an environment variable via the $env: namespace does not set the environment variable permanently for other processes. You can do that by calling [System.Environment]::SetEnvironmentVariable(), but even then, setting an environment variable only set the value for processes created after the value has been set. It won't refresh other threads already running.

    You cannot pass an object whole-hog from one process to another. You'll need to serialize it in some way and then deserialize it on the other side. Usually this is accomplished by storing your settings in a data file, database, or in the registry. You might try Export-Clixml and Import-Clixml, which provide basic data-type aware object serialization for PowerShell, but I can't really tell what you're trying to do.