从自定义提供程序的C#代码加载Powershell模块

时间:2015-09-25 15:44:39

标签: c# powershell powershell-provider

我一直致力于一个非常具体的功能“需要”与我用C#编写的自定义提供程序绑定。

基本上我开始寻找复制

的方法
A:
B:
PowerShell加载时定义的

等函数,而不必键入

CD A:

你可以做上述的

A:

我首先尝试让我的提供者将函数注入到运行空间中,但似乎我完全错过了如何使其工作的时间,所以我走了另一条路。

基本上我有一个非常简单的PSM1文件UseColons.psm1

function Use-ColonsForPSDrives
{
    [CmdletBinding()] Param()

    Write-Verbose "Looping Through Installed PowerShell Providers"
    Get-PSProvider | % `
    {
        Write-Verbose "Found $($_.Name) checking its drives"
        $_.Drives | ? { (Get-Command | ? Name -eq "$($_.Name):") -eq $null } | `
        { 
            Write-Verbose "Setting up: `"function $($_.Name):() {Set-Location $($_.Name):}`""
            if ($Verbose)
            {
                . Invoke-Expression -Command "function $($_.Name):() {Set-Location $($_.Name):}" 
            }
            else
            {
                . Invoke-Expression -Command "function $($_.Name):() {Set-Location $($_.Name):}" -ErrorAction SilentlyContinue
        }
            Write-Verbose "Finished with drive $($_.Name)"
        }
    }
    # Cert and WSMan do not show up as providers until you try to naviagte to their drives
    # As a result we will add their functions manually but we will check if they are already set anyways
    if ((Get-Command | ? Name -eq "Cert:") -eq $null) { . Invoke-Expression -Command "function Cert:() {Set-Location Cert:}" }
    if ((Get-Command | ? Name -eq "WSMan:") -eq $null) { . Invoke-Expression -Command "function WSMan:() {Set-Location WSMan:}" }
}

. Use-ColonsForPSDrives

简单来说,它遍历所有加载的提供程序,然后遍历每个提供程序的所有驱动器,然后检查Function:驱动器是否包含与{DriveName}:格式匹配的函数,如果找不到,则创建一个。

psd1文件只不过是导出所有函数

它存储在自己的文件夹下的%ProgramFiles%\ WindowsPowerShell \ Modules路径中

最后我在%windir%\ system32 \ windowspowershell \ v1.0目录下有profile.ps1

Remove-Module UseColons -ErrorAction SilentlyContinue
Import-Module UseColons

所以当我加载PowerShell或ISE时,如果我想通过变量说dir我可以调用

Variable:

或者如果我需要切换回注册表

HKLM:
HKCU:

当您使用多个提供商在切换时反复输入该CD时,这很烦人。

现在问题我还在努力开发最初用于的实际PowerShell提供程序。但是当我调试它时,UseColons模块会在Visual Studio转向并加载新的提供程序之前加载,所以如果我再次手动删除并导入模块,它会完成它的工作,并为我的提供程序提供所有驱动功能。

我想知道LONG解释后我怎么能:

  • 设置我的UseColons模块以加载LAST
  • 找到一种方法让我的自定义提供程序(技术上是一个模块,因为它有提供程序和自定义Cmdlet)在初始化时加载UseColons模块
  • 我不想将其从我的标准配置文件中删除,因为当我不使用新的提供程序并且只使用PowerShell来管理内容时,它非常有用。

    希望有人可以给我一些想法,或者指出一些更深入的潜力供应商提供文件和方法。

    1 个答案:

    答案 0 :(得分:0)

    在您的模块清单(.psd1)中,您有一个DLL作为RootModule?

    这是一个可怕的黑客攻击,并且对将来创建的驱动器没有帮助,但是......

    在模块清单中,不使用YourProvider.dll作为RootModule,而是使用Dummy.psm1(可以是空文件)。然后,对于NestedModules,使用@( 'YourProvider.dll', 'UseColons' )。这允许在 YourProvider.dll之后加载UseColons模块。 (假人将是最后一次。)