防止读取PowerShell脚本

时间:2016-10-24 00:42:04

标签: powershell

我有以下PowerShell脚本( myscript.ps1 ),其中我要求输入用户名和密码。根据用户名和密码,它会将文件复制到某个目的地。

$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1") 
{ Copy-Item "test1.pdf" "\test\test1.pdf"; } 
else 
{ Copy-Item "test2.pdf" "\test\test2.pdf"; }

要求:我想保护此文件,以便没有人可以编辑它并查看用户名和密码。

PS2EXE

我找到了一个找到here的解决方案,它将PowerShell脚本转换为.exe文件。当我最初使用PowerShell运行脚本时,会出现一个对话框,允许我输入用户名和密码:

Get-Credential dialog box

生成.exe后,当我运行它时,将不再显示凭据对话框。相反,控制台显示“Credential:”

PS2EXE console

我不知道为什么?我希望在运行exe时仍然显示凭据表单。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

问:为什么EXE提示“Credential”?

这不是真正问题的答案,而是基于对PS2EXE的猜测/假设,但我希望澄清一些混淆是有用的。

简要介绍了上面链接的PS2EXE页面,似乎该实用程序在Base64中对脚本进行编码,并将其与轻量级(?)自定义PowerShell主机捆绑在一起。运行时,我想EXE启动主机,解码脚本并运行它。

问题是Get-Credential cmdlet在PS主机中运行,可能无法与桌面交互。也就是说,它无法提供凭据的GUI提示。因此,它需要在命令行上提示 Credential 属性,解释您看到该行为的原因。

使用Read-Host进行解决方法?

您可以接受PS2EXE似乎正在做的事情而不是尝试使用Get-Credential来提示用户名和密码,而只是使用Read-Host

$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString

$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password

if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1") 
{ ... }

使用-AsSecureString将隐藏屏幕上的密码。 $ Password 变量的类型为System.Security.SecureString,可用于创建 PSCredential 对象,如图所示。

您需要对此进行测试,但似乎您可以从shell中读取,但不能从GUI提示中读取。

而且要明确一点:这一切都不是最佳实践安全性。如果您需要对这些活动进行身份验证/授权,请退后一步,再次查看问题。

使用两个脚本解决方法?

PS2EXE似乎不像普通PowerShell那样支持-AsSecureString,即它不会隐藏字符。可能的解决方法是在一个脚本中从用户收集用户名和密码,然后将它们传递给PS2EXE转换后的脚本进行处理。

启动-MyScript.ps1:

$Credentials = Get-Credential
& MyScript.exe $Credentials.Username $Credentials.Password

MyScript.exe (与PS2EXE一起转换):

param($Username,$Password)

$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password

if ($Credentials.Username -eq "user1" -and
  $Credentials.GetNetworkCredential().password -eq "pass1")
{
  ...
}

用户运行 Launch-MyScript.ps1 并完成密码提示。然后EXE自动运行,用户名和密码作为参数传入。请注意,如上所示,密码是安全字符串。测试一下;我没有使用PS2EXE,所以它是目前的理论解决方案。

如果您无法将管道中的 $ Password 作为安全字符串对象传递,则可以在第一个脚本中将其转换为ConvertFrom-SecureString的文本,然后将其转换回{ {1}}在第二个。

答案 1 :(得分:0)

根据本文http://windowsitpro.com/powershell/protect-your-powershell-scripts,您应首先将执行策略设置为Set-ExecutionPolicy AllSigned的AllSigned,然后使用makecert cmdlet创建证书。

然后,您可以使用Set-AuthenticodeSignature cmdlet签署单个脚本,或使用.pfx文件签署一个看起来更安全的脚本。

希望它有所帮助。