Использование Powershell -encodedcommand для передачи параметров - PullRequest
3 голосов
/ 09 июня 2011

Я пытаюсь найти элегантный способ передачи параметров в скрипт powershell, где строка может содержать любое количество специальных символов, которые необходимо экранировать. Например, сложный пароль со специальными символами.

Я смотрел на параметр -encodedcommand, но похоже, что он предназначен только для передачи закодированного блока сценария, а не кодированной версии параметров.

Например, рассмотрим следующий скрипт:

param(
[Parameter()][Alias("un")][string]$Username,
[Parameter()][Alias("pw")][string]$Password
)

Write-Host "Username: $Username"
Write-Host "Password: $Password"

Строка '-un testuser -pw testpw' в кодировке base64 выглядит следующим образом: LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AA ==

Я попытался вызвать скрипт как файл .ps1 и передать -encodedcommand с указанной выше строкой, но получил ошибку «Не удалось найти параметр, соответствующий имени параметра« encodedcommand »

Итак, это должен быть вызов напрямую powershell.exe.

Также попробовал следующее: powershell.exe - кодированная команда LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AA == - файл Base64ParamTest.ps1

Это запустило скрипт, но параметры не имели значения.

Это ведет себя так, как я ожидал, но не так, как я хотел бы надеяться. Есть ли способ фактически передать мои параметры как безопасно закодированные строки?

1 Ответ

4 голосов
/ 09 июня 2011

Вы должны включить вызов сценария как часть команды, например:

PS> $command = "& '$pwd\login.ps1' -un testuser -pw testpw"
PS> $bytes = [Text.Encoding]::Unicode.GetBytes($command)
PS> $encodedCommand = [Convert]::ToBase64String($bytes)
PS> powershell.exe -noprofile -encodedCommand $encodedCommand
Username: testuser
Password: testpw

Вот некоторые заметки, которые я делал в прошлом о том, как обращаться с паролями в сценариях:

###########################################################
#
# Stashing passwords to avoid interactive password prompting
#

# NOT RECOMMENDED BUT IF PASSWORD IS DYNAMIC OR WIDELY KNOWN

$passwd = ConvertTo-SecureString "Not Very Secret Password" -AsPlainText -Force

# Need a way to prompt for password and use clear text password for use with net use
$cred = Get-Credential
$cred.GetNetworkCredential().UserName 
$cred.GetNetworkCredential().Password

#
# SAFE BUT NOT NECESSARILY PORTABLE APPROACH 
# Depends on how DPAPI works with roaming profiles
#

# Capture once and store to file
$passwd = Read-Host "Enter password" -AsSecureString
$encpwd = ConvertFrom-SecureString $passwd
$encpwd
$encpwd > $path\password.bin

# Later pull this in and restore to a secure string
$encpwd = Get-Content $path\password.bin
$passwd = ConvertTo-SecureString $encpwd

# Let's see if the rehydrate worked?
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($passwd)
$str =  [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
$str

$cred = new-object System.Management.Automation.PSCredential 'john',$passwd
$cred

# NOTE: The "secret" required to rehyrdate correctly is stored in DPAPI - consequence:
#       You can only rehydrate on the same machine that did the ConvertFrom-SecureString


#
# PORTABLE BUT NOT NECESSARILY SAFE APPROACH
#

# Let's do this so that it will work on multiple machines:

$key = 1..32 | ForEach-Object { Get-Random -Maximum 256 }
$passwd = Read-Host "Enter password" -AsSecureString
$encpwd = ConvertFrom-SecureString $passwd -Key $key
$encpwd
# Could easily modify this to store username also
$record = new-object psobject -Property @{Key = $key; EncryptedPassword = $encpwd}
$record
$record | Export-Clixml $path\portablePassword.bin

# Later pull this in and restore to a secure string
$record = Import-Clixml $path\portablePassword.bin
$passwd = ConvertTo-SecureString $record.EncryptedPassword -Key $record.Key

# Let's see if the rehydrate worked?
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($passwd)
$str =  [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
$str

$cred = new-object System.Management.Automation.PSCredential 'john',$passwd
$cred

Start-Process powershell.exe -Credential $cred -NoNewWindow

# Portable is better BUT the secret (Key) is shared (stored with the password file)
# Can be reversed to original password - still much better than clear-text password
# stored in your script.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...