Im using in PS the next command:
"Password" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
This generate a Key that im saving as "Key.txt" file
Now i want to decrypt that password using this:
$password = Get-Content password.txt (or just copy-pasting the key)
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,($password | ConvertTo-SecureString)
BUT...
how i supose to add that to this...
$EmailFrom = "MyMail#gmail.com"
$EmailTo = "MayMail#gmail.com"
$Subject = "Test"
$Body = "this is a Test"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("My_USer", "My_Password");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
I want to add it as My_Password, of course i should add a variable $password that comes from the Key.txt file for example, but then...?
Nope, storing in plain text is not good at all, but if you are not concerned about that then it's there.
You have other options, with secure / encrypted files and Windows CredMan:
Quickly and securely storing your credentials – PowerShell
To get a credential object we can either manually create one or use the Get-Credential cmdlet to prompt for the account details:
$Credential = Get-Credential
To store the credentials into a .cred file:
$Credential | Export-CliXml -Path "${env:\userprofile}\Jaap.Cred"
And to load the credentials from the file and back into a variable:
$Credential = Import-CliXml -Path "${env:\userprofile}\Jaap.Cred"
Invoke-Command -Computername 'Server01' -Credential $Credential {whoami}
Securely Store Credentials on Disk
Allow multiple users to access credentials stored using export-clixml
How to run a PowerShell script against multiple Active Directory domains with different credentials
PowerShell Credentials Manager
CredMan.ps1 is a PowerShell script that provides access to the Win32 Credential Manager API used for management of stored credentials.
https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Credentials-d44c3cde
And modules to use
https://powershellgallery.com/packages/BetterCredentials
https://powershellgallery.com/packages/CredentialManager
https://powershellgallery.com/packages/IntelliTect.CredentialManager
First we save the credentials
"Password123" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File C:\key.txt -NoNewline
Then we can use it just like this :
$SMTPClient = New-Object Net.Mail.SmtpClient("SomeServer", 587)
$SMTPClient.Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist ThisIsAUserName ,($(Get-Content C:\key.txt) | ConvertTo-SecureString)
And we can check to make sure it loaded correctly like this :
$SMTPClient.Credentials | select username, password
The output looks like this
UserName Password
-------- --------
ThisIsAUserName Password123
Related
Basically I want to switch user in powershell in the same window (dont want to open a new one).
$username = "xxxxx"
$password = ConvertTo-SecureString "xxxxx" -AsPlainText -Force
$creds = New-Objet System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -NoNewWindow -Credential $creds
But instead of launching powershell in same window it launches it in a new window which doesnt even work I cant type anything into its just a blinking cursor.
First things first, try to describe what you need to do in detail since the approach you're using might be misguided. Are you just trying to run commands as a different user within a script? If so, use the methods described here : https://www.itdroplets.com/run-a-command-as-a-different-user-in-powershell/
I particularly like the start-job method which I use sometimes, example:
#Shows who is the current user
whoami
""
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $username,$password
$GetProcessJob = Start-Job -ScriptBlock {
#Shows who is the current user, in this case it's the user you provided credentials for. Everything in this scriptblock will run in his context.
whoami
} -Credential $Credential
#Wait until the job is completed
Wait-Job $GetProcessJob | Out-Null
#Get the Job results
$GetProcessResult = Receive-Job -Job $GetProcessJob
#Print the Job results
$GetProcessResult
If you truly just want to just launch another powershell.exe process as another user,
the only way I know of would be to simply start the new process and exit the first one after that command, this way you have only the new window running as the user provided.
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -Credential $creds ;Exit
I'm trying to update a local admin account password. I don't want to pass the password in plain text, so i found a workflow (https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/) that will allow me to encrypt PW's.
#Change password for TestAccount
$User = 'TestAccount'
$PasswordFile = "$PsScriptRoot\Password.txt"
$KeyFile = "$PsScriptRoot\AES.key"
$key = Get-Content $KeyFile
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)
$adsiUser = [adsi]"WinNT://localhost/$User,user"
$adsiUser.SetPassword($MyCredential.Password)
I received the error
Exception calling "SetPassword" with "1" argument(s): "Type mismatch.
(Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
So my google-fu allowed me to decrypt the password with
$decodedpassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($MyCredential.Password))
But now there's a trail of cookies in my script... is there any way to pass this as a Secure String?
Thanks,
Paul
Use the Built-in method GetNetworkCredential() to get the plain text password from the Credential Object
So Change this line:
$adsiUser.SetPassword($MyCredential.Password)
To This:
$adsiUser.SetPassword($MyCredential.GetNetworkCredential().Password)
For short Credential Save/Load Tutorial:
#To Save Credential to file
$pass = "123456" | ConvertTo-SecureString -AsPlainText -Force
$pass | ConvertFrom-SecureString | Set-Content c:\temp\pass.txt
#To Load Credential From Text
$username = "userName"
$encrypted = Get-Content c:\temp\pass.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
#To Show the Plain text Password from the Credential Object
$credential.GetNetworkCredential().Password
Issue:
Create a network share on a remote machine (Win 2008 Server) from a .ps1 script and provide username and password.
This works fine where the current user has enough privileges
$share = Get-WmiObject Win32_Share -List -ComputerName 10.0.0.1
$share.create("C:\dir","foo", 0)
When targetServer is a machine where my user does not have enough privileges I need a way to provide the username and password
Get-WmiObject has a parameter -Credential, so you can use Get-Credential to prompt the user for credentials and pass them like this:
$cred = Get-Credential
$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)
If you want to fully automate credential handling, you can build a credential object yourself:
$username = 'DOMAIN\user'
$password = 'password'
$pw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential $username, $pw
$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)
Storing plaintext passwords in a script is not a good practice, though, so you may want to store the encrypted password in a separate file (make sure to set restrictive permissions on that file):
PS C:\> Read-Host 'Enter password' -AsSecureString |
>> ConvertFrom-SecureString | Out-File 'C:\password.txt'
>>
Enter password: ******
PS C:\> Get-Content 'C:\password.txt'
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000a04a09e406c93741865ab010ed072699
0000000002000000000003660000c00000001000000028b14f21c501cdf629b94cea2837e8520000
000004800000a0000000100000002db774b0a8612917224e7dbfd69055340800000043f449c82f47
3e78140000007de59fcec57a1dc9b6b62272eff517b8bf5291e5
The encrypted password can then be read and decrypted like this:
$username = 'DOMAIN\user'
$pw = Get-Content 'C:\password.txt' | ConvertTo-SecureString
$cred = New-Object Management.Automation.PSCredential $username, $pw
$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)
Note, however, that ConvertTo-SecureString encrypts/decrypts the password with the user (and I think the host) running the command. If you need to encrypt the password as one user and decrypt it as another user (or on another host) you must share a key between those users/hosts. A random key can be generated like this:
PS C:\> $numchars = 24 # 192 Bit
PS C:\> $charmap = [char]'A'..[char]'Z' +
>> [char]'a'..[char]'z' +
>> [char]'0'..[char]'9'
>>
PS C:\> [char[]]($charmap | sort {Get-Random})[1..$numchars] -join ''
b69cGXKpJaI5tLrj4lHEPN3e
Create the password file with a shared key like this:
PS C:\> $key = [char[]]($charmap | sort {Get-Random})[1..$numchars] -join ''
PS C:\> $pw = Read-Host 'Enter password' -AsSecureString |
>> ConvertFrom-SecureString -Key ([byte[]][char[]]$key)
>>
Enter password: ******
PS C:\> #"
>> Key = $key
>> Pass = $pw
>> "# | Out-File 'C:\password.txt'
>>
and read the encrypted password like this:
$username = 'DOMAIN\user'
$pass = Get-Content 'C:\password.txt' | Out-String | ConvertFrom-StringData
$pw = ConvertTo-SecureString $pass.Pass -Key ([byte[]][char[]]$pass.Key)
$cred = New-Object Management.Automation.PSCredential $username, $pw
$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)
I'm working on some automation in our test environment where we have powershell scripts to join a windows client to either a domain or a workgroup.
I'm having trouble trying to move a windows 7 client from a domain to a workgroup, in the case where the client's machine account doesn't exist in the domain.
Here is the code:
$User = administrator
$Password = ConvertTo-SecureString "<password>" -AsPlainText -Force
$DomainCred = New-Object System.Management.Automation.PSCredential $User, $Password
remove-computer -credential $DomainCred -force -passthru -verbose
This is the error that is returned:
VERBOSE: Performing operation "Remove-Computer" on Target "localhost".
Remove-Computer: This command cannot be executed on target computer ('xxx')
due to following error: No mapping between account names and security IDs was done.
At line :1 char:16
+ remove-computer <<<< -credential $DomainCred -force -passthru -verbose
+ CategoryInfo : InvalidOperation: (xxx:String) [Remove-Computer],
InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.Powershell.
Commands.RemoveComputerCommand
However, if I try this using the GUI (Computer Properties, Advanced system settings, Computer Name , Change...), it prompts for credentials and succeeds.
How would I replicate this operation into the powershell command so that it can be done pragmatically?
Try Add-Computer, like this (untested):
Add-Computer -WorkgroupName "WORKGROUP" -Force
AFAIK the only difference between Add-Computer and Remove-Computer is that Remove-Computer also disables the computer account, which would probably give you this error since the computer account doesn't exist.
I have two options.
Option 01
$Workgroup = "CL-01" #IF you want to add computer to domain edit here(Domain name)
$Password = "Password" | ConvertTo-SecureString -asPlainText -Force
$Username = "$Workgroup\Username"
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
Add-Computer -WorkGroup $Workgroup -Credential $credential
Restart-Computer -Force
Option 2 and why Option 2 Storing a password in a script is not such a favorable option so I suggest taking up option 2
$Workgroup = "CL-01"#IF you want to add computer to domain edit here(Domain name)
$Password = Read-Host -Prompt "Enter password for $user" -AsSecureString
$Username = "$Workgroup\Username"
$credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
Add-Computer -WorkGroup $Workgroup -Credential $credential
Restart-Computer -Force
Note: Run the all the Scripts as Administrator!!
Hope this will help!! Cheers!!
I am trying to add remote server authentication to a PS1 batch file script.
So I can do this:
Copy-Item $src $destination -Credential $Creds
I created a password file that for now is in the same directory as the script. It simply contains the password string.
The line that causes the prompt:
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File password.txt
When I remove the Read-Host command, the prompt goes away and the script executes as expected.
Question
What's the correct way to do remote server authentication?
Here is the new code in context of the script:
[...]
if(-not(Test-Path $destination)){mkdir $destination | out-null}
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File password.txt
$PW = Get-Content password.txt | ConvertTo-Securestring
$Creds = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist "SERVER02\Administrator",$PW
ForEach ($sourcefile In $(Get-ChildItem $source | Where-Object { $_.Name -match "Daily_Reviews\[\d{1,12}-\d{1,12}\].journal" }))
{
[...]
Copy-Item $src $destination -Credential $Creds
[...]
}
If you aren't worried about portability of the password file between machines, you can use this fairly secure approach:
# Capture once and store to file - DON'T PUT THIS PART IN YOUR SCRIPT
$passwd = Read-Host "Enter password" -AsSecureString
$encpwd = ConvertFrom-SecureString $passwd
$encpwd
$encpwd > $path\password.bin
# Later pull this in and restore to a secure string
$encpwd = Get-Content $path\password.bin
$passwd = ConvertTo-SecureString $encpwd
$cred = new-object System.Management.Automation.PSCredential 'john',$passwd
$cred
# NOTE: The "secret" required to rehyrdate correctly is stored in DPAPI - consequence:
# You can only rehydrate on the same machine that did the ConvertFrom-SecureString
If you need to debug this to see if $passwd is correct you can execute this while debugging:
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($passwd)
$str = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
$str