2011-06-09 13 views
3

私は、PowerShellスクリプトにパラメータを渡すエレガントな方法を見つけようとしています。この場合、文字列にはエスケープする必要がある任意の数の特殊文字を含めることができます。たとえば、特殊文字を含む複雑なパスワードです。Powershell -encodedコマンドを使用してパラメータを渡す

私は-encodedcommandオプションを見ていましたが、これはエンコードされたバージョンのパラメータではなく、エンコードされたスクリプトブロックを渡すためだけのようです。例えば

、次のスクリプトを考えてみます。

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

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

にstring 'を-un testuserを-pw testpw' は次のようにbase64エンコードです: LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AAの==

私は、スクリプトを呼び出してみました.ps1ファイルを読み込んで上記の文字列で-encodedcommandを渡してもエラーが発生しました 'パラメータ名に一致するパラメータが見つかりません' encodedcommand '

これはb直接powershell.exeを呼び出します。

はまた、次のことを試してみました: たpowershell.exe -encodedcommand LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AA == -file Base64ParamTest.ps1

これは、スクリプトを実行したが、パラメータは値がありませんでした。

これは私が期待していたとおりに動作していますが、希望通りには動作しません。実際に自分自身のパラメータを安全にエンコードされた文字列として渡す方法はありますか?

+0

私の計画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

関連する問題