对用户隐藏导出的PowerShell函数

uinbv5nw  于 2023-01-26  发布在  Shell
关注(0)|答案(4)|浏览(97)

标题已经说得很清楚了,但我还是要问得更精确一些,所以问题是,是否有可能从模块中导出帮助函数,并使它们只能在代码中重用,但仅限于用户使用,因此用户无法从控制台调用它们?
先谢谢你!

of1yzvn4

of1yzvn41#

当然,你只需要指定你是什么样的导出(在psm文件):

Export-ModuleMember  -Function Verb-Noun

这将只导出这一个函数,并在您的psd文件中:

FunctionsToExport = 'Verb-Noun'
ma8fv8wu

ma8fv8wu2#

我不认为这是可能的方式,你想这样做。我会如何处理它是有一个PS1文件在帮助模块中包含所有隐藏的命令,但不加载它作为帮助模块的一部分。然后在模块中依赖于它,简单的点源PS1帮助文件,它将导入所有的脚本,它使用。
例如,在需要帮助模块的模块中:

. $PSScriptRoot\..\HelperModule\HelperModuleInternal.ps1

显然,用helper模块的名称和隐藏命令ps1文件分别替换helperModule和helperModuleInternal。注意,如果你把它做成一个psm1文件,它只会打开伊势。
我不确定,但它可能仍然试图导出隐藏的命令,如果是这样的话,我读到一个处理它的巧妙技巧。调用所有发布的命令通常Verb-Noun语法,并在最后把Export-ModuleMember -Function "*-*"。然后为您的内部命令,使用命名不符合这一点,如Verb_NounVerbNoun。非常整洁。

bxgwgixi

bxgwgixi3#

我发现了两种方法来达到你想要的效果,虽然它们都不干净也不直观。我认为这个问题是由自动加载$Env:PSModulePath目录中的任何模块引起的。下面是对我有效的方法,你可以选择你的毒药。

选项1:关闭模块自动加载

  • 在父模块清单中,将helper模块的名称添加为嵌套模块:NestedModules = @('MyHelperModule')
  • 在配置文件中,将$PSModuleAutoloadingPreference设置为'None''ModuleQualified'。这将阻止helper模块自动加载,从而阻止helper模块暴露给用户。不幸的是,这也将阻止所有其他模块自动加载,这意味着您还必须在配置文件中添加Import-Module语句,以显式加载您希望在每个会话开始时出现的模块。并手动导入任何额外的文件。根据您的工作方式,这可能会比它的价值更麻烦。
    选项2:移动助手模块
  • 将助手模块移到$Env:PSModulePath列表中没有的目录中,例如C:\MyHiddenModules\MyHelperModule。
  • 在父模块清单中,将helper模块的完整路径添加为嵌套模块:NestedModules = @('C:\MyHiddenModules\MyHelperModule\MyHelperModule.psm1')

在这两种情况下,都可以使用父清单中的FunctionsToExport数组来控制要向用户公开哪些帮助器函数(如果有)。
有关$PSModuleAutoloadingPreference首选项变量的详细信息。

qncylg1j

qncylg1j4#

用例标准:

  • 函数存储在powershell模块或脚本文件中
  • 将函数加载到内存
  • 您不希望对整个文件进行点源编码,因为脚本可能包含可执行命令
  • 您不希望手动解析文件,因为这样做很恶心
  • 当你使用完你的函数后,你希望它被删除,这样用户就不能访问它了
  • 您不想或无法加载包含所需函数的整个模块

局限性:

  • Powershell日志记录仍将显示此操作已执行
  • 您知道函数存储的确切文件

解释方式:

  • 将代码 Package 到try/finally块中。
  • Try块中
  • 使用Get-Function按名称收集所需的函数,并将结果通过管道传输到Invoke-Expression以将其加载到内存中。加载的函数将仅存储在当前powershell示例的作用域中,并且不能用于同一计算机上的其他powershell示例。
  • 然后执行您想要的命令
  • Finally块中
  • 执行命令删除先前加载的函数,以防止用户访问它们
  • finally块中包含的代码将在控制权传递回用户之前执行,即使用户在运行期间的任何时候按下Control + C

方法示例:

Try {
    # load the 
    Get-Function -Path "$($ModulePath)\Library_GeneralPurpose.ps1" -Name Get-DeathStarPlans | Invoke-Expression

    # run the super secret function
    Get-DeathStarPlans -IncludeCriticalWeaknesses
    }
Finally {
    # remove function from memory to prevent rebel alliance from accessing the source code or running it them selves
    Remove-Item -Path Function:\Get-DeathStarPlans -Force
    }

获取函数

这个函数需要已经加载,或者您可以删除特定的命令。

function Get-Function {
    <# 
    .SYNOPSIS 
        Returns a named function from a .ps1 file without executing the file
    .DESCRIPTION
        This is useful where you have a blended file containing functions and executed instructions.

        If neither -Names nor -Regex are provided then all functions in the file are returned.
        Returned objects can be piped directly into Invoke-Expression which will place them into the current scope.

        Returns an array of objects with the following
            - .ToString()
            - .Name
            - .Parameters
            - .Body
            - .Extent
            - .IsFilter
            - .IsWorkFlow
            - .Parent

    .PARAMETER -Files
        Array of file paths or file objects;
        These files will be parsed

    .PARAMETER -Names 
        Array of Strings; Optional; Case Insensitive
        If provided then function objects of these names will be returned
        The name must exactly match the provided value

    .PARAMETER -Regex
        Regular Expression; Optional; Case Insensitive
        If provided then function objects with names that match will be returned

    .EXAMPLE
        Get all the functions names included in the file
            Get-Function -name TestA | Select-Object name

    .EXAMPLE
        Import a function into the current scope
            Get-Function -name TestA | Invoke-Expression

    .EXAMPLE
        Get a single function from this library file
            $Function = "$($ModulePath)\Library_GeneralPurpose.ps1" | Get-Function -Name Get-Function
            $Function.ToString()

    .EXAMPLE
        Load a function then remove it to prevent it from being usable by the user
            Try {
                # load the 
                "$($ModulePath)\Library_GeneralPurpose.ps1" | Get-Function -Name Get-DeathStarPlans | Invoke-Expression

                # run the super secret function
                Get-DeathStarPlans -IncludeCriticalWeaknesses
                }
            Finally {
                # remove function from memory to prevent rebel alliance from accessing the source code
                Remove-Item -Path Function:\Get-DeathStarPlans -Force
                } 
    #>
    param (
        [Parameter(Position=0, ValueFromPipeline=$True)]
        [alias("File", "Paths")]
        $Files
        , 
        [alias("Name", "FunctionNames", "Functions")]
        $Names
        ,
        [alias("NameRegex")]
        $Regex
        ) # end function
    Process {
        foreach ( $File in $Files ) {
            # get the script
            $Script = $File | Get-Item | Select-Object -ExpandProperty Fullname | Get-Command
            # parse out all the functions
            $AllFunctions = $Script.ScriptBlock.AST.FindAll({$args[0] -is [Management.Automation.Language.FunctionDefinitionAst]}, $false)

            # return all requested functions
            $AllFunctions | Where-Object { `
                ( $Names -and $Names -icontains $_.Name ) `
                -or ( $Regex -and $_.Name -imatch $Regex ) `
                -or (-not $Names -and -not $Regex) `
                } # end where-object
            } # next file
        } # end process
    } # end function Get-Function

相关问题