在模块中的PowerShell函数上使用脚本范围修饰符无效?

时间:2015-01-07 08:10:16

标签: powershell powershell-module

我假设在PowerShell模块中的函数上使用script范围修饰符会阻止导出函数。样品:

function script:Get-One { 1 }

导入模块时,导出Get-One功能。

问题

  1. 是否应该使用script范围修饰符来使模块函数变为私有?
  2. 如果没有:为什么?我可以使用的任何其他范围修饰符?

  3. 我知道我可以使用Export-ModuleMember来控制要导出的函数,但我只有一些不应导出的函数。我宁愿指定要忽略哪些函数。

2 个答案:

答案 0 :(得分:1)

模块中的

script范围是多余的,因为默认范围是其定义的脚本/模块。它相当于一个实例变量。模块中的global类似于静态变量。例如,Posh-Git使用全局首选项变量来实现shell之间的一致性。

我使用了内存模块,但是当使用psd1定义New-Module

的参数时,这个想法是一样的
# remove module from namespace for repeated testing
if(Get-Module -Name 'SOTest') { Remove-Module -Name 'SOTest' }

new-Module -Function:'*' -Name:'SOTest' -ScriptBlock {

    $global:helpers = [PSCustomObject]@{}
    Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFoo' -Value { return "Private Foo!" }
    Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFooWithArgs' -Value { return "Private " + $args -join ',' + '!'  }
    Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFooWithParams' -Value { param ([string]$str, [int]$num); return "Private Str = $str + num; $num!"  }


    ## script: scope refers to module scope, which makes it redundant
    function WriteFoo {
        Write-Output "PublicFoo!"
    }

    function WritePrivate { 
        #This fails, because the private now refers to the function scoped $private:helpers 
        $private:helpers.HiddenFoo | Write-Verbose -Verbose
    }

    function WritePrivateShort {
        # This works because the helpers object is static across instances
        $helpers.HiddenFoo() | Write-Verbose -Verbose
        $helpers.HiddenFooWithArgs("Cow", "Moo") | Write-Verbose -Verbose
        $helpers.HiddenFooWithParams("Four", 4) | Write-Verbose -Verbose
        # This errors due to argument type mismatch
        $helpers.HiddenFooWithParams("Five", "Five") | Write-Verbose -Verbose

    }

} | Import-Module

# Prefer short errors for this demo
$ErrorView = "CategoryView"

Get-Module -Name 'SOTest'
'WF-----------------'
WriteFoo
'WP-----------------'
WritePrivate
'WPS----------------'
WritePrivateShort
'-------------------'

输出:

ModuleType Version    Name                                ExportedCommands                                                                                                            
---------- -------    ----                                ----------------                                                                                                            
Script     0.0        SOTest                              {WriteFoo, WritePrivate, WritePrivateShort}                                                                                 
WF-----------------
PublicFoo!
WP-----------------
InvalidData: (:) [Write-Verbose], ParameterBindingValidationException
WPS----------------
VERBOSE: Private Foo!
VERBOSE: Private Cow Moo
VERBOSE: Private Str = Four + num = 4!
InvalidArgument: (:) [], RuntimeException
-------------------

答案 1 :(得分:0)

对于Powershell模块,Export-ModuleMember是首选方法。

作为替代方案,您可以定义您不希望从使用它的函数内部导出的函数(例如,在Begin块中)。

这使得该功能仅由" parent"功能,使其有效私密。

此外,您可以尝试使用专用范围,而不是脚本范围。