how to change encoding of string variable to UTF8 in powershell - powershell

In my PS script I have a string variable which is later used as a body of html email. I need to change encoding of the variable to UTF8 so that the text will be displayed correctly in the email. The variable is defined in the script, it's not read from any file.
Can anybody help me to fix that?
The solution in Encode a string in UTF-8 didn't work for me.

I solved it with -encoding "UTF8".
Send-MailMessage -From $FromEmail `
-to $mailto `
-Subject $mailSubject `
-Body $EmailBody `
-SmtpServer $SMTPHost `
-port $SMTPPort `
-UseSsl `
-Credential $cred `
-BodyAsHtml `
-Encoding "UTF8"

Related

Unable to send attachment using Send-MailMessage

Unable to send attachments using the Send-MailMessage cmdlet. The email sends with the subject and body, but no attachment.
Get-ADComputer -Filter {operatingsystem -like '*server*'} |
where {
$_.distinguishedname -notlike '*production*' -and
$_.distinguishedname -notlike '*tbd*' -and
$_.distinguishedname -notlike '*disabled*' -and
$_.distinguishedname -notlike '*domain controll*'
} |
Select Name, Distinguishedname |
Export-Csv -Path C:\Users\User1\wrongOU.csv |
Send-MailMessage -From 'from.email#gmail.com' -To 'to.email#gmail.com' -Subject 'This is a test email.' -SmtpServer smtp.test.com -Attachments "C:\Users\User1\File.txt" -Body 'This is a test email.'
The only parameter that accepts pipeline by value input is Attachments. If you perform a parameterbinding trace, you can see C:\Users\User1\File.txt bind to Attachments. Then the pipeline input is evaluated and a bind attempt is made. The attempt fails because there are no unbound parameters available to accept the value. When you bind that parameter in your command while piping an object into Send-MailMessage, PowerShell effectively removes the previously bound value (C:\Users\User1\File.txt) from binding to the Attachments parameter.
For successful command execution, you can do either of the following:
# For emailing File.txt
Send-MailMessage -From 'from.email#gmail.com' -To 'to.email#gmail.com' -Subject 'This is a test email.' -SmtpServer smtp.test.com -Attachments "C:\Users\User1\File.txt" -Body 'This is a test email.'
# For emailing wrongOU.csv
"C:\Users\User1\wrongOU.csv" | Send-MailMessage -From 'from.email#gmail.com' -To 'to.email#gmail.com' -Subject 'This is a test email.' -SmtpServer smtp.test.com -Body 'This is a test email.'
In short, the symptom is due to the parameter binding conflict that you have created. If you chose to leave off the -Attachments parameter with all else remaining the same, you would then have encountered issues because you are not piping a file path into the Send-MailMessage.
This exception and binding behavior appears to be typical for many built-in commands. A custom function does not exhibit these symptoms unless additional parameter validation is added. I would like to have more evidence as to what strips off the parameter value, but that remains to be seen.

Converting local user password to secure string does not work

I am needing to change local user passwords. When I convert it to a secure string, it acts as if it changed it, but when trying to login to the account it does not take the password. Not sure what I'm doing wrong, but I know for Powershell's Set-LocalUser cmdlet to take a password it must be a secure string. Below is the code
$UnsecurePassword = "Testing1234"
$SecurePassword = ConvertTo-SecureString $UnsecurePassword -AsPlainText -Force
$localaccount = Get-LocalUser -Name "Local" -ea stop | Enable-LocalUser
$localaccount | Set-LocalUser -Password $SecurePassword -PasswordNeverExpires 1 -ea stop
Your problem is the line
$localaccount = Get-LocalUser -Name "Local" -ea stop | Enable-LocalUser
As Enable-LocalUser doesn't return anything and also hasn't a -PassThru parameter, you end up with $localaccount being empty.
So change your script to:
$UnsecurePassword = "Testing1234"
$SecurePassword = ConvertTo-SecureString $UnsecurePassword -AsPlainText -Force
$localaccount = Get-LocalUser -Name "Local" -ea stop
$localaccount | Enable-LocalUser
$localaccount | Set-LocalUser -Password $SecurePassword -PasswordNeverExpires 1 -ea stop
This is the simplest way to set the password, you can add in your other stuff to make sure its enabled and whatever else you want. In terms of setting a password this is the easiest way to do it in my opinion.
Set-LocalUser -Name Local -Password (ConvertTo-SecureString -String 'Testing1234' -AsPlainText -Force)
Minimal solution in powershell > 5, Win 10
TL;DR:
Set-LocalUser -Name Local -Password (ConvertTo-SecureString 1234 -AsPlainText)
Findings
You can omit the force parameter for a minimal solution in opposition to the other's answer.
A naive approach would be Set-LocalUser local to change the password to no password. Try it, in powershell it does not work. Unsetting a password works in the gui in windows 10 though.

Powershell Scripting regarding decrementing dates by one

Here is my script so far. My intention is to take the event log from the previous day and send it an email to myself every morning. This is my script so far.
(Get-EventLog -LogName Application -After "10/26/16" | ConvertTo-Html | set-content 'C:\Users\myusername\Documents\Powershell Outputs\1day event log.html')
$date= get-date
if ($date=get-date).AddDays(-1)
Else {"File Not Found"}`
Send-MailMessage -To "my email" -From "my email" -subject "Eventlog for Yesterday" -body "This is a daily sent automated email for the event log of the previous day." -Attachments "`
Now what am I doing wrong, Im brand new to powershell so go easy.
So the first thing you are going to want to do is get Yesterday in a DateTime, which is what I assume you were trying to do with $date and if ($date = (get-date).AddDays(-1))
Then let's put you log location in a variable, so that we can use it both in saving the log and then sending the attachment
The -After parameter uses the DateTime that we saved in $Yesterday. The path for Set-Content is then $logPath
#Get DateTime for Yesterday
$Yesterday = (Get-Date).AddDays(-1)
#Set the location of the log attachment
$logPath = 'C:\Users\myusername\Documents\Powershell Outputs\1day event log.html'
#Get the Event Log After Yesterday, Convert it to HTML, Save it to the logPath
Get-EventLog -LogName Application -After $Yesterday | ConvertTo-Html | Set-Content $logPath
#Send Mail Message with the logPath as an attachment
Send-MailMessage -To "my email" -From "my email" -subject "Eventlog for Yesterday" -body "This is a daily sent automated email for the event log of the previous day." -Attachments $logpath

Brackets cause error in Send-MailMessage -Attachment

I am working on a script that gets the oldest log file in a folder, mails it to me and then deletes the file.
Getting the file name and deleting it afterwards works but, when a log file contains [ ] brackets, it fails sending the mail, while the file still gets deleted...
I know that brackets are wildcards and that I need to rename the files before trying to attach them but, I am not an experienced Powershell scripter and could not get examples working with my code... Could someone help me on my way?
My code:
$Item = Get-ChildItem -Path "C:\backup log" -filter "*.log" | Sort CreationTime | select -First 1
Send-MailMessage -to "Jason <jason#company.com>" -from "Backupmaster <backupmaster#company.net>" -Subject "sync log: $($Item.Name)" -SmtpServer "172.24.1.x" -body "Attached is the sync log.`nFilename: $($Item.Name). `nNote that the oldest log is sent first, newer logs may arrive later.`nThis log will be deleted from the server after sending.`n`n-Backupmaster" -attachments "$($Item.FullName)"
Remove-Item $($Item.FullName)
-Jason
I haven't tested this, but I'd expect it to work if you escape the brackets with `:
$Attachment = $Item.FullName -replace "(\[|\])",'`$1'
And then
Send-MailMessage -Attachments $Attachment

PowerShell send email to list of addresses within another script

I am trying to create a PowerShell script that will send an email to a list of people, but the email call is already embedded within a ping script. This is for a system that only has PowerShell v2.0.
Computers.txt contains a list of computers to be pinged and on failure will send an email.
This is my existing script I am trying to modify:
Get-Content -path "E:\Computers.txt" | ForEach-Object {
if (-not (Test-Connection -ComputerName $_ -Delay 2 -Quiet)) {
Send-MailMessage -To "email address" -Subject "$_ is Unreachable" -Body "$_ is unreachable by ping. Next check is in 5 minutes" -SmtpServer "server address" -From "another email address"
}
}
I know that I can use the Get-Content -path "E:\From_Email.txt" and Get-Content -path "E:\To_Email.txt" to call the list of email addresses, but I am not sure how to do this within the existing command. I have looked online, but I have not found how to nest calling additional text files within PowerShell for a script.
Do I need to call these files earlier and set them equal to a variable which gets called? Any help would be greatly appreciated. Thank you.
Assuming you have an email address on each line of "E:\To_Email.txt", the code below should work
$emails = (Get-Content "E:\To_Email.txt") -join ";"
Get-Content -path "E:\Computers.txt" | ForEach-Object {
if (-not (Test-Connection -ComputerName $_ -Delay 2 -Quiet)) {
Send-MailMessage -To $emails -Subject "$_ is Unreachable" -Body "$_ is unreachable by ping. Next check is in 5 minutes" -SmtpServer "server address" -From "another email address"
}
}
The extra first line reads in all lines of the email list file as an array, then joins it with semi-colons, which I think is how your email addresses should be separated. Worth checking though.
Example content of "E:\To_Email.txt"
person.one#yourdomain.whatever
person.two#yourdomain.whatever
person.three#yourdomain.whatever
person.four#yourdomain.whatever