encrypt username in PowerShell - powershell

Need to encrypt username and password in PowerShell I've encrypted password using the below code.
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString |
Set-Content E:\powershell\encrypted_password1.txt
But when I tried to encrypt username with the same code
$credential.username | ConvertFrom-SecureString |
Set-Content E:\powershell\encrypted_user1.txt
Encountered with below error:
ConvertFrom-SecureString : The input object cannot be bound to any parameters
for the command either because the command does not take pipeline input or the
input and its properties do not match any of the parameters that take pipeline
input.
Is there any way to encrypt username?

Exporting:
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content E:\powershell\encrypted_password1.txt
$credential.Username | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Set-Content E:\powershell\encrypted_user1.txt
Importing:
$Username = Get-Content E:\powershell\encrypted_user1.txt | ConvertTo-SecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Username)
$Username = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$Password = Get-Content E:\powershell\encrypted_password1.txt | ConvertTo-SecureString
$Credential = New-Object -TypeName PSCredential -ArgumentList $Username, $Password

Related

ConvertTo-SecureString run without key on different user account, is there a way (with proper credentials) to get this working from a different user?

I have a VM that I have full access to with access to all accounts. My question below is all run on the same machine, just under different user accounts.
If I logon with domain\user1 and run the following PowerShell to generate a string of a SecureString:
$SecurePassword = "ThisIsATest" | ConvertTo-SecureString -AsPlainText -Force
$RawSecureString = $SecurePassword | ConvertFrom-SecureString
Write-Host $RawSecureString
So the output is below:
$RawSecureString = "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000014c54a4678625849adf32615ece5d33f000000000200000000001066000000010000200000007ece54f23781b598d0341c2380e678bc6286222186717e612e0f095b3edc4137000000000e80000000020000200000006b68df76dbc98fcd35943be7818c80ed502ec49d0ae06deeec183367ea19e10d200000002087d6178d6a67165d41ed172e11eae6bf7d648a59d25c01dd573baaad985bb040000000adc87d779c7de9d1565bcb834e50214e982c133c3558111138a2e1964b599d1bcb7b4583ff18d314f7bc6a0549bf03342a49ba2456cc13df60585ca36125ae37"
With domain\user1 I run the following:
$SecureString = $RawSecureString | ConvertTo-SecureString
[System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($SecureString))
and the output is ThisIsATest, which is good.
If I logon as domain\user2 and run the following:
$RawSecureString = "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000014c54a4678625849adf32615ece5d33f000000000200000000001066000000010000200000007ece54f23781b598d0341c2380e678bc6286222186717e612e0f095b3edc4137000000000e80000000020000200000006b68df76dbc98fcd35943be7818c80ed502ec49d0ae06deeec183367ea19e10d200000002087d6178d6a67165d41ed172e11eae6bf7d648a59d25c01dd573baaad985bb040000000adc87d779c7de9d1565bcb834e50214e982c133c3558111138a2e1964b599d1bcb7b4583ff18d314f7bc6a0549bf03342a49ba2456cc13df60585ca36125ae37"
$SecureString = $RawSecureString | ConvertTo-SecureString
[System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($SecureString))
I get Key not valid for use in specified state., because it's a different user.
Since there is no key provided during encryption by user1, my question is, if I have access to both logon accounts, is there a way from user2 to decrypt this secure string?
The reason is I have many VM's where keys were stored in the registry as the local administer account and most of what I'm doing is from a remote domain account.
Yes, but you will have to recreate the SecureStrings.
The strings encrypted by ConvertTo-SecureString can only be de-crypted by the same computer and user account that encrypted them by default.
You can use work around this with the -Key parameter. From the helpful folks at PDQ.
You create an AES key like so:
$KeyFile = "C:\AES.key"
$Key = New-Object Byte[] 16 # You can use 16 (128-bit), 24 (192-bit), or 32 (256-bit) for AES
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | Out-File $KeyFile
Create the new SecureString object:
$PasswordFile = "C:\Password.txt"
$KeyFile = "C:\AES.key"
$Key = Get-Content $KeyFile
$Password = "P#ssword1" | ConvertTo-SecureString -AsPlainText -Force
$Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile
Creating PSCredential object on another computer or user:
$User = "MyUserName"
$PasswordFile = "C:\Password.txt"
$KeyFile = "C:\AES.key"
$key = Get-Content $KeyFile
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)
Anyone who gets the AES.key file will be able to decrypt the SecureString object so be mindful can access it!

PSCredential Error

I had created a PSCredential with the inline script and was able to access the credential until the PowerShell session which created the credential was open. When I have closed and reopened PowerShell to run the script again, I was not able to access $TFSAdminCred:
$UserID = "xyz"
$PswdFile = "\\Server1\TFSencrypt$\Pswd.txt"
$KeyFile = "\\Server1\TFSencrypt$\AES.txt"
$Key = New-Object byte[] 16
[System.Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | Out-File $KeyFile
$Key = Get-Content $KeyFile
$Pswd = "password" | ConvertTo-SecureString -AsPlainText -Force |
ConvertFrom-SecureString -Key $Key | Out-File $PswdFile
$TFSAdminCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserId, (Get-Content $PswdFile | ConvertTo-SecureString -Key $Key)
To persist variables for re-use you can export them to disk and import on Powershell start, or you can use powershell profiles to do that for you.
To export variable do
$var | export-clixml 'path'
To import
$var = import-clixml 'path'
to import with profile just add import to your powershell profile, to access your profile do notepad $profile from your PS prompt

Authenticating with PowerShell to Kill Process

I would like to be able to run this from different workstations which mean we need to authenticate. I have this below but it doesn't seem to work. Can you see anything wrong.
get-content .\killprocess.PS1
$username = 'je\leigh'
$password = cat 'U:\Accounts\Synergy Tools\securestring.txt' | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential `-argumentlist $username, $password
(Get-Content 'U:\Accounts\Synergy Tools\Computers.txt') | ForEach-Object {Get-WmiObject -computer $_ -class win32_process -filter "name='synergy.exe' or name='booking9.exe' or name='acl_apps.exe' or name='pos.exe' or name='booking.exe'" -credential $cred| %{$_.terminate()} | out-null}
If securestring.txt contains a readable password E.g. MyP#ssWord!123. Try using ConvertTo-SecureString's -AsPlainText & -Force parameters:
$password = Get-Content 'U:\...\securestring.txt' | ConvertTo-SecureString -AsPlainText -Force
This will convert the text in securestring.txt into a readable SecureString, which can be viewed with $Password | ConvertFrom-SecureString:
01000000d08c9ddf0115d1118c7a00c04fc297eb010000000a65b1b20fe4e0418aece793d7242358
0000000002000000000003660000c00000001000000082e9a55adb7c90d9bed5946aed69e5380000
000004800000a000000010000000932bccf24879272d36536f6ef98e1be4180000006fb092d673a8
1f84b5954f9cb35daee2addb2d325ec25112140000005c8982b4cd15503000796213c3e0d3869780
Then just give the $password variable straight to -argumentlist $username, $password
If you wanted to you could store the output of ConvertFrom-SecureString into the securestring.txt then use the following in your script:
$password = Get-Content 'U:\...\securestring.txt' | ConvertTo-SecureString
Note: You may get errors if there are more than one line in securestring.txt as it will turn $password an array of strings.

Powershell data read from file contains dollar sign $

I have a powershell script that is reading a password from a file, the password has been 'secured' using a generated AES Key. There are three files used in the process
AES Key File Generation:
$KeyFile = "\\server\path\AES.key"
$Key = New-Object Byte[] 16
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file $KeyFile
Password File Generation:
$PasswordFile = "\\server\path\Password.txt"
$KeyFile = "\\server\path\AES.key"
$Key = Get-Content $KeyFile
$Password = "Sy$tem#dmin" | ConvertTo-SecureString -AsPlainText -Force
$Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile
Script That Grabs Password File and Converts back to Plain Text:
$User = "myuser"
$PasswordFile = "\\server\path\Password.txt"
$KeyFile = "\\server\path\AES.key"
$key = Get-Content $KeyFile
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)
$PlainPassword2 = $MyCredential.GetNetworkCredential().Password
$PlainPassword2
The conversion back to plain text is really being done just so we can verify that the data is the same as what was initially created.
When we display the data contained in $PlainPassword2 instead of seeing Sy$tem#dmin as is expected, we are seeing Sy#dmin.
What can we do to correct this?
You are using double-quotes when converting the original password string:
$Password = "Sy$tem#dmin" | ConvertTo-SecureString -AsPlainText -Force
Since " allow for string interpolation, the parser tries to expand $tem, which, since it probably doesn't exist results in an empty string, thus you end up with the string you see in your output.
Use single-quotes instead:
$Password = 'Sy$tem#dmin' | ConvertTo-SecureString -AsPlainText -Force

Encrypt Credentials, Export, then Import

I've been working with Powershell for quite some time now but I don't understand how the encryption works, not even sure I'm using the right syntax from reading the help files.
#Get User Information
$User = Read-Host "Please enter your username"
$Password = Read-Host "Please enter your password. This will be encrypted" -AsSecureString | ConvertTo-SecureString -AsPlainText -Force
#Define a Key File
$KeyFile = "C:\Powershell\AES.key"
$Key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file $KeyFile
#Encrypt using AES
$PasswordFile = "C:\Powershell\Password.txt"
$KeyFile = "C:\Powershell\AES.key"
$Key = Get-Content $KeyFile
$Password | ConvertFrom-SecureString | Out-File $PasswordFile
#Set credentials to be called.
$myCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)
#Open text file.
Invoke-Command -ComputerName localhost -Credential $MyCredentials -ScriptBlock{
Invoke-Item C:\Powershell\Password.txt
}
I received an error when running this and I'm not sure why I can't pipe this:
ConvertFrom-SecureString : The input object cannot be bound to any
parameters for the command either because the command does not take
pipeline input or the input and its properties do not match any of the
parameters that take pipeline input. At C:\Powershell\Password.ps1:15
char:13
+ $Password | ConvertFrom-SecureString -Key $Key | Out-File $PasswordFile
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.Security.SecureString:String) [ConvertFrom-SecureString],
ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand
Are there any encryption experts that can help? I'm trying to simply save a password to a text file (encrypted) and then I want to use another script to call various programs using new credentials using the encrypted password, but I can't even get the encrypted password to work correctly. Thanks in advance.
To make things simple:
To Save the Credential Object to disk:
$credential = Get-Credential
$Key = [byte]1..32
$credential.Password | ConvertFrom-SecureString -Key $Key | Set-Content c:\cred.key
To Load it back to Powershell:
$Key = [byte]1..32
$username = "type the username here"
$encrypted = Get-Content c:\cred.key | ConvertTo-SecureString -Key $Key
## Create The Credential Object:
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
Sure that this is not secured, because everyone who see your code can re-use the credential,
If you are not using a key at all, the credential will be encrypted with your current user, and only the current user can decrypt it back.