PowerShell函数内点源.ps1文件如何加载到父作用域?
问题原因
你当前的代码中,点源操作是在Reload-ToolBox的局部作用域执行,所有加载的函数、变量会在函数执行结束后自动销毁,无法保留到调用函数的父作用域。
解决方案
方案1:调用时加.(改动最小,无需修改函数代码)
直接在调用函数前加一个点和空格,让整个函数在当前作用域执行,内部点源的内容会自然保留在父作用域:
# 示例调用 . Reload-ToolBox -Name All
方案2:修改函数逻辑,默认加载到父作用域
如果你希望用户直接调用函数就能生效,不需要额外加.,使用修改后的代码:
function Reload-ToolBox { [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] [ValidateSet('TechToolBox', 'NetworkToolBox','All')] [string[]]$Name = 'TechToolBox' ) Begin { $ToolBoxes = @{ TechToolBox = "\\path\to\my\ps1.ps1" NetworkToolBox = "\\path\to\my\ps2.ps1" } # 修正All的逻辑,直接返回所有路径数组 if ($Name -contains 'All') { $loadPaths = $ToolBoxes.Values } else { $loadPaths = $Name | ForEach-Object { $ToolBoxes[$_] } } } Process { foreach ($path in $loadPaths) { # 显式指定不在局部作用域运行,直接在父作用域执行点源 $PSCmdlet.SessionState.InvokeCommand.InvokeScript( $false, # 不使用局部作用域,直接在父作用域执行 [scriptblock]::Create(". `"$path`""), $null, $null ) } } End { } }
修改说明
- 新增
[CmdletBinding()]将函数转为高级函数,可访问会话上下文 - 修正了原代码中
All参数的逻辑错误,原逻辑会将路径转为字符串无法正常点源 - 使用
InvokeScript方法指定点源操作在父作用域执行,无需调用方额外加前缀
内容的提问来源于stack exchange,提问作者Abraham Zinala
相关产品推荐
相关产品推荐

