Posts Tagged ‘Refelection’

I saw a post yesterday on the Scripting Guys forum that pointed me to a function that I absolutely fell in love with. I ended up spending a few hours messing around, and I came up with something I hope met the original poster’s requirements.

The poster was looking for a way to find out if ‘Strict Mode’ is being used, and if it is, what version is being enforced. There is no built-in cmdlet to do this. Someone else was able to point him to a function that did what he was looking for, but that function’s author said that it would only work for the global scope. In all honesty, that should be enough to cover virtually any use case you have for the function, but I was curious as to whether or not I could get the current scope’s setting, which could be different than the global scope’s.

The original Get-StrictMode function I found was using a function the author had picked up from PoshCode: Get-Field. It’s a function that gets public and private fields from objects passed to it–information that isn’t generally available. This is the function that I fell in love with.

I modified the Get-Field function somewhat, and you can find my version here.

Using the original Get-StrictMode as a starting point, I came up with my own version that can be found here.

And here’s a ridiculous example that shows that it works with multiple scopes:

function StrictModeTest {
    [CmdletBinding()]
    param([int] $Recurse = 0)

    Write-Verbose "Effective strict mode: $(Get-StrictMode)"

    switch (Get-Random -Minimum -1 -Maximum ($PSVersionTable.PSVersion.Major + 1)) {
        { $_ -gt -1 } { Write-Verbose "Setting strict mode to $_" }

        # This sets strict mode to 0.0
        0 { Set-StrictMode -Off }
        
        # Set strict mode to random version:
        { $_ -gt 0 } { Set-StrictMode -Version $_ }
    }
    Write-Verbose "New effective strict mode: $(Get-StrictMode)"

    if ($Recurse -le 0) { 
        Get-StrictMode -ShowAllScopes 
    }
    else { 
        if ($VerbosePreference -eq "Continue") {
            Get-StrictMode -ShowAllScopes
        }
        StrictModeTest -Recurse (--$Recurse) 
    }
}

Make sure that you’ve dot-sourced the Get-StrictMode function from the repository and run the StrictModeTest function definition above, then run the following command:


PS> StrictModeTest -Recurse 4

StrictModeVersion Scope
----------------- -----
2.0                   0
1.0                   1
3.0                   2
0.0                   3
                      4
2.0                   5

What the test function is doing is setting a random strict mode, then calling itself again. If you pass -Recurse the number 4, it will call itself 4 times, which means 5 scopes total (4 from the function calls, and 1 for the global scope). The last time the function calls itself, it calls Get-StrictMode with the -ShowAllScopes switch. If -Verbose is passed, it will call Get-StrictMode each time the function is called.

In my sample output, 5 is the global scope. Strict mode was set at 2.0 in that scope. Scope 4 didn’t have Set-StrictMode called, so it would inherit 2.0 from its parent scope. Scope 3 called ‘Set-StrictMode -Off’, so strict mode would not be enforced in that scope.

I don’t know that I’ll ever use Get-StrictMode, but I learned a ton playing around with it. Even if you don’t use it, you might take a look at it as an example of how to use Get-Field, which is one of my new favorite functions. I really think Get-Field has a ton of uses.

There’s still some work that can be done with both functions, so feel free to modify them and share your results.