ConvertTo-SecureString - use encrypted password for everyone - powershell

I stored a pw encrypted in a txt file and load it into a powershell session with:
gc .\localadmincred.txt | convertto-securestring
This doesn't work because i read that only the User that encrypted that key, can convert it to a secure string, everyone als can't decrypt the string that is in my txt.
How can I store an encrypted string in a file so that everyone can use it with convertto-securestring?

You can encrypt the string with a key. If another user has the key, he/she will be able to decrypt the string.
See example: Secure Password with PowerShell: Encrypting Credentials – Part 2

Related

Get SecureString as a Plain Text Parameter

I'm trying to get a SecureString as plain text parameter to a command line PowerShell.
I know what is the form of the secure string.
For example, the string "abc" would be a Secure String of "71289371289".
Then, I want to pass "71289371289" as a parameter to the script (Running it from command line), that would be my Secure String and then Decrypt it to a clear text to pass it to another program i'm calling from Powershell.
How would I do something like this?
Update:
I ended up using Credfile with PSCredential to persist the credentials across reboots until the script is complete.
You can convert it back to a clear text password with SecureStringToBSTR:
Param(
$securestring = (Read-Host -AsSecureString)
)
Write-Host "Encrypted Password: $(ConvertFrom-SecureString $securestring)"
$ClearText = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securestring))
Write-Host "Original Password: $ClearText"

Encrypt password for a Powershell script to be used by other customers

I've been searching all around the internet for a really safe solution but still nothing worth. My script expects a connection to O365 but I actually run it on my machine so I can almost store the password in a file and then decrypt it easily with my account. The problem begins when I want to - for example - make a zip with all the files and give it to a customer without the fear to get my password stolen.
The only solution I have found is to use an exact key to encrypt but, how could I "hide" it? I mean, I first encrypt using
[Byte[]] $key = (1..16)
then I go into the script and use:
$File = “path\Password.pwd"
[Byte[]] $key = (1..16)
Get-Content $File | ConvertTo-SecureString -Key $key
but if the key I used to encrypt is written in the script, they should be able also to decrypt and we go back to the main problem. Is there any solution for this problem?
Thanks in advance, hope I won't get downvoted because I really couldn't find anything.
^
Update: I edit my request because I made a few researches and I assumed that the best way to encrypt is using the default Windows Apis. Now my request is if possible to run a script in a server with different users. Maybe the user could make a "run as administrator" that would let him run it and decrypt the password without any problem... I mean the big problem is I need it working on a server for multiple users who are not all administrators. Thanks.

Understanding Powershell SecureStrings

today, I wanted to dig deeply into the concept of SecureString .NET and Powershell, yet I don't think, I am understanding it very well.
If I have a password and convert it to a securestring. Is it saved as I entered it? (Being both encrypted or plain text).
Now if I would pass the password as a part of a PSCredential to a PSSession: what would happen? Does PSSession run ConvertFrom-SecureString on the passed password? But then the password is being encrypted again. How does it know how to pass it to a PSSesion?
I don't fully understand your question but get the jist. This will probably be easier if you think in terms of object types (some explanation). [This link is now dead.]
"If I have a password and convert it to a securestring. Is it saved as
I entered it? (Being both encrypted or plain text)"
Your password will be plain text, and have the type [String]. This is not encrypted.
The SecureString has the type [System.Security.SecureString]. It is encrypted.
This encryption happens in memory whenever you create the SecureString.
It's important to note that a key is required to decrypt the SecureString (more on that below)
Approach 1
This creates an encrypted SecureString variable called $SecurePassword. The unencrypted password does not make it to memory.
$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString
Approach 2
This creates an unencrypted String variable $PlainPassword, then a SecureString variable.
$PlainPassword = Read-Host -Prompt "Enter password"
$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force
"Now if I would pass the password as a part of a PSCredential to a PSSession: what would happen?"
PSSession does not accept unencrypted passwords. To simplify you can either provide a User and be prompted for a password, or pass an object that has the type PSCredential - i.e. it is expecting a secure password.
When you a pass a PSCredential, it is already encrypted with the password as a SecureString.
But the PSSession needs to decrypt it (this part I am not sure on but assume... how else can it varify it?)
To decrypt the SecureString, the key is required. The key is normally generated and as long as both machines have the same security principle, the PSSession can complete the decryption (this part I'm sure of)
This post addresses how to create a key so that a SecureString can be decrypted when there there are different principles.

mapping a networkdrive in PS 2.0 with encoded credentials

I need to map drives and I have an encoded PW which I need to connect to DMZ drives.
I'm using the following code to map the drives:
[Byte[]]$key = (1..16)
$pw = Get-Content .\LocalAdminCred.txt | ConvertTo-SecureString -key $key
# some other stuff
[string]$pwencoded = ConvertFrom-SecureString $pw -Key $key
$Map = New-Object -comobject Wscript.Network
$Map.MapNetworkDrive($_.letter,$_.path,$false,$_.username,$pwencoded)
What your eyes catches first is the $pwencoded Variable - I had to use a string for PW, that's why I needed to decode the Secure.String to a normal string, otherwise i would have had a type mismatch. now the problem is that .MapNetworkDrive needs the password in plain text like 'password' and mine is an encoded key and not a plain text.
To the question: Is it possible to use a encrypted password or even better a secure string to map my network drive this way? I really don't want to use plain text.
First I wanted to do the mapping with New-PSDrive but since the script must work for PS 2.0 I can't use that because the -persist Parameter doesn't exist there.
I don't think this is the answer you're looking for but Dave Wyatt has a few blog posts about using secure strings and credentials.
... I also added an -AsPlainText switch to the ConvertFrom-SecureString command, in case you want to get the plain text back.
The only two ways I know how to map drives are to use plain text credentials. The only other way would be to run the script as an account that has permissions to the network location; that way you don't have to authenticate with a password.

Store Password as Multiple Variables

I've run into a stumbling block for a script I'm writing and I was hoping someone more knowledgeable might be able to help me out.
To put it simply, I want a user to be able to input their password and each letter of that password be assign to variables.
$uCcuGUBIJnoORUWA = "a"
$LjN6WLzWVAaM4BQN = "b"
$5qJ79dPkDGNeIsVy = "c"
… etc.
Once this is done, the password is send to a text file and outputted as the variables. So if your password was "abc" then the text file would appear as …
HASH1 = $uCcuGUBIJnoORUWA
HASH2 = $LjN6WLzWVAaM4BQN
HASH3 = $5qJ79dPkDGNeIsVy
… and so on.
Once the password is completely written and is stored on the text file, the rest of the script uses that information to match each piece of code to figure out what the password is. It then would then type out the password using something like:
[System.Windows.Forms.SendKeys]::SendWait("$uCcuGUBIJnoORUWA$LjN6WLzWVAaM4BQN$5qJ79dPkDGNeIsVy")
Right now my script is using a hard-coded password, which is less than ideal. I'm using PS2EXE to convert the .ps1 file to an .exe file so it's not in plain-text.
I understand how to store the variables and how to get the script to output the variables as the actual letters, I'm just having some trouble figuring out a way for the user to input the password and then have it stored.
How about something better than obfuscation: actual encryption?
Store the credentials in a [PSCredential] object. The password portion of this is stored as a secure string, which is already a good thing.
To export it to a file:
$cred | Export-Clixml -Path C:\master.xml
To re-import it:
$cred = Import-Clixml -Path C:\master.xml
The important thing is that the password will be encrypted when it's written out to disk. It can only be decrypted (and therefore reimported) by the same user on the same computer.
As a result I like to make the user and computer name part of the file name. Here's an example of a script to store the credentials:
$cred = Get-Credential
$cred | Export-Clixml -Path "C:\whatever\master_$env:COMPUTERNAME-$env:USERNAME.xml"
In the script where you actually want to use it:
$cred = Import-Clixml -Path "C:\whatever\master_$env:COMPUTERNAME-$env:USERNAME.xml"
It's quite useful. By embedding the user and computer in the file name you can store multiple copies of the credentials depending on how many users need to access the creds on however many computers.
And since you might need the raw password in your script, the way to get that out of a [PSCredential] object is like so:
$cred.GetNetworkCredential().Password