Albert Mulder
Albert Mulder

Reputation: 157

Powershell ps1 file fails but code is good

When I run my Powershell script from the command line, it fails, however if I copy line by line and run it in Powershell Console it runs fine.

powershell -ExecutionPolicy Bypass -File "F:\email.ps1" -FFFeatureOff

yields:

At F:\email.ps1:16 char:126 + ... ential("username", "password"); + ~~~ The string is missing the terminator: ".

At F:\email.ps1:9 char:1 + { + ~ Missing closing '}' in statement block or type definition.

Its just really odd if I open powershell window and paste the script in, it works, but running the ps1 file I get the error, even in the editor I get the same issues

Full Script:

$EmailTo = "xxxxx"
$EmailFrom = "xxxxxx"
$Subject = "LicenceKey & Instructions"
$Body = "This is an automated email"
$SMTPServer = "smtp.gmail.com"
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
$files=Get-ChildItem "C:\Users\alber\Desktop\LicenceKey\newuser"
Foreach($file in $files)
{
    Write-Host “Attaching File :- ” $file
    $attachment = New-Object System.Net.Mail.Attachment –ArgumentList "C:\Users\alber\Desktop\LicenceKey\newuser\$file"
    $SMTPMessage.Attachments.Add($attachment)
}
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username", "password");
$SMTPClient.Send($SMTPMessage)

Upvotes: 0

Views: 822

Answers (2)

mklement0
mklement0

Reputation: 437052

The fact that James C.'s answer was accepted by the OP suggests that it was motivated by the OP's gratitude for the generally helpful, but non-specific - and ultimately potentially confusing - pointers contained in it.

Unfortunately, it falls short as an answer of general interest to future readers and is likely to cause confusion; as of this writing:

  • It contains an overtly incorrect claim:

The issue here is that the $file is outside the param for the message, moving the quote will fix that: Write-Host “Attaching File :- $file”

However, there is no problem with Write-Host “Attaching File :- ” $file, because Write-Host simply concatenates multiple arguments with spaces - no strict need for a single argument.
(As stated, PowerShell recognizes "smart quotes" (non-ASCII quotes), assuming they're properly encoded - see below).

  • It does not explain the OP's symptoms as posted.

  • It almost makes it sound as if it weren't possible to embed a literal " - or $, for that matter - in a double-quoted string due to a limitation in PowerShell, which, of course, isn't true; escaping with backticks is all that is needed: "Pa`$`$`"w0rd".


Instead, PetSerAl's helpful comments on the question presumably point to the actual answer:

  • There may be a character encoding issue, given that "smart quotes" (non-ASCII quote characters) are used, which would surface in an incorrectly encoded script file.

  • PetSerAl's answer here suggests that UTF-8-encoded script content must be saved to a file with a BOM in order for PowerShell to recognize the encoding.

  • Update: PetSerAl surmises that the "actual troublemaker is an EN DASH here:
    –ArgumentList, which, when improperly decoded: [Text.Encoding]::GetEncoding(1250).GetString([Text.Encoding]‌​::UTF8.GetBytes('–')‌​), yields –, an unpaired double quote."

Upvotes: 2

henrycarteruk
henrycarteruk

Reputation: 13207

At F:\email.ps1:9 char:1 + { + ~ Missing closing '}' in statement block or type definition.

The issue here is that the $file is outside the param for the message, moving the quote will fix that:

Write-Host “Attaching File :- $file”

(Smart Quotes “ ” are accepted by PowerShell but aren't but most other languages, I personally avoid them to be sure.)


At F:\email.ps1:16 char:126 + ... ential("username", "password"); + ~~~ The string is missing the terminator: ".

The double quotes you're using here: ("username", "password") can cause Powershell to incorrectly interpret where the password ends if it contains certain special characters.

For example the password Pa$$"w0rd will cause issues when used in your script because of the double quote within.

It will be interpreted as "Pa$$" with the remaining w0rd" remaining ( which only contains a single quoteation mark and is not correctly terminated as a string)

To avoid this you can use single quotes instead, they are not evaluated and are interpreted as literals:

$SMTPClient.Credentials = New-Object System.Net.NetworkCredential('username', 'password')

See about about_quoting_rules for more info on single and double quotes.

Upvotes: 1

Related Questions