PowerShell 启动前的 PSModulePath 变量要求
PSModulePath variable requirements before PowerShell starts
WPS = Windows PowerShell
PSC = PowerShell 核心
开始时,我有三 (3) 个路径作为系统环境变量的一部分 PSModulePath
。
%ProgramFiles%\WindowsPowerShell\Modules
%SystemRoot%\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\
我假设 SQL 服务器的安装创建了最后一个。但是,我删除了前两个以查看 PowerShell 是否可以找到自己的方式或者是否需要它们?
WPS 5.1 64-bit appears to start ok, but ISE reports an error finding `ISE`.
PSC 6.2 starts ok. There is no ISE.
PSC 7.0 starts ok. There is no ISE.
我不得不将 %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules
目录放回到系统环境变量 PSModulePath
中。之后,WPS 5.1 和 ISE 正常启动。
WPS 5 在启动前是否需要 PSModulePath
中的 System32 目录?我想删除它。而且,实际上,我想将 SQL 服务器目录移动到更合适的位置。还有更好的地方吗?我经常 运行 powershell -NoProfile
来自 .bat 文件脚本,所以我认为六 (6) 个配置文件脚本(如果添加 32 位则为 12 个)中的任何一个都不是一个好地方。你有什么建议?
更新
===开始cmd.exe
C:>echo %PSModulePath%
C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\;
=== 运行 powershell.exe 5.1.18362.145
C:>$Env:PSModulePath
C:\Users\lit\Documents\WindowsPowerShell\Modules;C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\;C:\Program Files\WindowsPowerShell\Modules
=== 运行 是
ipmo : The specified module 'ISE' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ ipmo ISE
+ ~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (ISE:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
顺便说一句,回复:
PSC 6.2 [7.0] starts ok. There is no ISE.
ISE 是 self-contained 可执行文件 hosts PowerShell,而不是相反。它只能承载WindowsPowerShell,不能承载PowerShellCore,所以你不能用它来开发PowerShellCore代码。
关于你的 follow-up 问题,"Should I expect there to ever be an ISE for PSC, or should I think VS Code is the thing to use?"
确实,Visual Studio Code with its PowerShell extension 是以后要使用的编辑器:它能够同时针对 Windows PowerShell 和 PowerShell Core,以及所有未来的开发努力将去那里。
相比之下,Windows PowerShell-only ISE 将看不到任何新功能。
(虽然 .NET Core 3.0 假设 为将 WPF-based ISE 移植到 .NET Core 铺平了道路,但我认为这不会发生。)
WPS 5.1 64-bit appears to start ok, but ISE reports an error finding ISE
.
从 $env:PSModulePath
中省略目录 $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
是 ill-advised 并导致以下症状:
位于那里的重要系统 (shipped-with-Windows PowerShell) 模块的命令仍然可执行,因为 PowerShell 显然 隐式参考这个位置。
但是,命令发现、Tab 完成和显式 模块 name 对 Import-Module
的调用(与完整路径相反)然后停止工作:
- 一个典型的例子是 ISE 的启动行为,它试图 显式地 加载
ISE
模块(以及其他模块) ipmo ISE
(Import- Module
),失败了。
- 隐式加载模块仍然有效可以通过简单地直接调用其命令之一来验证,例如
New-ISESnippet -?
.
在确定有效 $env:PSModulePath
值时,PS 版本根本不同:
Windows PowerShell (WPS) 使用复杂的规则来确定要自动 添加到 $env:PSModulePath
的目录;简而言之:
- all-users 模块目录,
$env:ProgramFiles%\WindowsPowerShell\Modules
总是 自动添加,如果您 $env:PSModulePath
值在注册表中预定义(默认情况下,它是预定义的,并设置为$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
)。
current-user 模块目录。仅在没有 user-level 注册表定义时添加。
您可以使用 process-level 值 $env:PSModulePath
设置临时 before 调用 powershell.exe
.
PowerShell 核心 (WPC):
完全忽略任何先前存在的registry-based定义$env:PSModulePath
并始终定义其自己的标准目录列表。在启动时,包括 WPS 位置 加上 WPS' system-module 目录 、[=11= 的 PSC 对应项](因为越来越多的 WPS 系统模块也可用于 PSC)。
- 此意外行为首次报告于 this GitHub issue、...
- ... 导致 this RFC,在撰写本文时仍悬而未决,最终解决方案尚未确定。
注入一个process-level值$env:PSModulePath
set ad hoc before 将 powershell.exe
调用到其标准目录列表中,在 current-user 条目之后 - 假设值 与任何 registry-based 不同 ] 定义.[1]
如果不是因为 registry-based 值和不同的临时值之间的模糊区别,PSC 的行为可以说是更明智的:它只允许 添加 到标准目录列表。通过预先存在的 $env:PSModulePath
environment-variable 值,而不是 替换 它。
忽略 registry-based 定义是有意义的,因为用户可能使用它指向包含 WSM-only 模块的目录。但是,如果为 PSC 选择了 不同的变量名称 ,则可以避免该问题 - 这确实是链接 RFC 中正在考虑的解决方案。
I would like to move the SQL Server directory to a more appropriate location. Is there a better place? I often run powershell -NoProfile
from .bat file scripts
没有修改$env:PSModulePath
的registry-based定义:
唯一适用于 两个 版本的目录是 $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
,但考虑到此目录用于 WPS, 不合适.
Edition-specifically,您可以选择:
- WPS:
$env:ProgramFiles\WindowsPowerShell\Modules
- PSC:
$env:ProgramFiles\PowerShell\Modules
用修改$env:PSModulePath
的registry-based定义:
对于WPS,您可以在\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
处修改$env:PSModulePath
的machine-level注册表定义(您也可以通过sysdm.cpl
, Advanced
> Environment Variables...
): 将您选择的目录添加到那里的现有值。
遗憾的是,在撰写本文时,这不适用于 PSC,因为它 忽略了 registry-based 定义ns,如前所述。
[1] 似乎对差异的测试执行得很草率,因为设置了一个临时值,其中 registry-based 值是 prefix匹配被认为是相同的;例如,如果在注册表中定义了值 c:\modules
,则临时值 c:\modules.core
会使 PowerShell Core 认为临时值 与 不同并忽略它.
除此之外,这种根据定义方法选择性地忽略 environment-variable 值的做法非常晦涩。
WPS = Windows PowerShell
PSC = PowerShell 核心
开始时,我有三 (3) 个路径作为系统环境变量的一部分 PSModulePath
。
%ProgramFiles%\WindowsPowerShell\Modules
%SystemRoot%\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\
我假设 SQL 服务器的安装创建了最后一个。但是,我删除了前两个以查看 PowerShell 是否可以找到自己的方式或者是否需要它们?
WPS 5.1 64-bit appears to start ok, but ISE reports an error finding `ISE`.
PSC 6.2 starts ok. There is no ISE.
PSC 7.0 starts ok. There is no ISE.
我不得不将 %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules
目录放回到系统环境变量 PSModulePath
中。之后,WPS 5.1 和 ISE 正常启动。
WPS 5 在启动前是否需要 PSModulePath
中的 System32 目录?我想删除它。而且,实际上,我想将 SQL 服务器目录移动到更合适的位置。还有更好的地方吗?我经常 运行 powershell -NoProfile
来自 .bat 文件脚本,所以我认为六 (6) 个配置文件脚本(如果添加 32 位则为 12 个)中的任何一个都不是一个好地方。你有什么建议?
更新
===开始cmd.exe
C:>echo %PSModulePath%
C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\;
=== 运行 powershell.exe 5.1.18362.145
C:>$Env:PSModulePath
C:\Users\lit\Documents\WindowsPowerShell\Modules;C:\Program Files (x86)\Microsoft SQL Server0\Tools\PowerShell\Modules\;C:\Program Files\WindowsPowerShell\Modules
=== 运行 是
ipmo : The specified module 'ISE' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ ipmo ISE
+ ~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (ISE:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
顺便说一句,回复:
PSC 6.2 [7.0] starts ok. There is no ISE.
ISE 是 self-contained 可执行文件 hosts PowerShell,而不是相反。它只能承载WindowsPowerShell,不能承载PowerShellCore,所以你不能用它来开发PowerShellCore代码。
关于你的 follow-up 问题,"Should I expect there to ever be an ISE for PSC, or should I think VS Code is the thing to use?"
确实,Visual Studio Code with its PowerShell extension 是以后要使用的编辑器:它能够同时针对 Windows PowerShell 和 PowerShell Core,以及所有未来的开发努力将去那里。
相比之下,Windows PowerShell-only ISE 将看不到任何新功能。 (虽然 .NET Core 3.0 假设 为将 WPF-based ISE 移植到 .NET Core 铺平了道路,但我认为这不会发生。)
WPS 5.1 64-bit appears to start ok, but ISE reports an error finding
ISE
.
从 $env:PSModulePath
中省略目录 $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
是 ill-advised 并导致以下症状:
位于那里的重要系统 (shipped-with-Windows PowerShell) 模块的命令仍然可执行,因为 PowerShell 显然 隐式参考这个位置。
但是,命令发现、Tab 完成和显式 模块 name 对
Import-Module
的调用(与完整路径相反)然后停止工作:- 一个典型的例子是 ISE 的启动行为,它试图 显式地 加载
ISE
模块(以及其他模块)ipmo ISE
(Import- Module
),失败了。 - 隐式加载模块仍然有效可以通过简单地直接调用其命令之一来验证,例如
New-ISESnippet -?
.
- 一个典型的例子是 ISE 的启动行为,它试图 显式地 加载
在确定有效 $env:PSModulePath
值时,PS 版本根本不同:
Windows PowerShell (WPS) 使用复杂的规则来确定要自动 添加到 $env:PSModulePath
的目录;简而言之:
- all-users 模块目录,
$env:ProgramFiles%\WindowsPowerShell\Modules
总是 自动添加,如果您$env:PSModulePath
值在注册表中预定义(默认情况下,它是预定义的,并设置为$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
)。 current-user 模块目录。仅在没有 user-level 注册表定义时添加。
您可以使用 process-level 值
$env:PSModulePath
设置临时 before 调用powershell.exe
.
PowerShell 核心 (WPC):
完全忽略任何先前存在的registry-based定义
$env:PSModulePath
并始终定义其自己的标准目录列表。在启动时,包括 WPS 位置 加上 WPS' system-module 目录 、[=11= 的 PSC 对应项](因为越来越多的 WPS 系统模块也可用于 PSC)。- 此意外行为首次报告于 this GitHub issue、...
- ... 导致 this RFC,在撰写本文时仍悬而未决,最终解决方案尚未确定。
注入一个process-level值
$env:PSModulePath
set ad hoc before 将powershell.exe
调用到其标准目录列表中,在 current-user 条目之后 - 假设值 与任何 registry-based 不同 ] 定义.[1]如果不是因为 registry-based 值和不同的临时值之间的模糊区别,PSC 的行为可以说是更明智的:它只允许 添加 到标准目录列表。通过预先存在的
$env:PSModulePath
environment-variable 值,而不是 替换 它。忽略 registry-based 定义是有意义的,因为用户可能使用它指向包含 WSM-only 模块的目录。但是,如果为 PSC 选择了 不同的变量名称 ,则可以避免该问题 - 这确实是链接 RFC 中正在考虑的解决方案。
I would like to move the SQL Server directory to a more appropriate location. Is there a better place? I often run
powershell -NoProfile
from .bat file scripts
没有修改$env:PSModulePath
的registry-based定义:
唯一适用于 两个 版本的目录是
$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules
,但考虑到此目录用于 WPS, 不合适.Edition-specifically,您可以选择:
- WPS:
$env:ProgramFiles\WindowsPowerShell\Modules
- PSC:
$env:ProgramFiles\PowerShell\Modules
- WPS:
用修改$env:PSModulePath
的registry-based定义:
对于WPS,您可以在
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
处修改$env:PSModulePath
的machine-level注册表定义(您也可以通过sysdm.cpl
,Advanced
>Environment Variables...
): 将您选择的目录添加到那里的现有值。遗憾的是,在撰写本文时,这不适用于 PSC,因为它 忽略了 registry-based 定义ns,如前所述。
[1] 似乎对差异的测试执行得很草率,因为设置了一个临时值,其中 registry-based 值是 prefix匹配被认为是相同的;例如,如果在注册表中定义了值 c:\modules
,则临时值 c:\modules.core
会使 PowerShell Core 认为临时值 与 不同并忽略它.
除此之外,这种根据定义方法选择性地忽略 environment-variable 值的做法非常晦涩。