PowerShell启动之前的PSModulePath变量要求

时间:2019-06-15 23:21:57

标签: powershell powershell-5.0

WPS = Windows PowerShell
PSC = PowerShell核心

开始时,我有三(3)条路径作为系统环境变量PSModulePath的一部分。

%ProgramFiles%\WindowsPowerShell\Modules
%SystemRoot%\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server\140\Tools\PowerShell\Modules\

我假设SQL Server的安装创建了最后一个。但是,我删除了前两个,以查看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 Server目录移动到更合适的位置。有没有更好的地方?我经常从.bat文件脚本运行powershell -NoProfile,所以我认为六(6)个配置文件脚本(如果添加了32位,则为12)都不是一个好地方。你有什么建议?

更新

===启动cmd.exe

C:>echo %PSModulePath%
C:\Program Files (x86)\Microsoft SQL Server\140\Tools\PowerShell\Modules\;

===运行powershell.exe 5.1.18362.145

C:>$Env:PSModulePath
C:\Users\lit\Documents\WindowsPowerShell\Modules;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\PowerShell\Modules\;C:\Program Files\WindowsPowerShell\Modules

===运行ise

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

1 个答案:

答案 0 :(得分:1)

顺便说一句,重新:

  

PSC 6.2 [7.0]开始正常。没有ISE。

ISE是一个自包含的可执行文件,可以托管 PowerShell,而不能相反。它只能承载 Windows PowerShell ,不能承载PowerShell Core ,因此您不能使用它来开发PowerShell Core 代码。

关于您的后续问题,“我是否应该为PSC使用ISE,还是应该使用VS Code?”

实际上, Visual Studio Code及其PowerShell extension是以后使用的编辑器:它能够同时针对Windows PowerShell和PowerShell Core,并且将来的所有开发工作都将去那里。

相比之下,仅Windows PowerShell的ISE将看不到任何新功能。 (虽然.NET Core 3.0 假设地为将基于WPF的ISE移植到.NET Core铺平了道路,但我认为这不会发生。)


  

WPS 5.1 64位似乎可以正常启动,但是ISE报告发现错误ISE

$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules省略目录$env:PSModulePath的建议不正确,并导致以下症状:

  • 位于重要系统(Windows PowerShell附带)中的命令仍然是可执行文件,因为PowerShell显然是隐式咨询此位置。

  • 但是,命令发现,制表符完成和模块 name Import-Module explicit 调用(相对于完整路径)然后停止工作:

    • 最重要的是ISE的启动行为,该行为试图显式ISEipmo ISE加载Import- Module模块(以及其他) ,但失败。
    • 隐式仍然可以正常加载模块,只需直接调用其命令之一,例如New-ISESnippet -?,即可验证。

在确定有效$env:PSModulePath值时,PS版本存在根本差异:

Windows PowerShell(WPS)使用复杂的规则来确定要自动 添加到$env:PSModulePath的目录;简而言之:

  • 如果在中预定义了$env:ProgramFiles%\WindowsPowerShell\Modules的值,则 all-users 模块目录$env:PSModulePath始终会自动添加 。注册表(默认情况下,它是 预先定义,并设置为$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules)。
  • 当前用户模块目录。仅当没有用户级注册表定义时才添加。

  • 您可以在调用$env:PSModulePath之前,使用临时设置为powershell.exe进程级值覆盖所有注册表定义。 / p>

PowerShell Core(WPC):

  • 完全忽略任何$env:PSModulePath基于注册表的定义,并始终定义其自己的标准目录列表。在启动时,包括WPS位置加上WPS的系统模块目录 $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules的PSC副本(因为PSC还可使用越来越多的WPS系统模块)。

    • 此意外行为最早是在this GitHub issue,...
    • 中报告的
    • ...导致this RFC,在撰写本文时仍未决,最终决议尚未确定。
  • 注入值为$env:PSModulePath进程级值,然后在调用powershell.exe当前用户条目之后的标准目录列表-假定值与任何基于注册表的定义都不同 [1]

    • 如果不是出于基于注册表的值和(即不同的)临时值之间的模糊区别,则PSC的行为可以说是更明智的:它只允许在添加标准目录列表。通过预先存在的$env:PSModulePath环境变量值,而不是替换

    • 忽略基于注册表的定义很有意义,因为用户可能已经使用它来指向包含仅WSM模块的目录。但是,如果为PSC选择了不同的变量名,则可以避免该问题-的确是链接的RFC中正在考虑的解决方案。


  

我想将SQL Server目录移动到更合适的位置。有没有更好的地方?我经常从.bat文件脚本运行powershell -NoProfile

没有修改$env:PSModulePath的基于注册表的定义:

  • 同时适用于两个版本的唯一目录为$env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules,但鉴于此目录适用于WPS附带的模块,因此不合适。

  • 特定于版本,您可以选择:

    • WPS:$env:ProgramFiles\WindowsPowerShell\Modules
    • PSC:$env:ProgramFiles\PowerShell\Modules

使用修改$env:PSModulePath的基于注册表的定义:

  • 对于WPS,您可以在$env:PSModulePath处修改\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment的计算机级注册表定义(也可以通过sysdm.cplAdvanced> { {1}}:添加您选择的目录到那里的现有值。

  • 很遗憾,在撰写本文时,它不适用于PSC,因为如上所述,它忽略了基于注册表的定义。


[1]看来,对差异的测试是草率地实施的,因为设置基于注册表的值是 prefix 匹配的临时值被认为是相同的;例如,如果在注册表中定义了值Environment Variables...,则临时值c:\modules使PowerShell Core认为该临时值没有差异,而将其忽略。
除此之外,根据环境变量的定义方法对环境变量值的这种选择性忽略是非常模糊的。