Reputation: 3616
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.
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:
After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"
I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?
Upvotes: 0
Views: 4129
Reputation: 4659
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.
Upvotes: 3
Reputation: 1
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.
Upvotes: 0