Why is force and AsPlainText required for secure string - powershell

I'm currently learning PowerShell through online tutorials.
What is the benefit of/why do examples use -Force and -AsPlainText when creating a secure string?
$password = 'P#ssw0rd' | ConvertTo-SecureString -AsPlainText -Force

There is no benefit of using those arguments, rather they are required to show that you understand that your string is not secure, despite the fact you've now placed it in a SecureString. Because you've passed it as plain text, it's already in memory in an insecure manner.
-AsPlainText shows that you want to pass in it as a plain text parameter. -Force is documented as:
Confirms that you understand the implications of using the AsPlainText parameter and still want to use it.

IIRC, -Force suppresses the confirmation prompt from -AsPlainText
$PW = ConvertTo-SecureString -String 'P#ssw0rd' -AsPlainText -Force

Related

Can you use MFA in powershell without using Exchange Online Powershell Module?

I've tried using "Send-MailMessage", but it looks like there isn't a parameter for authentifaction.
Can someone help here?
Send-MailMessage has a Credential parameter, see an example:
$smtpServer = 'smtp.office365.com'
$user = 'smtp#domain.com'
$pass = 'Password'
$creds = [pscredential]::new($user,($pass | ConvertTo-SecureString -AsPlainText -Force))
Send-MailMessage -SmtpServer $smtpServer -Credential $creds -To[...]
It's should work with MFA Enabled, if not, Generate an App Password and use it instead, See this link

How to encrypt/hide ClearText password in PowerShell Transcript

I have used the Start-Transcript command in my PowerShell profile. This is very useful for me to review the console output of my scripts at a later point in time when required. However, at times I also directly run some commands that include a ClearText password like the Set-ADAccountPassword cmdlet. Now, these passwords also get captured in the Transcript log file which poses a security risk.
So, is there a way PowerShell can recognize these password related commands and hide them with *'s in the Transcript log file.
I do not see any parameter in the Start-Transcript that would enable this behavior. Is there a workaround?
EDIT:
The command used (with ClearText password) is like the below,
Set-ADAccountPassword -Identity 'CN=Elisa Daugherty,OU=Accounts,DC=Fabrikam,DC=com' -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "p#ssw0rd" -Force)
All passwords accepted by the Set-ADAccountPassword cmdlet are encrypted (SecureString) passwords:
Set-ADAccountPassword
[-WhatIf]
[-Confirm]
[-AuthType <ADAuthType>]
[-Credential <PSCredential>]
[-Identity] <ADAccount>
[-NewPassword <SecureString>]
[-OldPassword <SecureString>]
[-Partition <String>]
[-PassThru]
[-Reset]
[-Server <String>]
[<CommonParameters>]
Nevertheless, if you come across a cmdlet (or an external command) that accepts plain text passwords, that would be your security weakness to be resolved as that is not just captured by Start-Transcript but also sent to the host console and displayed.
Saying that, you should not hardcode passwords in your scripts as in the example of Set-ADAccountPassword :
Set-ADAccountPassword -Identity elisada -OldPassword (ConvertTo-SecureString -AsPlainText "p#ssw0rd" -Force) -NewPassword (ConvertTo-SecureString -AsPlainText "qwert#12345" -Force)
Instead, use the encrypted string as input for the ConvertTo-SecureString.
To create the secure string, use the follwing sommand: (don't hardcode this in your scripts either):
Read-Host -Prompt "Enter password" -AsSecureString | ConvertFrom-SecureString
Results:
12345678d08c9ddf0115d1118c7a00c04fc297eb01000000c8e74a7ee4e2da4eae03ae6fbc416934123456789200000000001066000000010000200000002568f3e73d018b1d0ee8a616c8aa2e9614bad0a6bb62ac76aa4b2b90c0178d4b000000000e80000000020000200000002e443228fdf8e2c54b356420d854535e9acc13dcf635755ae80d17bca4ec3cce20000000a4517f6ca8873e9431a5cd9af714617116014ede30e1a927c856ed4738e03a2340000000ce49ddafe4da3f8cd64e14c347126d5e8907fa16deb9f5133f8807b675f40a3354465868414aba785fcde64bbd98a125924ccfb16ad718f8f24698c3dab88c0d
And use the results in the concerned script (without the -AsPlainText switch), e.g.:
$OldPassword = '12345678d08c9ddf0115d1118c7a00c04fc297eb01000000c8e74a7ee4e2da4eae03ae6fbc416934123456789200000000001066000000010000200000002568f3e73d018b1d0ee8a616c8aa2e9614bad0a6bb62ac76aa4b2b90c0178d4b000000000e80000000020000200000002e443228fdf8e2c54b356420d854535e9acc13dcf635755ae80d17bca4ec3cce20000000a4517f6ca8873e9431a5cd9af714617116014ede30e1a927c856ed4738e03a2340000000ce49ddafe4da3f8cd64e14c347126d5e8907fa16deb9f5133f8807b675f40a3354465868414aba785fcde64bbd98a125924ccfb16ad718f8f24698c3dab88c0d'
$NewPassword = '12345678d08c9ddf0115d1118c7a00c04fc297eb01000000c8e74a7ee4e2da4eae03ae6fbc416934123456789200000000001066000000010000200000002568f3e73d018b1d0ee8a616c8aa2e9614bad0a6bb62ac76aa4b2b90c0178d4b000000000e80000000020000200000002e443228fdf8e2c54b356420d854535e9acc13dcf635755ae80d17bca4ec3cce20000000a4517f6ca8873e9431a5cd9af714617116014ede30e1a927c856ed4738e03a2340000000ce49ddafe4da3f8cd64e14c347126d5e8907fa16deb9f5133f8807b675f40a3354465868414aba785fcde64bbd98a125924ccfb16ad718f8f24698c3dab88c0d'
Set-ADAccountPassword -Identity elisada -OldPassword (ConvertTo-SecureString $OldPassword) -NewPassword (ConvertTo-SecureString $NewPassword)
note 1: The encrypted string is only supposed to work under the account where it is created.
note 2: quote from the SecureString Class:
We don't recommend that you use the SecureString class for new
development. For more information, see SecureString shouldn't be
used
on GitHub.

Saving secure string in persistent environment variable

So I'm wanting to save a secure string variable type for a local user. That way I can run a convertfrom-securestring to make rest api calls in a .ps1 file without the password being accessible. Is what I'm trying possible?
The code I'm using is below, but not yet working:
$PlainPassword = "atestpassword"
$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force
[Environment]::SetEnvironmentVariable('JiraCreds', $SecurePassword, "User")
Are environment variables only saved as strings without support for other data types?
Yes, environment variables are invariably strings, and a [securestring] instance cannot be used directly, because its string representation is simply its type name (System.Security.SecureString).
However, you can pipe to ConvertFrom-SecureString to get a (still encrypted) string representation:
$PlainPassword = "atestpassword" # Don't actually store this in your script.
$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force |
ConvertFrom-SecureString
[Environment]::SetEnvironmentVariable('JiraCreds', $SecurePassword, "User")
To later use the environment variable to construct a [pscredential] instance (using the current user's username as an example):
$cred = New-Object pscredential $env:USERNAME, (ConvertTo-SecureString $env:JiraCreds)

Add username and password to Powershell script

I'm trying to create a powershell script to allow my kids to reboot my Raspberry Pi from their Windows computer if need be. I've tested everything and have gotten it to work, but the only hitch is that it's prompting for a username and password. I realize the line that's doing it is:
New-SSHSession -ComputerName "myPi" -Credential (Get-Credential)
I've done some searching, but I can't seem to figure out if it's possible to replace the "(Get-Credential)" section to automatically enter the username/password.
And yes, I'm aware of the security risks. They could do much more damage to the Windows machine than they could ever do on the Pi, and the settings on the Pi are very easily restored, so no worries from my end.
Something like this should work:
$user = "someuser"
$pass = ConvertTo-SecureString -String "somepassword" -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
New-SSHSession -ComputerName "myPi" -Credential $creds
You could also call a file that has the password encrypted in it. Note this can only be decrypted by the account it was generated on on the computer it was generated on.
$pass = "Password"
$Username = "Username"
$outfile = "c:\filelocation.xml"
$secureStringPwd = $pass | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($Username,$secureStringPwd)
$credential | Export-CliXml -Path $OutFile
Addressing Bill.
Correct, hard coding the password in the script is bad practice. Below is how I would change the first portion.
The above came from a custom script that's purpose was to create many cred accounts off a input json is why I wrote it that way.
$outfile = "c:\filelocation.xml"
Get-Credential | export-clixml -path $OutFile
You then can call the file in your script like so but this has to be done on the same user and computer that the creds file was generated on.
$Creds = Import-Clixml -Path "c:\file.xml"
New-SSHSession -ComputerName "myPi" -Credential $creds
Good point Edited -argumentlist.
Another option could be to do a 1 time setup with get-credential then convert the password to plaintext using convertfrom-securestring and then in the file you can take your password plaintext secure string and so something similar to the other answers:
$user = "someuser"
$pass = "YOUR LONG PASSWORD GUID FROM ABOVE" | convertTO-securestring
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
New-SSHSession -ComputerName "myPi" -Credential $creds
This lets you do a one time setup, but avoids having multiple files or having your password appear in a readable way in the script.
If you go this way you need to do the setup FROM the account that will run the script ON the machine that will run the script, because it uses those for the encryption as far as I know.

Importing a certificate with "Import-PfxCertificate" results in an invalid cert

I have a certificate (.pfx) that works fine when I import it using the GUI with (include all extended properites) checked.
If I import it without that checked, I can't use it in IIS.
If I try to import it via powershell (the end goal), I also can't use it in IIS.
When I try to use it in IIS, I get this error message:
A specified logon session does not exist. It may already have been
terminated.
I've tried a few methods for importing it, this is the most recent version of my script:
$certPassword = convertto-securestring 'thecertpasswordhere' -asplaintext -force
Import-PfxCertificate $localFilePath -Password $certPassword
Does anyone have any idea how to make this work or what I can look into for more info? I've had no luck searching so far.
Thanks!
Verify the script is running with the appropriate credentials (i.e. LOCAL SYSTEM, etc.).
You can also try piping the certificate (*.pfx) as follows:
Get-ChildItem -Path $localFilePath | Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString -String "thecertpasswordhere" -Force -AsPlainText