Skip to content

Instantly share code, notes, and snippets.

@indented-automation
Last active August 13, 2021 11:05
Show Gist options
  • Save indented-automation/81e2dc1fa1ba06f5023e535a8e1c2a50 to your computer and use it in GitHub Desktop.
Save indented-automation/81e2dc1fa1ba06f5023e535a8e1c2a50 to your computer and use it in GitHub Desktop.
Add a PowerShell Provider without Import-Module
using namespace System.Management.Automation
using namespace System.Management.Automation.Provider
using namespace System.Management.Automation.Runspaces
[CmdletProvider('MyProvider', [ProviderCapabilities]::None)]
class Provider : DriveCmdletProvider {
[PSDriveInfo] NewDrive( [PSDriveInfo]$drive )
{
return ([DriveCmdletProvider]$this).NewDrive($drive)
}
}
function Import-PSProvider {
param(
[String]$Name,
[Type]$Type
)
$sessionStateProviderEntry = New-Object SessionStateProviderEntry(
$Name,
$Type,
$null
)
# System.Management.Automation.Runspaces.LocalPipeline will let us get at ExecutionContext.
# Note: $ExecutionContext is *not* an instance of this object.
$type = [PowerShell].Assembly.GetType('System.Management.Automation.Runspaces.LocalPipeline')
$method = $type.GetMethod(
'GetExecutionContextFromTLS',
[Reflection.BindingFlags]'Static,NonPublic')
# Invoke the method to get an instance of ExecutionContext.
$context = $method.Invoke($null, [Reflection.BindingFlags]'Static,NonPublic', $null, $null, (Get-Culture))
# Get the SessionStateInternal type
$type = [PowerShell].Assembly.GetType('System.Management.Automation.SessionStateInternal')
# Get a valid constructor which accepts a param of type ExecutionContext
$constructor = $type.GetConstructor(
[Reflection.BindingFlags]'Instance,NonPublic',
$null,
$context.GetType(),
$null)
# Get the SessionStateInternal for this execution context
$sessionStateInternal = $constructor.Invoke($context)
# This attempts to verify that we have the "right" session state
# $currentLocation = $type.GetProperty('CurrentLocation', [Reflection.BindingFlags]'Instance,NonPublic')
# $currentLocation.GetValue($sessionStateInternal)
# Get the method which allows Providers to be added to the session
$method = $type.GetMethod(
'AddSessionStateEntry',
[Reflection.BindingFlags]'Instance,NonPublic',
$null,
$sessionStateProviderEntry.GetType(),
$null)
# Invoke the method.
$method.Invoke($sessionStateInternal, $sessionStateProviderEntry)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment