0

I have the below PowerShell script (myscript.ps1) in which I ask for username and password. Depending on the username and password it copies a file to a certain destination.

$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"; }

Requirement: I want to make this file protected so no one can edit it and see the username and password.

PS2EXE

I found a solution found here which converts the PowerShell script to an .exe file. When I originally run the script using PowerShell a dialog box appears allowing me to enter the username and password:

Get-Credential dialog box

After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"

PS2EXE console

I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?

9
  • You can't protect the script. But you can keep the uname and password in an encrypted file and read them in at runtime. Commented Oct 24, 2016 at 0:56
  • @RyanBemrose could you send me a reference how this can be done please? Commented Oct 24, 2016 at 1:07
  • That doesn't sound secure, the script would then need the encryption key hardcoded, which is just as bad as having the password. Why not just apply an ACL to the script file? Commented Oct 24, 2016 at 1:10
  • This article shows how to store encrypted passwords in the Windows Credential manager or in a Secure String. You can websearch for "powershell secure password" for other tutorials on storing passwords in an encrypted file. Commented Oct 24, 2016 at 1:14
  • @Burt_Harris Is there an ACL you can apply that allows executing the file but not reading it? Commented Oct 24, 2016 at 1:15

2 Answers 2

3

Q: Why does the EXE prompt with "Credential"?

This isn't an answer to the real question, and is based on guessing/supposition about PS2EXE, but I hope it is useful to clear up some confusion.

Having looked briefly at the PS2EXE page linked above, it seems that this utility encodes the script in Base64 and bundles it with a lightweight (?) custom PowerShell host. When run, I suppose the EXE starts the host, decodes the script and runs it.

The problem is that the Get-Credential cmdlet is running within a PS host that probably can't interact with the desktop. That is, it can't put up the GUI prompt for credentials. It therefore needs to prompt for the Credential property on the command line, explaining why you see that behaviour.

Workaround with Read-Host?

Instead of trying to use Get-Credential to prompt for username and password, you could embrace what PS2EXE seems to be doing and just use 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") 
{ ... }

Using -AsSecureString will hide the password on the screen. The $Password variable will be of type System.Security.SecureString, which can be used to create a PSCredential object as shown.

You'd need to test this, but it seems that you're able to read from the shell but not from a GUI prompt.

And just to be clear: none of this is anywhere near best-practice security. If you need authentication/authorization for these activities, step back and look at the problem again.

Workaround with two scripts?

It seems that PS2EXE doesn't support -AsSecureString in the same way that normal PowerShell does, i.e. it doesn't hide the characters. A possible workaround for this would be to collect the username and password from the user in one script and then pass them to a PS2EXE-converted script for processing.

Launch-MyScript.ps1:

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

MyScript.exe (coverted with PS2EXE):

param($Username,$Password)

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

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

The user runs Launch-MyScript.ps1 and completes the password prompt. Then the EXE is run automatically with the username and password passed in as arguments. Note that, as shown above, the password is a Secure String. Test this; I'm not using PS2EXE so it's a theoretical solution at the moment.

If you can't pass $Password along the pipeline as a Secure String object, you can convert it to text with ConvertFrom-SecureString in the first script, then conver it back with ConvertTo-SecureString in the second one.

Sign up to request clarification or add additional context in comments.

9 Comments

thanks for the explanation. So what shall I do then when the Credential property appears on the command line?
If command-line prompts are acceptable, then you could prompt for username and password individually using Read-Host and drop any pretence at using a PSCredential object at all.
could you show me how please? as I'm not familiar with this. Also there is no way to convert it to .exe and has the Get-Credential form appearing?
Have updated by answer. It does seem to me that we're heading off down the wrong track to solve what you are ultimately trying to do.
Thank you very much. I've done this but now I'm trying to mask the password but it doesn't work using $Password = Read-Host -assecurestring "Enter password" any thoughts?
|
0

According to this article http://windowsitpro.com/powershell/protect-your-powershell-scripts you should first set ur execution policy to AllSigned by Set-ExecutionPolicy AllSigned, then create a certificate using makecert cmdlet.

Then u can sign single script using Set-AuthenticodeSignature cmdlet or use .pfx File to Sign a Script which appears even safer.

Hope it helps a bit.

1 Comment

I think the ask is about hiding the script contents. Signing a script controls the execution of the script, not whether someone can read the file contents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.