Display variables values at different scopes

I have an automated process for building the necessary regular expression using Emacs. It has a function called regexp-opt which builds an optimized regular expression to search for a list of words.The result is converted to a Powershell regex with a list of string replacements such as “\(” to “(” etc.

######################################################################
#
#                               MYVARS
#
#   Displays *ALL* Non-AUTOMATIC PS Variables in a scope range.
#   With the -del option it cleans up the variables in that range.
#   Requires Get-MaxScopeID posted by Kiron 20080917.
#
######################################################################
function MyVars([int]$minScope=0,
                [int]$maxScope=$(Get-MaxScopeID),
                [switch]$del) {
$ScopeLimit = (Get-MaxScopeID)
if ($minScope -gt $maxScope){throw "Myvars [<min>] [<max>]"}
"Maximum Scope range specification is 0..$($ScopeLimit - 1)"
if ($minScope -lt 0 -or $maxScope -lt 0){throw "Scope out of range."}
$maxScope++                     #These offsets are to account
$minScope++                     #for $this scope which goes away
if ($maxScope -gt $ScopeLImit){$maxScope = $ScopeLimit}
if ($minScope -gt $maxScope)  {$minScope = $maxScope}
$minScope..$maxScope|%{Get-Variable -scope $_|Select-Object Name,Value|
                       Add-Member noteproperty 'Scope' ($_ - 1) -passthru}|
 ?{$_.name -notmatch (
   '^(Co(?:mmandLineParameters|n(?:(?:firmPreferenc|soleFileNam)e))|DebugPref' +
   'erence|E(?:rror(?:ActionPreference|View)?|xecutionContext)|FormatEnumerat' +
   'ionLimit|H(?:OME|ost)|L(?:ASTEXITCODE|oad_Library_Paths)|M(?:aximum(?:(?:' +
   'Alias|Drive|Error|Function|History|Variable)Count)|yInvocation)|NestedPro' +
   'mptLevel|OutputEncoding|P(?:ID|ROFILE|S(?:BoundParameters|C(?:mdlet|ultur' +
   'e)|EmailServer|HOME|MaximumReceived(?:(?:DataSizePerCommand|ObjectSize)MB' +
   ')|Session(?:(?:Applic|Configur)ationName)|TypePath|(?:UICultur|VersionTab' +
   'l)e)|WD|rogressPreference)|ReportErrorShow(?:ExceptionClass|InnerExceptio' +
   'n|S(?:(?:our|tackTra)ce))|S(?:hellId|tackTrace)|VerbosePreference|W(?:SMa' +
   'nMaxRedirectionCount|(?:arning|hatIf)Preference)|args|false|input|null|pa' +
   'ttern|true|[$?_^])$'
   )}|
 %{Add-Member -in $_ noteproperty 'Type'  $(if ($_.Value){
              $_.Value.PSTypeNames[0]}else{'Null'}) -passthru}|
 Sort-Object -property scope,name|
 %{if ($del) {Remove-Variable $_.Name -scope ($_.Scope + 1)
              "Deleted $($_.name)"}else{$_}}|
 Format-Table Scope,Name,Type,Value -a
}
######################################################################
#
#                             Get-MaxScopeID
#
#   Returns the numeric -scope value currently equivalent to 'global'
#   Posted by iron 20080917 on microsoft.public.windows.powershell NG
#
######################################################################
function Get-MaxScopeID () {
 # -2 below accounts for function and foreach scopes which go away
 trap {return ([int]$id - 2)}
 foreach ($id in 0..100) {
  gv -s $id >$null
 }
}

Generic way to see if an object is castable to another type

This function provides a generic way to tell if a given object can safely be cast to another type.
It returns a boolean value (True False) so it can also be used as a filter in a pipeline.
filter Global:CanBe([string]$Type,$InputObject) {
  begin {if ($InputObject){$InputObject|CanBe $Type}}
  process { if (!$InputObject) {
    Invoke-Expression "&{trap {`$false;continue};[boolean]([$Type]`$_)}"}
  }
}
Here are some test cases you can try.
CanBe int 'rick'
CanBe int '12,345'
'abc',123,'124',@(),{throw},@('hu',1)|CanBe int
'abc',123,'124',@(),{throw},@('hu',1)|CanBe string
'abc',123,'124',@(),{throw},@('hu',1)|CanBe scriptblock
'abc',123,'124',@(),{throw},@('hu',1)|CanBe object[]
'abc',123,'124',@(),{throw},@('hu',1)|?{CanBe scriptblock $_}
'abc',123,'124',@(),{throw},@('hu',1)|?{CanBe string $_}

PowerShell Class Definition Library

If you read Windows PowerShell In Action you might have thought that the section on ‘Extending the PowerShell language’ was interesting.  Particularly the ‘Adding a CustomClass Keyword’ section.  I basically tried to go all out to provide a full blown custom-class solution.  There are limits to what is possible but this emulation is pretty good.  I use it every day so it should be stable.  I make updates occasionally.  Check back regularly.  You’re welcome to report bugs or suggest improvements.
 
This code was updated 10/28/08.  It is now radically different from the original which was strongly based on Bruce Payette’s version.  This version supports inheritence, serialization and (more importantly) resurection of objects to a working state after being de-serialized.
 
I put the doc in a here-string because a seperate file begs to get out of sync.

#REQUIRES -VERSION 2
$ErrorActionPreference = 'Stop'
[void]@'
                        Class Definition Library

Lets you Define, Get, Instantiate Rebuild and Remove - classes and instances.

EXAMPLE:

  Add-Class Example {
    Constructor {
      param ([string]$InstanceName)
      Property       Instance_call_count  0
      Property       MyName               $InstanceName
    }
    StaticProperty   Class_call_count     0
    Method ToString {
      "`t$($this.type) called $([string]++$this.Class_call_count) times`n" +
      "`t$($this.MyName) Called $([string]++$this.Instance_call_count) times"
    }
  }
  $a = New-ClassInstance Example "Instance A"
  $b = New-ClassInstance Example "Instance B"

  $a.ToString()
        Example called 1 times
        Instance A Called 1 times.
  $b.ToString()
        Example called 2 times
        Instance B Called 1 times.
  $a.ToString()
        Example called 3 times
        Instance A Called 2 times.
  $a,$b|ft -a

  Type    Class_call_count Instance_call_count MyName
  ----    ---------------- ------------------- ------
  Example                3                   2 Instance A
  Example                3                   1 Instance B

DOCUMENTATION:

Add-Class <name>[,<parent>] {<definition>}       # Defines the Class <name>.
                                # <definition> is a Script Block where the class
                                # Constructor, Methods and StaticProperties are
                                # defined.  When <parent> is included your new
                                # class first inherits all StaticProperties and
                                # Methods of the parent class.  IOW all the
                                # StaticProperties and Methods of that class are
                                # implicitly defined.  Instance properties are
                                # defined in your Constructor code and they too
                                # are inherited.

Remove-Class <name>             # Deletes the definition for class <name>.  This
                                # does not delete existing instances.  It only
                                # renders them effectively useless because it
                                # deletes their methods and static properties
                                # out from under them.  The objects still exist
                                # and their properties are still accessible.

New-ClassInstance <name> [<args>] # Creates an instance of a class.  <args> are
                                # arguments to the class constructor.

The following are the special functions available within <definition> code to
declare your class constructor and any methods or static properties.  They are
all public.  Instance properties are covered later.  The order in which you
declare class elements is not important unless you declare the same element
multiple times.  There is no safeguard against this and the last definition
overrides prior definitions.

Constructor <scriptblock>       # <scriptblock> contains your class constructor
                                # code.  Here you interpret constructor args and
                                # declare/initialize instance properties.  See
                                # the Property keyword below.  Note that when
                                # inheriting from another class you must create
                                # an alias for the parent constructor and call
                                # it yourself if you both overload it and want
                                # it called.  See AliasParentMethod below.  The
                                # only difference between a constructor and any
                                # other method is that you can declare class
                                # properties in them.  In fact you can use the
                                # syntax: Method Constructor {scriptblock}
                                # instead if you want.  A constructor is not
                                # required however unless you define or inherit
                                # a constructor, your class will have no
                                # instance properties.

Method <name> <scriptblock>     # <scriptblock> defines a method of the class.
                                # Accessed via $obj.<name>([<args>]) where $obj
                                # is an instance of the class.  Methods access
                                # other properties and Methods via $this.<name>

StaticProperty <name> <value>   # Defines a variable whose value is accessible
                                # to all members of the class via the syntax:
                                # $this.<name>.  Although regular properties are
                                # accessed by the same syntax, any change to a
                                # StaticProperty is seen by all instances.

AliasParentMethod <parent method name> <alias> # Use this to give a parent
                                # method that you override a name by which the
                                # parent Method can still be invoked.  Otherwise
                                # $this.<method> always invokes your function
                                # and the parent function is inaccessible.

AliasParentStaticProperty <parent static property name> <alias> # Use this to
                                # give your methods access to a parent static
                                # property that you override.  While parent
                                # methods invoked from your class will only see
                                # your instance of a static property you
                                # overrode, there may still be interactions with
                                # objects based on your parent class but not
                                # based on your class.  This provides a
                                # mechanism for managing those situations.

NOTE: Every class has 2 built-in StaticProperties: "Type" and "ParentType".
"Type" is a [string] containing the name of the class.  ParentType is a
[string] containing $null or the parent class upon which this class is built.
This lets you check the class name of an object like this.

if ($var -is [PSObject] -and $var.Type -eq "Custom") ...
if ($var -is [PSObject] -and $var.ParentType -eq "A_Mom") ...

The names are also added to PSObject.TypeNames so these work too.

if ($var.PSObject.TypeNames -contains "Custom")
if ($var.PSObject.TypeNames -contains "A_Mom")

Within Constructor <ScriptBlock> code you can do whatever you like.  Typically
you interpret arguments and initialize properties.  The only special function
available in a constructor ScriptBlock is the Property function.

Property <name> [<value>]       # Each property declared in a constructor is
                                # available to class Methods via $this.<name>.
                                # Where <value> is the initial value.  Each
                                # instance of the class references a private
                                # copy of the value and so each instance is
                                # unique by virtue of these properties.

The following function allows access to class Static properties and methods.
Static methods are simply methods that do not reference instance properties.

Get-Class [<name>]              # Returns an object that represents the
                                # definition a class or a list of all defined
                                # classes.

A list of all defined classes is available like this:

get-class|%{$_.type}

External access to a static property or method of a class is made like this:

(Get-Class <class name>).<method name>

WARNING: From within class methods you should not use this syntax to access your
own class methods and properties.  You should always use $this.<name>.  Access
other than through $this circumvents any overriding done by a derived classes
which is almost always the wrong thing to do.
'@

function global:Add-Class ([string[]]    $type,
                           [scriptblock] $script,
                           [switch]      $Force) {
     #
     # Validate arguments.
     #
     if (! $type -or ! $script) {
       throw "Syntax: Add-Class '<type>'[,'<parent>'] {<script>} -- '$type'"}
     if ($type.Count -gt 2) {
       throw "You can only inherit from 1 class - '$type'"}
     $Parent = $type[1]
     [string]$type = $type[0]
     # Re-definition is (usually) not legal.
     # When using -Force an existing definition is changed rather than being
     # replaced so that existing class instance objects are not orphaned from
     # their underlying code.  This feature is only a testing aid.  If you add
     # new properties or methods, existing instances will not know about them.
     # Rebuild-Instance can be used in this case.
     if (($Class = Get-Class $type) -and !$Force) {
       throw "Error: '$type' already defined.  Use Remove-Class to re-define."}
     # Parent Class must exist too
     if ($Parent -and !(Get-Class $Parent)) {
       throw "Error: Can't inherit from '$Parent'.  Class not defined."}
     if ((Get-Class -i).InvalidName($type)) {
       throw "Illegal class name - '$type'"}
     #
     # DEFINE THE FUNCTIONS THAT ALLOW CLASS FEATURES TO BE DECLARED
     #
     function Property {Throw ("Define Properties in Constructor scripts.`n" +
                               "Use StaticProperty for static properties.")
     }
     function AliasParentMethod ([string]$name,[string]$alias)  {
         if (!$PClass) {
           throw "Can't use AliasParentMethod when not inheriting"}
         if (! $name -or ! $alias) {
           throw "Syntax: AliasParentMethod '<name>' '<alias>' -- $args"}
         if ((Get-Class -i).InvalidName($alias)) {
           throw "Illegal Method Alias name '$alias'"}
         # The method to be renamed must exist on the parent Class object.
         $Method = $PClass.PSObject.Members.Item($name)
         if (!$Method -or $Method.MemberType -ne 'ScriptMethod') {
           throw $("Syntax: AliasParentMethod '<name>' '<alias>'`n" +
                   "'$name' is not a Method of '$($PClass.Type)'")}
         # Overwriting the existing code rather than adding a new object keeps
         # existing pointers to the data from becoming invalid.
         if ($Class.PSObject.Methods -contains $alias -and
             $Class.$alias.MemberType -eq 'ScriptMethod') {
           $Class.$alias.script = $Method.Script}
         else {
           $Class|Add-Member ScriptMethod $alias $Method.Script -Force}
     }
     function AliasParentStaticProperty ([string]$name,[string]$alias) {
         if (!$PClass) {
           throw "Can't use AliasParentMethod when not inheriting"}
         if (! $name -or ! $alias) {
           throw "Syntax: AliasParentStaticProperty '<name>' '<alias>' -- $args"}
         if ((Get-Class -i).InvalidName($alias)) {
           throw "Illegal Method Alias name '$alias'"}
         # The property to be renamed must exist on the parent Class object.
         $Prop = $PClass.PSObject.Members.Item($name)
         if (!$Prop -or ($Prop.MemberType -ne 'NoteProperty' -and
                         $Prop.MemberType -ne 'ScriptProperty')) {
            throw $("Syntax: AliasParentStaticProperty '<name>' '<alias>'`n" +
                     "'$name' is not a Static Property of '$($PClass.Type)'")}
         # Create accessors that point to the parent static value.
         $T1 = "(`$global:__Defined_Classes__['$Parent']).$name"
         $T2 = $t1  + ' = $args[0]'
         $T1 = $ExecutionContext.InvokeCommand.NewScriptBlock($T1)
         if ('Type','ParentType' -contains $name) {
             $T2 = $null} # Setters for these types are not allowed
         else {
           $T2 = $ExecutionContext.InvokeCommand.NewScriptBlock($T2)}
         # Overwriting the existing code rather than adding a new object keeps
         # existing pointers to the data from becoming invalid.
         $Property = $Class.PSObject.Properties.Item($alias)
         if ($Property -and $Property.MemberType -eq 'ScriptProperty') {
           $Property.GetterScript = $T1
           $Property.SetterScript = $T2}
         else {
           $Class|Add-Member ScriptProperty $alias -Force `
                      -Value $T1 -SecondValue $T2}
     }
     function Constructor ([scriptblock] $script) {
         # Nobody should point to this so don't worry about saving pointers.
         # The very special name (contains a space) tries to insure we don't
         # step on user functions.
         $Class|Add-Member ScriptMethod 'Constructor' $script -Force
     }
     function Method ([string]$name, [scriptblock] $script) {
         if (! $name)
            {throw "Syntax: method '<name>' {<script>} -- <name> missing"}
         if ((Get-Class -i).InvalidName($name))
            {throw "Illegal Method name '$name'"}
         # Overwriting the existing code rather than adding a new object keeps
         # existing pointers to the data from becoming invalid.
         if ($Class.PSObject.Methods -contains $name -and
             $Class.$name.MemberType -eq 'ScriptMethod') {
           $Class.$alias.script = $Method.Script}
         else {
           $Class|Add-Member ScriptMethod $name $script -Force}
     }
     function StaticProperty ([string]$name, $value)
     {   if (! $name)
            {throw "Syntax: StaticProperty '<name>' <value> -- <name> missing"}
         if ((Get-Class -i).InvalidName($name))
            {throw "Illegal StaticProperty name '$name'"}
        # You can't point to a NoteProperty so replacing one is OK'
        $Class|Add-Member NoteProperty $name $value -Force
     }
     #
     #          Build the complete definition used to build an instance
     #
     $PClass = $null
     if (!$Class) {$Class  = New-Object PSObject} # might be a re-definition
     if (!($Class.PSObject.TypeNames -eq $Type)) {
       $Class.PSObject.TypeNames.Insert(0,$Type)}
     $Class|Add-Member NoteProperty 'ParentType' $Parent -Force
     $Class|Add-Member ScriptMethod 'Class` Def' $script -Force
     $Class|Add-Member NoteProperty 'Type'       $type   -Force 
     # Make a stack of the classes that this one is built upon.
     $Stack = new-object System.Collections.Stack
     $TClass = $Class
     while ($TClass.ParentType) {
       $Stack.Push($TClass)
       if (!($Class.PSObject.TypeNames -eq $TClass.ParentType)) {
         $Class.PSObject.TypeNames.Insert(0,$TClass.ParentType)}
       if (!($TClass = (Get-Class $TClass.ParentType))) {
         throw "A parent class definition is missing '$(($Stack.Pop()).ParentType)'"}
     }
     # With the LIFO stack of definitions, build the complete definition.
     while ($TClass) {
       # Execution of the class definition script declares the methods
       # and static properties etc. on $Class because the functions like
       # Constructor and Method (defined above) are hard-coded to do so.
       [void]$TClass.PSObject.Methods['Class` Def'].Script.Invoke()
       # Creating an alias for a parent class method or property requires
       # access to the parent class.  The alias functions (defined above)
       # are coded to look for that data in $PClass.
       $PClass = $TClass
       # Get the next class or null if the hierarchy is ended.
       $TClass = $(if ($stack.count) {$Stack.Pop()})
     }
     # Add the new definition or replace an existing one
     $global:__Defined_Classes__[$type] = $Class
}

function global:Get-Class ([string] $name, [switch]$internal) {
     if ($name -match ' ') {throw "$name is an illegal class name"}
     #
     # Create (if needed) a location for class defs and private fcns.
     #
     if (!(test-path variable:global:__Defined_Classes__)) {
       $global:__Defined_Classes__ = @{}
       $T = New-Object PSObject
       $T|Add-Member ScriptMethod 'InvalidName' {('Type', 'ParentType',
                     'PSTypeNames', 'PSAdapted', 'PSBase', 'PSExtended',
                     'PSObject' -contains $args[0])}
       $global:__Defined_Classes__['Lib Internal'] = $T
     }
     #
     # $Internal returns an object with private library values.
     #
     if ($internal) {return $global:__Defined_Classes__['Lib Internal']}
     #
     # Either get all Class entries or just the one(s) requested.
     #
     if (! $name){
       $global:__Defined_Classes__[[string[]]($global:__Defined_Classes__.keys|
               ?{$_ -notmatch ' '})]}
     elseif ($global:__Defined_Classes__) {
       $global:__Defined_Classes__[$name]}
     else {$null}
}

function global:New-ClassInstance ([string] $type,
                                   [switch]$__DontInitialize__) {
     #
     #  CLASS WRITERS USE THIS FUNCTION TO DECLARE INSTANCE PROPERTIES
     #
     function Property ([string]$name, $value)
     {   if (! $name)
            {throw "Syntax: property '<name>' <value>  -- <name> missing"}
         if ('Type','ParentType','PSTypeNames','PSAdapted','PSBase',
               'PSExtended','PSObject' -contains $name -or
             $name -match '[^0-9A-Za-z_^]')
            {throw "Illegal Property name '$name'"}
         if ($Instance.PSObject.members.item($name))
            {throw "Instance already has a Method or Property named '$name'"}
         $Instance|Add-Member NoteProperty $name $value
     }
     #
     #                      CREATE THE NEW INSTANCE
     #
     $Class = Get-Class $type
     if (!$Class) {throw "Class '$type' doesn't exist."}
     $Instance = New-Object PSObject 
     #
     #                        ADD THE CLASS NAMES
     #
     $Class.PSObject.TypeNames|
       %{if (!($Instance.PSObject.TypeNames -eq $Type)) {
           $Instance.PSObject.TypeNames.Insert(0,$Type)}} 
     #
     #                       ADD DECLARED METHODS
     #
     $Class.PSObject.methods|
         ?{$_.MemberType -eq 'ScriptMethod' -and $_.name -notmatch ' '}|
         %{$Instance.PSObject.members.add($_)}
     #
     #                       ADD STATIC PROPERTIES
     #
     $Class.PSObject.properties|
       ?{$_.MemberType -eq 'NoteProperty'}|
       %{$T1 = "(`$global:__Defined_Classes__['$type']).$($_.Name)"
         $T2 = $T1  + ' = $args[0]'
         $T1 = $ExecutionContext.InvokeCommand.NewScriptBlock($T1)
         if ('Type','ParentType' -contains $_.Name) {
           $T2 = $null} # Setters for these types are not allowed
         else {
           $T2 = $ExecutionContext.InvokeCommand.NewScriptBlock($T2)}
         $Instance|Add-Member ScriptProperty $_.name -Force `
                      -Value $T1 -SecondValue $T2}
     #
     #                 ADD REDIRECTED STATIC PROPERTIES
     #
     $Class.PSObject.properties|
         ?{$_.MemberType -eq 'ScriptProperty'}|
         %{$Instance.PSObject.members.add($_)}
     #
     #                 CALL THE CONSTRUCTOR (if needed)
     #
     if ($Instance.PSObject.Methods['Constructor'] -and !$__DontInitialize__) {
       # This works around the lack of a (working) splat operator
       $args|
         % -begin  {$exp = '$Instance.Constructor('
                    $_ctr_ = 0} `
           -process{set-variable ('_tmp_'+ ++$_ctr_) $_
                    $exp += "`$$('_tmp_' + $_ctr_),"} `
           -end    {$exp = $exp.Trim(',') + ')'
                    Invoke-Expression $exp}|
       Out-Null
     } 
     # Done.  Return it.
     $instance
}

function global:Remove-Class ([string] $type = $(throw 'A valid type is required'),
                              [switch] $Force) {
     if (Get-Class $type) {
       $global:__Defined_Classes__.remove($type)}
     elseif (!$Force) {
       throw "Type '$type' is not defined"}
}

# Rebuild-Instance recursively replaces static properties and methods on the
# object passed with the methods and properties currently defined for that
# object class.  Its purpose is mainly to resurrect serialized objects but it
# can be useful in testing if you change a class definition and want to update
# some existing objects to use the new definition.

# IMPORTANT: When you serialize an instance, the fact that a property was
# Static is lost.  To account for this, when rebuilding a static member if the
# instance being rebuilt has a non-null value, the static value is replaced by
# it.  If the instance only has a pointer to a static value then the pointer is
# refreshed.  The idea here is that all instances should have the same value
# for static properties.  If you are rebuilding because the instance is being
# resurrected from an XML file, the static value would have been converted to
# an instance value and thus the value would have been preserved.  So this
# tries to convert the value in $obj back to being static.

function global:Rebuild-Instance ([PSObject]$obj,
                                  [switch]$NoStaticReplace) {
    # $obj must have a type property
    if (!($obj -and $obj.Type)) {
      throw "Syntax: Rebuild-Class <class-instance> [-NoStaticReplace]"}
    # See if the type is defined and get
    $Type = $obj.type
    if (!($TypeDef = Get-Class $Type)) {
      throw "Can't rebuild object, type '$Type' not defined"}
    # Build a new object just to get all the current class elements.
    $New = New-ClassInstance $Type -__DontInitialize__
    # Replace all the old methods
    $New.PSObject.Methods|
      ?{$_.MemberType -eq 'ScriptMethod'}|
      %{$obj|Add-Member ScriptMethod $_.Name $_.Script -Force}
    # Replace accessors to static properties.  This means tossing the non-static
    # version if it exists and updating the static value to the non-static one.
    $New.PSObject.Properties|?{$_.MemberType -eq 'ScriptProperty'}|
      %{# This replaces the static value with the instance value if needed.
        if ($obj.$($_.name) -ne $null -and
            $obj.$($_.name).MemberType -eq 'NoteProperty' -and
            !$NoStaticReplace) {
          $TypeDef.$($_.name) = $obj.$($_.name)}
        # Restore/Refresh the Getter/Setter for this property
        $obj|Add-Member ScriptProperty $_.Name -Force `
                   -Value $_.GetterScript -SecondValue $_.SetterScript}
    # Recurse into nested objects and rebuild them too
    $obj.PSObject.properties|
      ?{$_.MemberType -eq 'NoteProperty' -and
        $_.Value -is [PSObject] -and
        $_.Value.Type}|
      %{Rebuild-Instance $_.value -NoStaticReplace:$NoStaticReplace}
    # recurse into nested lists to rebuild any of 'our' objects
    $obj.PSObject.properties|
      ?{$_.MemberType -eq 'NoteProperty' -and
        $_.Value -is [Array]}|
      %{$_.Value|
        ?{$_ -and $_ -is [PSObject] -and $_.Type}|
        %{Rebuild-Instance $_}}
}

# LocalWords:  MemberType GetType ScriptMethod StaticProperty ScriptBlock args
# LocalWords:  PSObject NoteProperty ClassInstance ScriptProperty PSAdapted eq
# LocalWords:  ParentType AliasParentMethod PSTypeNames PSBase TypeNames param
# LocalWords:  PSExtended PowerShell's PSCustomObject InvalidName defs fcns
# LocalWords:  StaticProperties AliasParentStaticProperty InstanceName ToString
# LocalWords:  NoStaticReplace MyName

# SIG # Begin signature block
# MIIEKgYJKoZIhvcNAQcCoIIEGzCCBBcCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUnTj5AKjmAb60nI92xbA7Q9aw
# 4xagggI0MIICMDCCAZ2gAwIBAgIQlTIOA6/HvqJAFvdEzio63DAJBgUrDgMCHQUA
# MCwxKjAoBgNVBAMTIVBvd2VyU2hlbGwgTG9jYWwgQ2VydGlmaWNhdGUgUm9vdDAe
# Fw0wODAzMDcxNDMyMTBaFw0zOTEyMzEyMzU5NTlaMBExDzANBgNVBAMTBkEwSjY1
# MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAv0yAvkSPkcGd8YBnWbxerzKr
# kQJWUfHXDtQlHefTmRXcjOZZ0XAoZINA4XVJFdJvNC/Qp8l4Uv14Ea9MYNByUELH
# REAU4P3lCb3i3wPTxbKQVv/pWu1IZjReZJljeL8gmBa0QAeZ9rLagoxHziChDZ1S
# MtFcbEwXYy0KY2q4QKsCAwEAAaN2MHQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwXQYD
# VR0BBFYwVIAQL3ZRv2pYKftzC3bM4Z22lqEuMCwxKjAoBgNVBAMTIVBvd2VyU2hl
# bGwgTG9jYWwgQ2VydGlmaWNhdGUgUm9vdIIQ41ebY7VoLJtFHAsM0UMAnTAJBgUr
# DgMCHQUAA4GBALYT6aYBK3nx6vpOlTRXZ4cPNv3C0Q5BGZvdJ0VVaNPEScQDt0dr
# 4Qr9izYgPAaarpMvr+Nk9ugpRtTDTQRzY3y8MN9Oa/WPyEVFR3ZSh/GjFkBEbVHC
# LvneK5dNVOe0NZLcPa5VJmFDUwvj6WCJlVW28G/pMFU2HyVpftoBqC9IMYIBYDCC
# AVwCAQEwQDAsMSowKAYDVQQDEyFQb3dlclNoZWxsIExvY2FsIENlcnRpZmljYXRl
# IFJvb3QCEJUyDgOvx76iQBb3RM4qOtwwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcC
# AQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB
# BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFEMAVA9nxLrY
# FWSin4R9tcfOibx0MA0GCSqGSIb3DQEBAQUABIGAU8ZlvWgRxUkLdVS4szkFpiUa
# mtXF0UvIpMcKjmc6ayvV980qMs91MQoz1s9l2AETlVaPJyTor52E/WisyJaUqYsr
# djON/dUd/Dh2Gjulmay48zuEyVY42JzuBkqOHsZT9MBLmMhpSDELqylEtgt5yNlL
# 2JvfS+PCswFZxFMI0Iw=
# SIG # End signature block