Экранирование всех специальных символов пароля в Powershell для переменной - PullRequest
1 голос
/ 18 марта 2020

У меня есть следующий сценарий, работающий на Powershell v5:

Сценарий Powershell извлекает несколько битов информации из вызова API в стороннюю систему в массе для каждого l oop и назначает их Переменные. Среди извлекаемой информации - пароли (это делается для того, чтобы избавиться от упомянутой сторонней системы и перенести ее на что-то, что не позволяет вам получать пароли в виде простого текста):

$userset = Invoke-WebRequest -Method Post -Uri "https://$Url/path/to/api.asmx" -Headers $Headers -Body $usercall

$xmluserset = [xml] $userset.Content

$userset2 = $xmluserset.Envelope.Body.UserSettingsResult.settingValues.string

$userpasstemp = $userset2[1].trimstart("password")
$userpass = $userpasstemp.trimstart("=")

Эти пароли затем используются в других местах скрипта.

Например, они передаются другому API и должны быть в формате, совместимом с URL, поэтому я запускаю это:

$urlescapeduserpass = [uri]::EscapeDataString($userpass)

который работает для этого раздела скрипта

Проблема заключается в том, что эти пароли могут содержать любые специальные символы:! "# $% & '() * +, -. / :; <=>? @ [] ^ _ `{|} ~

И когда я вызываю другую часть сценария, специальные символы в строке пароля вызывают сбой и сценарий завершается. Это происходит при использовании любой из команд вызова:

& .\application.exe --option1 $option1 --user1 $user --password1 $userpass

или при использовании выражения invoke

$command = "$path\application.exe  --option1 $option1 --user1 $user --password1  $userpass"
Invoke-Expression $command

Я пытался использовать Regex, используя командлет -replace:

$escapedpass = $userpass -replace ' !"#$%&()*+,-./:;<=>?@[\]^_`{|}~', '`$&'

Но не повезло, Я знаю что-то похожее на [uri] escapedatastring, есть подобное для Regex, но, кажется, нет единственного родного для Powershell. Я уверен, что есть либо [contenttype], у которого будет встроенная функция для экранирования специальных символов, либо какой-то способ достижения конечного результата.

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Поскольку Обработка PowerShell встроенных " символов в аргументе, передаваемом внешним программам не работает (по состоянию на PowerShell 7) - см. этот ответ - вам нужно вручную \ -escape " символов , встроенных в вашу строку:

$escapedpass = $userpass -replace , '"', '\"'

В контексте вашей команды:

& .\application.exe --option1 $option1 --user1 $user --password1 ($userpass -replace , '"', '\"')
0 голосов
/ 18 марта 2020

Давайте создадим минимальный воспроизводимый пример с прохождением туда и обратно на основе ответа Как экранировать специальные символы в PowerShell? из @ mklement0 для этого:
(также примите во внимание комментарий, который я только что сделал на пробелах)

К сожалению, PowerShell создает дополнительный гандикап, так как он требует одиночной кавычки строки, иначе он будет интерпретировать другие символы вместе со знаком доллара ($). Я разместил комментарии в коде, где вы можете оставить это.

Password.ps1

Param (
    [String]$Password
)
Write-Host $Password

Проверка пароля:

$Input = @'
 !"'#$%&()*+,-./:;<=>?@[\]^_`{|}~
'@

Write-Host 'Input:' $Input
$Escape = $Input.Replace('"', '\"')
$Escape = $Escape.Replace("'", "''") # Only required for PowerShell
Write-Host 'Command:' PowerShell .\Password.ps1 "'$Escape'"
# Omit the inner single quotes if it doesn't concern PowerShell
# But note that your .\application.exe might have its own syntax
# to support spaces and special characters from the command line,
# like double quotes: """$Escape"""
$Output = & PowerShell .\Password.ps1 "'$Escape'"
Write-Host 'Output:' $Output
Write-Host 'Input and output are equal?' ($Input -eq $Output)

Результаты:

Input:  !"'#$%&()*+,-./:;<=>?@[\]^_`{|}~
Command: PowerShell .\Password.ps1 "' !\"''#$%&()*+,-./:;<=>?@[\]^_`{|}~'"
Output:  !"'#$%&()*+,-./:;<=>?@[\]^_`{|}~
Input and output are equal? True
...