Pass Stored Creds to bat file - powershell

I am trying to figure out if there is a way to take a stored credential in Windows Cred vault and pass it to a bat file that needs the credentials. I found a very old bat file that has a username and password in clear text. These are used to authenticate against a portal and have to be read by the bat in clear text. I have stored credentials on my server that I want to use so I can close this security gap but I am not 100% sure how to pass the password because it has to be in clear text. Here is what I have:
$creds = Get-StoredCredential -Target "Username"
$password = $creds.Password
$username = $creds.UserName
Start-Process cmd.exe "/c C:\trigger.bat `"argument1`" $username $password `"Argument2`" Argument3" -NoNewWindow -Verbose
When I enter the password in clear text in my line it works. If I use $password it throws an auth error. I assume that this is because the $password is a stored PSObject and isn't getting passed to cmd "correctly". Is there a way around this?
PS: Get-StoredCredential is from the CredentialManager module.

If $creds contains a PSCredential object, then you should be able to replace this:
$password = $creds.Password
with this:
$password = $creds.GetNetworkCredential().Password

Get-StoredCredential, when called without -AsCredentialObject, yields PSCredential instances.
The PSCredential.Password property you are accessing is not a String but a SecureString, so you cannot retrieve the plain text password like you are attempting.
Based on Convert a secure string to plain text you can use the PSCredential to get a NetworkCredential and then use its Password property...
$password = $creds.GetNetworkCredential().Password
In any case, when you get an authentication error using $username and $password you should ensure those variables contain the values you expect them to.

Related

Is there a way to use ConvertFrom-SecureString and ConvertTo-SecureString with any user?

I'm using the following to create the password file:
$path = "C:\Users\USER\Desktop"
$passwd = Read-Host "enter desired password" -AsSecureString
$encpwd = ConvertFrom-SecureString $passwd
$encpwd > $path\filename.bin
Then calling the file with:
# define path to store password and input password
$path = "C:\Users\USER\Desktop"
# get the encrypted password from the path
$encpwd = Get-Content $path\filename.bin
# convert file to secure string
$passwd = ConvertTo-SecureString $encpwd
# define needed credential
$cred = new-object System.Management.Automation.PSCredential 'WIN-SERVER\AdminForQB',$passwd
# go to DVD drive launch setup.exe as user with privileges to launch the program with no user input required
Set-Location "C:\Program Files (x86)\Intuit\QuickBooks 2017\"
Start-Process PowerShell -windowstyle hidden -Cred $cred -ArgumentList .\QBW32PremierAccountant.exe
My goal is be able to run QB2017 with admin privs without giving the user admin privs. The issue I am having is that I have to generate the password file on each user or I get the following error if a user trys to use one generated from another user:
Key not valid for use in specified state.
Is there a way to use this method without generating a key per user?
When you use ConvertTo-SecureString and ConvertFrom-SecureString without a Key or SecureKey, Powershell will use Windows Data Protection API (DPAPI) to encrypt/decrypt your strings. This means that it will only work for the same user on the same computer.
When you use a Key/SecureKey, the Advanced Encryption Standard (AES) encryption algorithm is used. You are able to use the stored credential from any machine with any user so long as you know the AES Key that was used.
More info on this topic (with example code)
Note: This is only Security through obscurity, which isn't good practice. If you store the Key on the same computer as the encrypted password, it's not much more secure than plain text passwords!
PowerShell is the wrong solution for this.
To fix this you should give them read/write access to the folders and registry key QB2017 needs access to. If you still have issues, create a Shim using Microsoft's Application Compatibly Toolkit.
https://deployhappiness.com/fixing-applications-that-require-administrator-rights/

Prevent PowerShell script from being read

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:
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?
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.
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.

Powershell Automation - Passing Password after executing a exe file

I working on automating the specific task using powershell and getting error while passing the password. Below is my task. Below are the tasks I need to automate.
Execute exe file (For ex: export.exe)
It will prompt for password twice (Enter your password and Reenter your password)
After Entering our password Twice, It will ask for confirmarion Yes or No: (I need to give 'Yes' or No to continue )
I tried automating the above first two steps. First I get the stored password in a file using the below command
$password = get-content C:\cred.txt | convertto-securestring
Then I tried executing the below commands in script
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $pass
Invoke-Expression "& `"C:\Program Files\XX\XX\bin\export.exe`""
But I dont know how to use the password from the file twice to continue the script. I am new to powershell. Please help me.
I don't think that your application will accept PowerShell's PSCredential object. More likely, you just have to pass plaintext password twice and then Yes.
Try this (assuming that export.exe is console application):
'Password', 'Password', 'Yes' | & 'C:\Program Files\XX\XX\bin\export.exe'
This will send 3 strings, separated by the newline (Enter) to the export.exe's stdin.

SSRS Power shell command syntax for credential?

Does anyone know what is the syntax to insert a service account credential (to replace the useDefaultCredential) in this PS command line:
$ssrsProxy = New-WebServiceProxy -Uri $webServiceUrl'/ReportService2005.asmx?WSDL' -UseDefaultCredential
You would want to use the -Credential parameter and then use something like below as the variable being passed to it.
$(get-credential -UserName "Domain\Svc-User" -Message "Please enter password for Domain\Svc-User Account")
Or there is a way to convert a password to a secure string shown on the help page here where you simply have the user name and password saved in plain text variables which is less secure.
Get-Credential

How can I use powershell's read-host function to accept a password for an external service?

I have a script I'm writing that makes a connection to a SOAP service. After the connection is made, I need to pass in a the username/pass with every command I send. The problem I have is that when I use read-host to do this, my password is shown in cleartext and remains in the shell:
PS C:\Users\Egr> Read-Host "Enter Pass"
Enter Pass: MyPassword
MyPassword
If I hide it with -AsSecureString, the value can no longer be passed to the service because it is now a System.Security.SecureString object:
PS C:\Users\gross> Read-Host "Enter Pass" -AsSecureString
Enter Pass: **********
System.Security.SecureString
When I pass this, it does not work. I don't care about the passwords being passed to the service in cleartext, I just don't want them sticking around on a user's shell after they enter their password. Is it possible to hide the Read-Host input, but still have the password stored as cleartext? If not, is there a way I can pass the System.Security.SecureString object as cleartext?
Thanks
$Password is a Securestring, and this will return the plain text password.
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password))
You can save the password(input) as a variable and pass it to your service. If the code is run in a script or as a function, the variable containing the password will be deleted after it's done(they are stored in a temp. local scope). If you run the commands in the console(or dot-source the script like . .\myscript.ps1), the password variable will stay in the session scope, and they will be stored until you delete it or close the session. If you want to be sure the variable is removed after your script is run, you can delete it yourself. Like this:
#Get password in cleartext and store in $password variable
$password = Read-Host "Enter Pass"
#run code that needs password stored in $password
#Delete password
Remove-Variable password
To read more about how variables are stored in scopes, check out about_Scopes
There is a way to do this in PowerShell versions 6.x+:
$password = read-host -maskinput "Enter password"
, thanks to jborean93 for pointing this out to me.