Get-Demo.ps1

function Get-Demo {
    <#
    .SYNOPSIS
        Gets Demos
    .DESCRIPTION
        Gets PowerShell Demos.
        Demos located in ShowDemo and all modules that tag ShowDemo will be automatically discovered.
    .LINK
        Import-Demo
    .EXAMPLE
        Get-Demo
    #>

    [CmdletBinding(DefaultParameterSetName='LoadedDemos')]
    param(
    # The name of the demo
    [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='LoadedDemos')]
    [string]
    $DemoName,
    # The path to the demo file.
    [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='DemoFile')]
    [Alias('FullName', 'DemoFile', 'File', 'Source')]
    $DemoPath,
    # A Demo Script block.
    [Parameter(Mandatory,ValueFromPipeline,ParameterSetName='DemoScript')]
    [scriptblock]
    $DemoScript
    )
    begin {
        $myModule = $MyInvocation.MyCommand.ScriptBlock.Module
    }
    process {
        if ($PSCmdlet.ParameterSetName -in 'DemoFile', 'DemoScript') {
            Import-Demo @psboundParameters
            return
        }
        $filePaths =
            @(
            if ($myModule) {
                $moduleRelationships = 
                                       @(
                                       $MyModuleName, $myModule = 
                                           if ($myModule -is [string]) {
                                               $myModule, (Get-Module $myModule)
                                           } elseif ($myModule -is [Management.Automation.PSModuleInfo]) {
                                               $myModule.Name, $myModule
                                           } else {
                                               Write-Error "$myModule must be a [string] or [Management.Automation.PSModuleInfo]"    
                                           }
                                       #region Search for Module Relationships
                                       if ($myModule -and $MyModuleName) {
                                           foreach ($loadedModule in Get-Module) { # Walk over all modules.
                                               if ( # If the module has PrivateData keyed to this module
                                                   $loadedModule.PrivateData.$myModuleName
                                               ) {
                                                   # Determine the root of the module with private data.
                                                   $relationshipData = $loadedModule.PrivateData.$myModuleName
                                                   [PSCustomObject][Ordered]@{
                                                       PSTypeName     = 'Module.Relationship'
                                                       Module        = $myModule
                                                       RelatedModule = $loadedModule
                                                       PrivateData   = $loadedModule.PrivateData.$myModuleName
                                                   }
                                               }
                                               elseif ($loadedModule.PrivateData.PSData.Tags -contains $myModuleName) {
                                                   [PSCustomObject][Ordered]@{
                                                       PSTypeName     = 'Module.Relationship'
                                                       Module        = $myModule
                                                       RelatedModule = $loadedModule
                                                       PrivateData   = @{}
                                                   }
                                               }
                                           }
                                       }
                                       #endregion Search for Module Relationships
                                       )
                                       
                foreach ($relationship in $moduleRelationships) {
                    $relationship.RelatedModule | Split-Path
                }
            } else {
                $PSScriptRoot
            }
            )
        $allDemoFiles =
            @($(
              # Collect all items into an input collection
              $inputCollection =$(
              $executionContext.SessionState.InvokeCommand.GetCommands('*','Script',$true)
              ),
                 $(($filePaths |
                  & { process {
                      $inObj = $_
                      if ($inObj -is [Management.Automation.CommandInfo]) {
                          $inObj
                      }
                      elseif ($inObj -is [IO.FileInfo] -and $inObj.Extension -eq '.ps1') {
                          $ExecutionContext.SessionState.InvokeCommand.GetCommand($inObj.Fullname, 'ExternalScript')
                      }
                      elseif ($inObj -is [string] -or $inObj -is [Management.Automation.PathInfo]) {
                          $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($inObj)
                          if ($resolvedPath) {
                              $pathItem = Get-item -LiteralPath $resolvedPath
                              if ($pathItem -is [IO.FileInfo] -and $pathItem.Extension -eq '.ps1') {
                                  $ExecutionContext.SessionState.InvokeCommand.GetCommand($pathItem.FullName, 'ExternalScript')
                              } else {                    
                                  foreach ($pathItem in @(Get-ChildItem -LiteralPath $pathItem -File -Recurse)) {
                                      if ($pathItem.Extension -eq '.ps1') {
                                          $ExecutionContext.SessionState.InvokeCommand.GetCommand($pathItem.FullName, 'ExternalScript')
                                      }
                                  }
                              }
                          }            
                      }
                  } }
              ))
              # 'unroll' the collection by iterating over it once.
              $filteredCollection = $inputCollection =
                  @(foreach ($in in $inputCollection) {
                      $in
                  })
              # Since filtering conditions have been passed, we must filter item-by-item
              $filteredCollection = :nextItem foreach ($item in $inputCollection) {
                  # we set $this, $psItem, and $_ for ease-of-use.
                  $this = $_ = $psItem = $item
               
                  # Some of the items may be variables.
                  if ($item -is [Management.Automation.PSVariable]) {
                      # In this case, reassign them to their value.
                      $this = $_ = $psItem = $item = $item.Value
                  }
                  
                  # Some of the items may be enumerables
                  $unrolledItems = 
                      if ($item.GetEnumerator -and $item -isnot [string]) {
                          @($item.GetEnumerator())
                      } else {
                          $item
                      }
                  foreach ($item in $unrolledItems) {
                      $this = $_ = $psItem = $item
                      if (-not $(
                              $_.Name -match '^(?>demo|walkthru)\.ps1$' -or
                              $_.Name -match '\.(?>demo|walkthru)\.ps1$'
                          
                      )) { continue } 
                      $item
                  }
                  
                  
              }
              # Walk over each item in the filtered collection
              foreach ($item in $filteredCollection) {
                  # we set $this, $psItem, and $_ for ease-of-use.
                  $this = $_ = $psItem = $item
              if ($item.value -and $item.value.pstypenames.insert) {
                  if ($item.value.pstypenames -notcontains 'demofiles') {
                      $item.value.pstypenames.insert(0, 'demofiles')
                  }
              }
              elseif ($item.pstypenames.insert -and $item.pstypenames -notcontains 'demofiles') {
                  $item.pstypenames.insert(0, 'demofiles')
              }
              $item
                          
              }   
              ))
        $currentDirectoryDemos = 
            Get-ChildItem -Filter *.ps1 -Path $pwd |
            Where-Object {
                $_.Name -match '^(?>demo|walkthru)\.ps1$' -or
                $_.Name -match '\.(?>demo|walkthru)\.ps1$'
            }
        
        $allDemoFiles += @(
            $(
            # Collect all items into an input collection
            $inputCollection =$(
            $executionContext.SessionState.InvokeCommand.GetCommands('*','Script',$true)
            ),
               $(($currentDirectoryDemos |
                & { process {
                    $inObj = $_
                    if ($inObj -is [Management.Automation.CommandInfo]) {
                        $inObj
                    }
                    elseif ($inObj -is [IO.FileInfo] -and $inObj.Extension -eq '.ps1') {
                        $ExecutionContext.SessionState.InvokeCommand.GetCommand($inObj.Fullname, 'ExternalScript')
                    }
                    elseif ($inObj -is [string] -or $inObj -is [Management.Automation.PathInfo]) {
                        $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($inObj)
                        if ($resolvedPath) {
                            $pathItem = Get-item -LiteralPath $resolvedPath
                            if ($pathItem -is [IO.FileInfo] -and $pathItem.Extension -eq '.ps1') {
                                $ExecutionContext.SessionState.InvokeCommand.GetCommand($pathItem.FullName, 'ExternalScript')
                            } else {                    
                                foreach ($pathItem in @(Get-ChildItem -LiteralPath $pathItem -File -Recurse)) {
                                    if ($pathItem.Extension -eq '.ps1') {
                                        $ExecutionContext.SessionState.InvokeCommand.GetCommand($pathItem.FullName, 'ExternalScript')
                                    }
                                }
                            }
                        }            
                    }
                } }
            ))
            # 'unroll' the collection by iterating over it once.
            $filteredCollection = $inputCollection =
                @(foreach ($in in $inputCollection) {
                    $in
                })
            # Walk over each item in the filtered collection
            foreach ($item in $filteredCollection) {
                # we set $this, $psItem, and $_ for ease-of-use.
                $this = $_ = $psItem = $item
            if ($item.value -and $item.value.pstypenames.insert) {
                if ($item.value.pstypenames -notcontains 'demofiles') {
                    $item.value.pstypenames.insert(0, 'demofiles')
                }
            }
            elseif ($item.pstypenames.insert -and $item.pstypenames -notcontains 'demofiles') {
                $item.pstypenames.insert(0, 'demofiles')
            }
            $item
                        
            }   
            )
        )
        $allDemoFiles |
            Where-Object Name -like "*$demoName*" |
            Import-Demo
    }
}