Powershell配置文件脚本是否源于点?

Powershell配置文件脚本是否源于点?,powershell,Powershell,我使用的Microsoft.PowerShell\u profile.ps1脚本在运行时会创建许多变量。我已经将所有变量的作用域设置为“Script”,但脚本中使用的变量从未超出作用域 我希望在脚本运行完毕并将控制权移交给我之后,变量就超出范围 如果我比较全局变量、局部变量和脚本变量的数量,就会得出相同的数量 例如: # Profile script does what it does. Get-Variable -Scope Global | Measure-Object Get-Varia

我使用的Microsoft.PowerShell\u profile.ps1脚本在运行时会创建许多变量。我已经将所有变量的作用域设置为“Script”,但脚本中使用的变量从未超出作用域

我希望在脚本运行完毕并将控制权移交给我之后,变量就超出范围

如果我比较全局变量、局部变量和脚本变量的数量,就会得出相同的数量

例如:

# Profile script does what it does.

Get-Variable -Scope Global | Measure-Object
Get-Variable -Scope Local  | Measure-Object
Get-Variable -Scope Script | Measure-Object

Output:
60
60
60
$snapshotBefore = Get-Variable
$profileVar1 = 'some value'
$profileVar2 = 'some other value'
$snapshotAfter = Get-Variable

# Compare before and after, and create list of new variables.

Remove-Variable $variablesToRemove
目前,我正在概要文件脚本的开头捕获变量的快照,然后在结尾删除任何新变量

例如:

# Profile script does what it does.

Get-Variable -Scope Global | Measure-Object
Get-Variable -Scope Local  | Measure-Object
Get-Variable -Scope Script | Measure-Object

Output:
60
60
60
$snapshotBefore = Get-Variable
$profileVar1 = 'some value'
$profileVar2 = 'some other value'
$snapshotAfter = Get-Variable

# Compare before and after, and create list of new variables.

Remove-Variable $variablesToRemove

是的,PowerShell配置文件是由design提供的点源文件,因为允许其中包含的定义(别名、函数等)在默认情况下全局可用——这毕竟是配置文件的主要用途

不幸的是,没有范围修饰符允许您为您只想在配置文件加载时存在的变量创建临时范围——甚至范围
本地
在配置文件脚本中实际上是全局的;类似地,使用scope
private
也不是一个选项,因为配置文件的脚本范围(由于源于点)是全局范围

一般来说,您可以将
&
(调用运算符)与脚本块一起使用,在该块内创建变量,这些变量的作用域为该块,但这通常与在概要文件中创建全局可用的定义不一致,至少在默认情况下是如此。
类似地,在您自己的答案中调用另一个脚本而不使用点源,默认情况下不会使其定义全局可用。
但是,您可以通过显式指定全局范围,从非点源脚本块/脚本创建全局元素;e、 g.:
&{$global:foo='Going global'}
,或
&{function global:bar{'global func'}

这就是说,dot寻源配置文件背后的基本原理可能是,默认情况下更容易使所有定义全局化,从而使配置文件的典型元素(别名、函数、驱动器映射、模块加载)的定义更简单(无需指定明确的范围)。
相比之下,全局变量不太典型,要定义上面列出的典型元素,您的概要文件中通常不需要脚本级别(因此也不需要全局)变量


如果您仍然需要在概要文件中创建(概念上)临时变量(这不是创建全局可用别名、函数等的要求):

一个简单的解决方法是在配置文件脚本中使用外来变量名前缀,例如
\uuuuu
,以减少意外引用它们的风险(例如,
$\uuuuuprofilevar1=…
) 换句话说:变量仍然全局存在,但它们的外来名称通常不会引起问题

然而,您的方法,尽管它需要一些额外的工作,听起来像是一个健壮的解决方案,下面是它的完整外观(使用PSv3+语法):

请注意,我依赖于
Compare Object
的默认行为,即只报告对象之间的差异,并且假设您没有尝试删除任何变量,则只报告添加的变量


请注意,虽然可以从配置文件的实际行为推断它们确实是点源文件,但考虑到点源文件是将元素添加到当前范围(配置文件中为全局范围)的唯一方法,因此- 这一事实并没有明确记录下来

以下是各种帮助主题(从PSv5开始)的片段,它们提供了线索(重点是我的):

获取有关\u配置文件的帮助

Windows PowerShell配置文件是在Windows PowerShell运行时运行的脚本 开始您可以将配置文件用作登录脚本来自定义 环境可以添加命令、别名、函数、变量、管理单元、, 模块和Windows PowerShell驱动器。您还可以添加其他驱动器 将特定于会话的元素添加到您的配置文件中,以便在每个 会话,而无需导入或重新创建它们

获取有关变量的帮助

默认情况下,变量仅在以下范围内可用: 它们是被创造出来的

例如,在函数中创建的变量是 仅在函数中可用。一个你需要的变量 在脚本中创建仅在脚本中可用(除非 您可以点源脚本,这会将脚本添加到当前范围

获取有关\u运算符的帮助

。网点采购运营商 在当前范围内运行脚本,以便, 脚本创建的别名和变量将添加到当前 范围。

获取有关\u范围的帮助

但是,您可以使用点将脚本或函数添加到当前范围 源符号。然后,当脚本在当前范围内运行时,任何 脚本创建的函数、别名和变量可用 在当前范围内

要将函数添加到当前范围,请在前面键入点(.)和空格 函数调用中函数的路径和名称


听起来确实像是Powershell dot提供了个人资料。我找不到一个资源,特别是说,或其他论坛提出了这个问题

我找到了答案,想把它贴在这里

我已将配置文件更改为仅调用脚本文件。脚本现在有自己的作用域,只要变量不是全局的,一旦概要文件加载完成,它们就会超出作用域

现在我的个人资料有一行:

& (Split-Path $Path $profile -Parent | Join-Path "Microsoft.PowerShell_profile_v2.ps1")