#powershell
#powershell
Вопрос:
Существует сценарий с именем Get-Stuff.ps1
, который возглавляет его с PSScriptInfo
помощью блока. Сценарий публикуется в репозитории NuGet. Затем он устанавливается в ожидаемое местоположение, C:UserslitDocumentsWindowsPowerShellScriptsGet-Stuff.ps1
. Get-InstalledScript
сообщает, что он установлен. Однако он не является исполняемым файлом. C:UserslitDocumentsWindowsPowerShellScripts
Каталог отсутствует $Env:PSModulePath
.
Какой шаг я пропустил, чтобы сделать эту команду исполняемой после установки?
PS C:> (Get-ChildItem -Recurse -File -Path 'C:' -Filter 'Get-Stuff*' -ErrorAction SilentlyContinue).FullName
C:srcModulesscriptsGet-Stuff.ps1
PS C:> Test-ScriptFileInfo -Path 'C:srcModulesscriptsGet-Stuff.ps1'
Version Name Author Description
------- ---- ------ -----------
1.0.0.1 Get-Stuff lit Get-Stuff produces .csv files of record counts from tables.
PS C:> Publish-Script -Path 'C:srcModulesscriptsGet-Stuff.ps1' -NuGetApiKey 'yanon' -Repository 'yrepo'
PS C:> Find-Script -Name Get-Stuff
Version Name Repository Description
------- ---- ---------- -----------
1.0.0.1 Get-Stuff yrepo Get-Stuff produces .csv files of record counts from tables.
PS C:> Find-Script -Name Get-Stuff | Install-Script
PS C:> (Get-ChildItem -Recurse -File -Path 'C:' -Filter 'Get-Stuff*' -ErrorAction SilentlyContinue).FullName
C:srcModulesscriptsGet-Stuff.ps1
C:UserslitDocumentsWindowsPowerShellScriptsGet-Stuff.ps1
C:UserslitDocumentsWindowsPowerShellScriptsInstalledScriptInfosGet-Stuff_InstalledScriptInfo.xml
PS C:> Get-InstalledScript -Name Get-Stuff
Version Name Repository Description
------- ---- ---------- -----------
1.0.0.1 Get-Stuff yrepo Get-Stuff produces .csv files of record counts from tables.
PS C:> Get-Command Get-Stuff
Get-Command : The term 'Get-Stuff' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
Get-Command Get-Stuff
~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ObjectNotFound: (Get-Stuff:String) [Get-Command], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
PS C:> $PSVersionTable.PSVersion.ToString()
5.1.17763.1490
Ответ №1:
Это имеет $env:PATH
значение в отношении вызовов *.ps1
файлов (файлов сценариев) только по имени файла, а не $env:PSModulePath
, который применяется только к модулям.
К сожалению, более ранние версии PowerShellGet
модуля не предлагали постоянно добавлять каталоги, на которые нацелен Install-Script
командлет $env:PATH
, но, по крайней мере, начиная с версии 2.2.4, они это делают (отображается приглашение) при следующем вызове Install-Script
для выполнения фактической установки.
Попробуйте обновить свою PowerShellGet
версию с помощью либо Update-Module PowerShellGet
или, если это не удается Install-Module -Force PowerShellGet
(что в Windows PowerShell требует прав доступа, если вы не укажете -Scope CurrentUser
).
Если вы хотите внести эти $env:PATH
дополнения самостоятельно, выполните следующий код:
Примечание:
$env:PATH
Постоянное изменение через реестр поддерживается только в Windows (в Unix механизмы определения постоянных переменных среды различаются на разных платформах).- Однако в Unix также
$env:PATH
обновляется переменная в сеансе.
amp; {
Write-Verbose -vb "Adding Install-Script install directories to `$env:PATH..."
$isWin = $env:OS -eq 'Windows_NT'
$isAdmin = if ($isWin) { [bool] (net session 2>$null) } else { 0 -eq (id -u) }
$ErrorActionPreference = 'Stop'
# Determine the locations: current-user, all-user.
$scriptDirs = (Join-Path (Split-Path ($PROFILE, "$HOME/.local/share/powershell/Modules")[$env:OS -ne 'Windows_NT']) Scripts),
(Join-Path (Split-Path ("$env:ProgramFiles$(if ($PSVersionTable.PSEdition -ne 'Core') { 'Windows' })PowerShellModules", '/usr/local/share/powershell/Modules')[$env:OS -ne 'Windows_NT']) Scripts)
if (-not $isWin) {
# Note: There's no unified mechanism across macOS and Linux.
Write-Warning "On Unix, this script only supports modifying the *current session*'s `$env:PATH variable."
} elseif (-not $isAdmin) {
Write-Warning "Since this session isn't elevated, only the *current-user* location will be added *persistently*."
}
$pathVarSep = [IO.Path]::PathSeparator
$i = 0
foreach ($dir in $scriptDirs) {
# Always update the in-session variable.
Write-Verbose -vb "-- Adding $dir..."
if ($env:PATH -split $pathVarSep -notcontains $dir) {
$env:PATH = ($env:PATH -replace "$pathVarSep`$") $pathVarSep $dir
}
else {
Write-Verbose -vb "Already present in-session: $dir"
}
# On Windows, also try to update the *persistent* definitions
if ($isWin) {
$scope = ('User', 'Machine')[$i -eq 1]
if ($scope -eq 'Machine' -and -not $isAdmin) { break } # skip due to lack of permissions
# Note: We query the registry directly, so as to preserve unexpanded REG_EXPAND_SZ values.
$currVal = Get-ItemPropertyValue ('registry::HKEY_CURRENT_USEREnvironment', 'registry::HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerEnvironment')[$scope -eq 'Machine'] Path
if ($currVal -split $pathVarSep -notcontains $dir) {
[Environment]::SetEnvironmentVariable('Path', (($currVal -replace "$pathVarSep`$") $pathVarSep $dir), $scope)
} else {
Write-Verbose -vb "Already present persistently in the $scope scope: $dir"
}
}
}
Write-Verbose -vb 'Done.'
}
Комментарии:
1. @lit, я бы ожидал, что при следующем запуске появится приглашение
Install-Script
(для выполнения фактической установки). Однако, пожалуйста, ознакомьтесь с Моим Обновлением для кода, который вносит эти$env:PATH
дополнения по требованию.2. спасибо за этот ответ. Это работает. Для себя я вручную добавил два (2) каталога сценариев. В корпоративном офисе это не так просто. Я хочу сказать, что группа ИТ-специалистов должна развернуть что-то, чтобы это произошло, но это кажется маловероятным. Есть предложения?
3. @lit, у группы рабочего стола нет способа развернуть обновления переменных среды или развернуть сценарий PowerShell для одноразового запуска при входе пользователя в систему?
4. Да, у них много инструментов. Трудность, вероятно, будет заключаться в том, чтобы заставить руководство группы настаивать на том, чтобы это произошло.