PowerShell с надписью SecureString преобразуется в строку - PullRequest
0 голосов
/ 26 сентября 2018
param
(
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$True)]
    [securestring]
    $securityKey
)

powershell.exe -File $PSCommandPath -thisAppDomain @PSBoundParameters

Этот код выдает следующую ошибку:

Невозможно обработать преобразование аргумента для параметра 'securityKey'.Невозможно преобразовать значение "System.Security.SecureString" типа "System.String" в тип "System.Security.SecureString"

Если я проверяю тип securityKey, это SecureStringдо того, как его обрызгали.Я предполагаю его сериализацию по какой-то причине.Как мне предотвратить это?

Редактировать

Этот вариант использования может выглядеть странно, поэтому я приведу некоторый контекст.Мне нужно убедиться, что при загрузке в этот скрипт загружается определенная версия сборки.Я использую параметр thisAppDomain для перезапуска в новом домене приложения, чтобы попытаться выполнить это.Более крупный пример:

.\FirstScript.ps1 | .\SecondScript.ps1

Защищенная строка вводится, как ожидается, но преобразуется в строку при перезапуске.Вот как я перезапускаю:

if(-not $thisAppDomain)
{
    Write-Host "Invoking script in a new app domain"
    powershell.exe -File $PSCommandPath -thisAppDomain @PSBoundParameters
    return;
}

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Если вы вызываете интерфейс командной строки PowerShell с -File, все аргументы неизменно преобразуются в строки , поэтому ваша безопасная строка не будет работать (она преобразуется в обычную строку с литерал содержимое System.Security.SecureString).

Чтобы (в основном) сохранить типы аргументов, вы должны передать блок сценария , который вызываетPowerShell для автоматической сериализации и десериализации аргументов с сохранением типов [1] , который правильно сохраняет [securestring] экземпляров, но учтите, что этот метод работает только при вызове из PowerShell (тоже):

if (-not $thisAppDomain)
{
  Write-Host "Invoking script in a new app domain"
  powershell -Command { 
      $script, $splat = $Args # parse the args array into distinct variables
      . $script -thisAppDomain @splat # call the script with splatting
    } -args $PSCommandPath, $PSBoundParameters
  return
}

Обратите внимание, как значения из контекста вызывающей стороны, на которые нужно сослаться в блоке сценария, который будет выполняться в сеансе new , должны передаваться какаргументы , через -args <arg-array> - см. Get-Help about_powershell.exe или запустите powershell -? для получения более краткой справки.

Примечание : As Патрик Майнеке указывает на вышеприведенный подход, в котором используется преобразованныйСтрока ommand с зашифрованной строкой в ​​кодировке Base64 может гипотетически потерпеть неудачу из-за превышения макс.длина командной строки, которая составляет 32 768 символов в Windows 10 (см. CreateProcess функция WinAPI ).
При этом, если вы не передадите исключительно большие блоки скриптов и / или сотни аргументов, вы 'маловероятно, что он достигнет этого предела.


[1] Такой же тип сериализации также используется, например, в удаленном взаимодействии PowerShell и в фоновых заданиях.Обратите внимание, что не только фиксированный набор типов может быть точно десериализован, но PowerShell делает все возможное, чтобы эмулировать других типов с пользовательскими объектами , которые имеют те же свойства.

0 голосов
/ 27 сентября 2018

Рассеянные аргументы в исполняемом файле (даже powershell.exe) просто преобразуются в строку.Вы можете увидеть, как это закончится, запустив это:

$splat = @{ Test = 'something'; Secret = [securestring]::new() }
cmd.exe /c echo @splat
# returns
# -Test:something -Secret:System.Security.SecureString

Вы можете запустить что-то в другом процессе, используя SecureString, используя Start-Job

$mySecureString = Read-Host -AsSecureString
$job = Start-Job {
    & $using:PSCommandPath -thisAppDomain $using:mySecureString
}

$job | Receive-Job -Wait

Примечание:область using должна использоваться для переменных из родительского сеанса.Кроме того, переменные по-прежнему будут сериализованы, поскольку процессы не разделяют память, но безопасная строка будет сериализована правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...