Skip to content

Instantly share code, notes, and snippets.

@SeeminglyScience
Created September 30, 2017 18:31
Show Gist options
  • Save SeeminglyScience/fc64a6228c115768926b13617c5f56d8 to your computer and use it in GitHub Desktop.
Save SeeminglyScience/fc64a6228c115768926b13617c5f56d8 to your computer and use it in GitHub Desktop.
$typeDefinition = @'
using System;
using System.Management.Automation;
using System.Reflection;
namespace PSStateTree.Commands
{
[OutputType(typeof(StateTreeInfo))]
[Cmdlet(VerbsCommon.Show, "PSStateTree")]
public class ShowPSStateTreeCommand : PSCmdlet
{
private struct StateTreeInfo
{
public int ExecutionContext;
public int TopLevelSessionState;
public int EngineSessionState;
public int GlobalScope;
public int ModuleScope;
public int ScriptScope;
public int ParentScope;
public int CurrentScope;
}
private const BindingFlags BINDING_FLAGS = BindingFlags.Instance | BindingFlags.NonPublic;
protected override void ProcessRecord()
{
StateTreeInfo result;
EngineIntrinsics engine = GetVariableValue("ExecutionContext") as EngineIntrinsics;
var context = engine
.GetType()
.GetTypeInfo()
.GetField("_context", BINDING_FLAGS)
.GetValue(engine);
var stateInternal = GetProperty("Internal", SessionState);
var currentScope = GetProperty("CurrentScope", stateInternal);
var parent = GetProperty("Parent", currentScope);
result.ParentScope = 0;
if (parent != null)
{
result.ParentScope = parent.GetHashCode();
}
result.ExecutionContext = context.GetHashCode();
result.EngineSessionState = GetProperty("EngineSessionState", context).GetHashCode();
result.TopLevelSessionState = GetProperty("TopLevelSessionState", context).GetHashCode();
result.CurrentScope = currentScope.GetHashCode();
result.ScriptScope = GetProperty("ScriptScope", stateInternal).GetHashCode();
result.ModuleScope = GetProperty("ModuleScope", stateInternal).GetHashCode();
result.GlobalScope = GetProperty("GlobalScope", stateInternal).GetHashCode();
WriteObject(result);
}
private object GetProperty(string propertyName, object source)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException("propertyName");
}
if (source == null)
{
throw new ArgumentNullException("source");
}
return source
.GetType()
.GetTypeInfo()
.GetProperty(propertyName, BINDING_FLAGS)
.GetValue(source);
}
}
}
'@
if (-not ('PSStateTree.Commands.ShowPSStateTreeCommand' -as [type])) {
$module = New-Module -Name PSStateTree -ScriptBlock {
$types = Add-Type -TypeDefinition $typeDefinition -PassThru
Import-Module -Assembly $types[0].Assembly
Export-ModuleMember -Cmdlet Show-PSStateTree
}
Import-Module $module
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment