2011-06-09 2 views
3

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

Я смотрел опцию -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 »

Итак, это хорошо, для прямого вызова powershell.exe.

попытался также следующее: powershell.exe -encodedcommand LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AA == -file Base64ParamTest.ps1

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

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

+0

My Plan B здесь просто Base64 кодирует значение пароля сам по себе, а не всю строку параметров, а затем декодирует это в скрипте. Достаточно просто, но мне было интересно, не хватает ли мне более простого способа сделать это автоматически. – Eric

ответ

4

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

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. 
+0

Ах, включая скрипт в закодированной строке. Простое решение, но я не видел никаких примеров этого нигде. Большое спасибо! – Eric

Смежные вопросы