I have two functions, Save Credential to create a .cred file:
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($Username, $PWord)
$cred.Password | Out-File "some\path\$($cred.Username).cred" -Force
and Get Credential to retrieve the password:
$string = Get-Content "some\path\$($Username).cred" | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $string
return $cred
I cannot for the life of me figure out how to retrieve the password from the .cred file that I created. The errors I get are:
ConvertTo-SecureString: Input String was not in the correct format
New-Object: Exception calling .actor with 2 arguments. Cannot process argument because the value of argument "password" is null. change the value of argument password to a non-null value
What version are you bound to? I might not be following properly, but it looks like you don't care about the whole credential and just want the password, so couldn't it just be:
#set
$pwd = "replace me"
$securepwd = $pwd | ConvertTo-SecureString -AsPlainText -Force
$encryptedpwd = $securepwd | ConvertFrom-SecureString
Out-File -FilePath C:\temp\Reference.cred -InputObject $encryptedpwd
then
#get
$securepwd = (Get-Content -Path C:\temp\Reference.cred) | ConvertTo-SecureString
#commented out 3 lines shows how to decrypt in case you want to view it/verify it, but isn't necessary
#$Marshal = [System.Runtime.InteropServices.Marshal]
#$Bstr = $Marshal::SecureStringToBSTR($securepwd)
#$pswd = $Marshal::PtrToStringAuto($Bstr)
#$Marshal::ZeroFreeBSTR($Bstr)
$RunAs = New-Object System.Management.Automation.PSCredential ('Domain\Account', $securepwd)
I'm not as good as most folks on here though, just giving it a stab.
Related
I'm trying to use a stored encrypted password in a script that sends an email but I keed getting the error:
send-mailmessage : The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
[DM6PR66666019.namprd456.prod.outlook.com]
I used the following code to create the text file:
$passwordtostore = 'NotTheRealPassword$9gv8z6VHnPfDd8zc'
$secureStringPWD = $passwordtostore | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPWD | ConvertFrom-SecureString
Set-Content "c:\temp\scriptsencrypted_password1.txt" $secureStringText
I use the following to import the password:
$passwordFile = "c:\temp\scriptsencrypted_password1.txt"
$password = Get-Content $passwordFile | ConvertTo-SecureString
Here's the sendmail function I am using:
function SendMail($ToEmails,$FromEmail,$Subj,$Body,$UserName,$Password){
$cred = New-Object System.Management.Automation.PSCredential $UserName,$Password
$MailParams=#{"from"=$FromEmail; "to"=$ToEmails;"body"=$Body;"subject"=$Subj;"smtpserver"="smtp.office365.com"}
send-mailmessage #MailParams -Credential $cred -UseSsl $true -port 587
}
Here's the code which calls the function:
$alertEmail = "me.stillme#mydomain.com"
$username="psemail#mydomain.com"
$passwordFile = "c:\temp\scriptsencrypted_password1.txt"
$password = Get-Content $passwordFile | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $password)
Import-Module -Name "..\SendMail.psm1"
... Doing some stuff
SendMail $alertEmail $username "This is the subject" "this is the body" $credential.UserName $credential.Password
Personally, I fail to see why you would make a function in a module you need to import for the Send-MailMessage cmdlet..
This makes things a lot harder to use.
Also, it kind of looks like you are switching the emailaddresses To and From inside the function.
Anyway, things go wrong when you are creating the credentials, split it into username and (secure) password to send as parameters to the function and recombine them into a credentials object in there.
Why not skip that module function and simply do:
$password = Get-Content 'c:\temp\scriptsencrypted_password1.txt' -Raw | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PsCredential('YourLoginName', $password)
$MailParams=#{
From = 'me.stillme#mydomain.com'
To = 'psemail#mydomain.com'
Body = "this is the body"
Subject = "This is the subject"
SmtpServer = 'smtp.office365.com'
Port = 587
UseSsl = $true
Credential = $credential
}
Send-MailMessage #MailParams
This will make your script far more readable/maintainable
I found two issues with my code above:
An unescaped $ in the password.
Once I added " -NoNewline" to the set-content, it began to work.
So, to create the encrypted file:
$passwordtostore = "7K9CBgvc4rttvfctrsef6PVHqnP6fDdwhatevervtfdscttzSc"
$secureStringPWD = $passwordtostore | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPWD | ConvertFrom-SecureString
Set-Content "D:\Powershell Scripts\encrypted.hash" $secureStringText -NoNewline
Then to retrieve the password and use it in a credential:
$password = Get-Content $passwordFile -Raw | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $password)
It wasn't the source of the issue, but I did implement #Theo's suggestion re: using send-mailmessage.
I am trying to have my password secured and stored in a file so that I don't need to enter each time when I run the script.
First step, I ran the following, entered the password which got stored into E:\cred.txt file. The txt file now contains an encrypted password.
(Get-Credential).Password | ConvertFrom-SecureString | Out-File "E:\cred.txt"
Secondly, I ran the below Script:
$File = "E:\cred.txt"
$User = "jason#domain.com"
#### I have two different user accounts, one for admin and other for operator,
#### however both user accounts use same password.
$adminuser = $User
$operator = $User -replace "#domain.com"
#### I would need to read $File to get only the password
$pass = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList (Get-Content $File | ConvertTo-SecureString)
$adminuser
$operator
$pass
Output:
jason#domain.com
jason
UserName Password
-------- --------
From the output, it seems New-Object refers to both UserName and Password. And when I try to connect to systems, it fails with Authentication error. Since I already have two different usernames hard coded within the script, how should I get only the password stored in $pass? or is it possible to include all usernames ($User, $adminuser, $operator) into the cred.txt file?
Try this:
#saving credentials
Get-Credential | Export-CliXml -Path c:\credential.xml
#importing credentials to a variable
$Credential = Import-CliXml -Path c:\credential.xml
Or this:
#you could then write it to a file or, i say its a better approach to a registry key
$SecurePassword = ConvertTo-SecureString -String 'P#ssw0rd' -AsPlainText -Force | ConvertFrom-SecureString
#now you are taking it back as a secure string
$RegistrySecureString = $SecurePassword | ConvertTo-SecureString
#you can aslo see the password
$UserName = "NULL"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $RegistrySecureString
$Password = $Credentials.GetNetworkCredential().Password
#P#ssw0rd
Does anyone know how to use password in System.DirectoryServices.ActiveDirectory context. Password is stored in a file.
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = get-content $PassFile | ConvertTo-SecureString -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
It always returns "Server rejected the credentials". If I store password in $Password variable, it works. For example, below code works:
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = "MyPassword"
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
Can someone please help as to how to use password from a file and then use with System.DirectoryServices.ActiveDirectory context.
Many thanks!
Nratwa
A [PSCredential] stores the password as a secure string, so it's encrypted.
To get the unencrypted password value:
$creds.GetNetworkCredential().Password
I'm having a lot of difficulty with a PowerShell script that I'm trying to call a DirectoryServices query from. Currently, if I do a
$password = read-host "Password" -asSecureString
and subsequently
$credential = New-Object System.Management.Automation.PSCredential $username,$password
everything works fine. However if I try to pass the string parameter with a param($password) and then convert it to a secure string with this code:
$password = ConvertTo-SecureString -AsPlainText -Force $password
After extensive debugging I can see this is working fine in terms of converting the string to a securestring, but I get a bad user/password from DirectoryServices when I use the parameter. Everything works fine when read from the console. Any ideas on what I can do to accept a parameter OR take console input in the absence of a parameter?
This is what I was hoping would work, but doesn't:
if($password -eq $null) {
$password = read-host "Password" -asSecureString
} else {
$password = ConvertTo-SecureString -AsPlainText -Force $password
}
$credential = New-Object System.Management.Automation.PSCredential $username,$password
I recently created a script and was running into the same issue. The work around I found in my case was the following:
#Prompts for the username/password, enter the username in the form of DomainName\UserName
$Credential = get-credential
#Converts the password to clear text to pass it through correctly as passing through a secure string does not work.
$Password = $credential.GetNetworkCredential().password
#Converts the $Credential to just the DomainName/UsernName.
$Account = $credential.UserName
Hopefully this will work in your situation
I'm having some trouble creating a Powershell credential. I am reading an encrypted string from a file, converting the string to a securestring and using that to create the credential. The error I get is:
New-Object : Cannot convert argument "1", with value: "System.Security.SecureString", >for "PSCredential" to type "System.Security.SecureString": "Cannot convert >the "System.Security.SecureString" value of type "System.RuntimeType" to >type "System.Security.SecureString"."
Here is the code I'm using:
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "athenpoly", $(Read-EncString F:\Scripting\1-Dev\RSA\p_ftp_dellpoly.rsa)
Function Read-EncString {
param ([String]$InputFile)
$encrypted = Import-Clixml $InputFile
$key = (3,42,5,77,67,12,76,9,8,9,4,5,6,55,32,81,23,12,3,55,2,9,6,1,5,32,4,55,6,8,56,12)
$csp = New-Object System.Security.Cryptography.CspParameters
$csp.KeyContainerName = "SuperSecretKeyContainer"
$csp.Flags = $csp.Flags -bor [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider -ArgumentList 5120,$csp
$rsa.PersistKeyInCsp = $true
$password = [char[]]$rsa.Decrypt($encrypted, $true) -join "" | ConvertTo-SecureString -Key $key
}
Any idea what I am doing wrong?
Here is how I set a credential when reading from a file:
$PassSec = ConvertTo-SecureString $($Pass) -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $($Domain + "\" + $User),$passSec
Breakdown:
1. $Pass -> Password that is imported (Example: P#ssw0rd)
2. $Domain -> Domain name (Example: Contoso)
3. $User -> User Name (Example: Admin)
What this does is create the variable $cred with the username as Contoso\Admin with a password of P#ssw0rd. This ends up with the same things as the command:
$Cred = Get-Credentials "Contoso\Admin"
Only without the prompt.