Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement PowerShell PSProvider *in* PowerShell

I'm looking to implement a PowerShell Provider in PowerShell.

I keep thinking that if I just define the types, then import them into my session (import-module), I should be able to have them available.

For example, this does not work but its along the path of what I'd like to implement.

I'm obviously missing quite a bit...anyone know if this is possible?

# EnvironmentProvider.ps1
    $reference_assemblies = (

      "System.Management.Automation, Version=1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
    #  "System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    )

    $source = @"

    namespace Providers
    {

    using System.Management.Automation;
    using System.Management.Automation.Provider;


        [CmdletProvider("Environments", ProviderCapabilities.None)]
        public class EnvironmentProvider : DriveCmdletProvider
        {
            protected override PSDriveInfo NewDrive(PSDriveInfo drive)
            {
                return new EnvironmentDriveInfo(drive);
            }

            protected override object NewDriveDynamicParameters()
            {
                return base.NewDriveDynamicParameters();
            }

        }

         public class EnvironmentDriveInfo : PSDriveInfo
        {
            public EnvironmentDriveInfo(PSDriveInfo driveInfo) : base(driveInfo)
            {
            }
        }


    }
    "@

    # -ea silentlycontinue in case its already loaded
    #
    add-type -referencedassemblies $referenced_assemblies -typedefinition $source -language CSharp -erroraction silentlycontinue

After import-module, I try to create the drive "environments":

new-psdrive -psprovider Environments -name "Environments" -root ""

errors with:

New-PSDrive : Cannot find a provider with the name 'Environments'.

Assuming the provider actually worked, maybe have it return a list of environments: dev, qa, staging, production.

Then I'd like to be able to re-use this through:

c:\adminlib>import-module .\EnvironmentProvider.ps1
c:\adminlib>environments:

environments:>ls
dev
qa
staging
production

environments:> cd production
environments\production> [execute actions against production]

environments\production:> cd dev
environments\dev:> [execute actions against dev, etc]
like image 319
Zach Bonham Avatar asked May 22 '12 20:05

Zach Bonham


People also ask

What is PSProvider in PowerShell?

The Get-PSProvider cmdlet gets the PowerShell providers in the current session. You can get a particular drive or all drives in the session. PowerShell providers let you access a variety of data stores as though they were file system drives. For information about PowerShell providers, see about_Providers.

What is the result of typing get help * in PowerShell?

Description. The Get-Help cmdlet displays information about PowerShell concepts and commands, including cmdlets, functions, Common Information Model (CIM) commands, workflows, providers, aliases, and scripts.

What does %% mean in PowerShell?

% is an alias for the ForEach-Object cmdlet. An alias is just another name by which you can reference a cmdlet or function.

How do I create a new PSDrive in PowerShell?

Adding New Windows PowerShell Drives (New-PSDrive) To create a new Windows PowerShell drive, you must supply three parameters: A name for the drive (you can use any valid Windows PowerShell name) The PSProvider (use "FileSystem" for file system locations and "Registry" for registry locations)


2 Answers

I would strongly recommend looking at the stuff Oisin wrote, suspect for people like you, who can grab their head around it, that could be very good reference on how-to. Or maybe what to avoid? ;) You can find it on codeplex: http://psprovider.codeplex.com/

like image 81
BartekB Avatar answered Nov 15 '22 04:11

BartekB


I know it's been some time since you asked the question, but I've been searching for that same answer myself. As it happens, re-reading the Samples in msdn finally got me my answer, and given the frustration quotient I thought I'd share:

The assembly containing the provider needs to be imported using Import-Module (not merely the module containing the add-type declaration). This can be done using two ways:

Option 1: Use the parameter of Add-Type that builds the runtime assembly as a .dll file and import the file.

Option 2: Import the runtime assembly from memory. This is how I did that with the standard msdn samples:

[appdomain]::CurrentDomain.GetAssemblies() | Where {$_.ExportedTypes -ne $null} | Where {($_.ExportedTypes | Select -ExpandProperty "Name") -contains "AccessDBProvider"} | Import-Module

Replace the Provider name in the where filter with your own.

Cheers, Fred

like image 36
Fred Avatar answered Nov 15 '22 03:11

Fred