使用Powershell的-encodedcommand参数传递参数

4

我正在尝试寻找一种优雅的方法来传递参数给 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 -encodedcommand LQB1AG4AIAB0AGUAcwB0AHUAcwBlAHIAIAAtAHAAdwAgAHQAZQBzAHQAcAB3AA== -file Base64ParamTest.ps1

这运行了脚本,但参数没有值。

这的确是我所期望的行为,但不是我希望的。有没有一种方法可以将我的参数本身作为安全编码的字符串进行传递?


我的备选方案是仅对密码值本身进行Base64编码,而不是对整个参数字符串进行编码,然后在脚本中解码。这很简单,但我想知道是否有更简单的自动化方法。 - Eric
1个回答

5

您需要将脚本调用作为命令的一部分包含在其中,例如:

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

以下是我之前记录的有关脚本中处理密码的注意事项:

1.避免明文密码

永远不要在脚本中使用明文密码。您可以将密码存储在受保护的文件中,并在需要时读取该文件。

2.加密密码

如果必须在脚本中使用密码,那么请确保将其加密。可以使用加密算法如MD5、SHA等进行加密。

3.使用环境变量

您可以使用环境变量来存储密码,这样它们就不会出现在脚本中。但是,请注意,环境变量也应该受到保护。

4.限制访问权限

确保只有授权的用户才能访问包含密码的文件或环境变量。

###########################################################
#
# 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.

啊,将脚本包含在编码字符串中。简单的解决方案,但我没有在任何地方看到过类似的例子。非常感谢! - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接