Требования к переменной PSModulePath перед запуском PowerShell - PullRequest
2 голосов
/ 16 июня 2019

WPS = Windows PowerShell
PSC = PowerShell Core

Когда я начал, у меня было три (3) пути как часть системной переменной среды PSModulePath.

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

Я предполагаю, что установка SQL Server создала последнюю. Но я удалил первые два, чтобы посмотреть, смогут ли PowerShells найти свой собственный путь или они им нужны?

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 каталог System32 в PSModulePath до его запуска? Я хотел бы удалить это. И, на самом деле, я хотел бы переместить каталог SQL Server в более подходящее место. Есть ли лучшее место? Я часто запускаю powershell -NoProfile из файловых сценариев .bat, поэтому я не думаю, что какой-либо из шести (6) сценариев профиля (12, если добавлено 32-разрядное) является хорошим местом. Что вы предлагаете?

Обновление

=== start cmd.exe

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

=== run 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

=== run 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 Ответ

1 голос
/ 16 июня 2019

Кроме того, re:

PSC 6.2 [7.0] запускается нормально.ISE не существует.

ISE - это автономный исполняемый файл, который хостов PowerShell, а не наоборот.Он может содержать только Windows PowerShell , но не PowerShell Core , поэтому его нельзя использовать для разработки кода PowerShell Core .

на вопрос: «Стоит ли ожидать, что когда-нибудь будет ISE для PSC, или я должен думать, что VS Code стоит использовать?»

Действительно, Код Visual Studio сего расширение PowerShell - это редактор для дальнейшего использования : он способен нацеливаться как на Windows PowerShell, так и на PowerShell Core, и все дальнейшие усилия по его разработке пойдут туда.

В отличие от этого, ISE только для Windows PowerShell не увидит новых функций .(Хотя .NET Core 3.0 гипотетически прокладывает путь для переноса ISE на основе WPF в .NET Core, я не думаю, что это произойдет.)


64-разрядный WPS 5.1, кажется, запускается хорошо, но ISE сообщает об обнаружении ошибки ISE.

Пропуск каталога $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules из $env:PSModulePath является опрометчивым и приводит к следующемуСимптомы:

  • Команды из важных системных модулей (поставляются с Windows PowerShell), которые там находятся, все еще исполняемые , поскольку PowerShell, по-видимому, неявно обращается к этому расположению.

  • Однако обнаружение команд, завершение табуляции и явные вызовы Import-Module по модулю name (в отличие от полного пути), затем перестаньте работать:

    • Речь идет о поведении при запуске ISE, который пытается явно загрузить модуль ISE (среди прочих)с ipmo ISE (Import- Module), который завершается неудачей.
    • Это неявно загрузкамодуль по-прежнему работает, его можно проверить, просто напрямую вызвав одну из его команд, например, New-ISESnippet -?.

Когда дело доходит до определения эффективногоПри значении $env:PSModulePath редакции PS существенно различаются:

Windows PowerShell (WPS) использует сложные правила, чтобы определить, какие каталоги автоматически добавить к $env:PSModulePath;Короче говоря:

  • * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 * * * * * * * * * * * * * * * * * * * * * 10 * * * * * * * * * * * * * * * * * *] * реестр (по умолчанию он является предопределенным и установлен на $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules).
  • текущий пользователь модуль dir,добавляется только в том случае, если отсутствует определение реестра на уровне пользователя .

  • Вы можете переопределить все определения реестра значением уровня процесса , равным $env:PSModulePath установить ad hoc до вызова powershell.exe.

PowerShell Core (WPC):

  • полностью игнорирует любые ранее существовавшие определения на основе реестра $env:PSModulePath и всегда определяет свой собственный список стандартных директорий.при запуске, включая аналоги PSC для местоположений WPS плюс каталог системных модулей WPS , $env:SYSTEMROOT\system32\WindowsPowerShell\v1.0\Modules (поскольку из PSC также можно использовать все большее количество системных модулей WPS).

    • Это неожиданное поведение впервые было сообщено в этой проблеме GitHub , ...
    • ..., которая привела к этому RFC , который все еще находится на рассмотренииэто письмо, с окончательным разрешением еще не решено.
  • вводит a уровень процесса значение $env:PSModulePath установить объявлениеhoc перед вызовом powershell.exe в свой список стандартных каталогов после записи текущего пользователя - при условии, что значение отличается от любого определения на основе реестра. [1]

    • Если бы не было неясного различия между значением на основе реестра и специальным специальным значением, поведение PSC, возможно, более разумно: оно позволяет только добавлять в списокстандартных реж.через существующее $env:PSModulePath значение переменной среды, а не , заменяющее it.

    • Игнорирование определений на основе реестра имеет смысл в том смысле, что пользователи могли использовать его для указанияв каталоги, содержащие модули WSM-only.Однако, если для PSC было выбрано другое имя переменной , этой проблемы можно было бы избежать - и это действительно решение, рассматриваемое в связанном RFC.


Я хотел бы переместить каталог SQL Server в более подходящее место.Есть ли лучшее место?Я часто запускаю powershell -NoProfile из файловых сценариев .bat

Без без изменения определения реестра $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.cpl, Advanced> Environment Variables...): добавьте выбранный вами каталог к ​​существующему значению.

  • К сожалению, на момент написания статьи это не сработало для PSC, поскольку оно игнорирует определения на основе реестра, как указано.


[1] Кажется, чтоТест на разницу реализован небрежно, и в этом случае значение ad hoc, для которого значение на основе реестра является префиксом , считается идентичным;например, если в реестре определено значение c:\modules, специальное значение c:\modules.core заставляет PowerShell Core думать, что специальное значение не отличается и игнорирует его.
Кроме этого,это избирательное игнорирование значений переменных среды в зависимости от способа их определения крайне неясно.

...