I'm having a problem with a script.
Every night, the server task scheduler runs a batch that creates a log on which PCs it couldn't update. This PS script then pulls the error log and sends an email notifying us of the PCs. The error log file is a .txt file and the name of the file changes everyday to reflect the date, for example, 10172016.txt.
I can get the script to email and it used to pull the log file and place it into its body; but now, it's blank and shows an error regarding "+".
Code:
clear
$smtpserver = "test.test.org"
$from="noreply@test.org"
$to="adamh@test.org"
$subject="Update Error Log for" + " " + (get-date -format d)
$message = (Get-Content -path "\\testserver\Departments\IT\Private\test\logs" + "(get-date -f mmddyyyy)" + ".txt" | Out-String )
$mailer = new-object Net.Mail.SMTPclient($smtpserver)
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
$msg.IsBodyHTML = $false
$mailer.send($msg)
Please help.
There is (at least) a problem with your code, namely (command simplified):
Get-Content -path "\path\to\" + "(get-date -f MMddyyyy)" + ".txt"
It needs to be (note the enclosing parentheses and the absence of double quotes around the get-date
command):
Get-Content -path ("\path\to\" + (get-date -f MMddyyyy) + ".txt")
PowerShell has two fundamental parsing modes - argument mode and expression mode, and understanding which is applied when is important:
see Get-Help about_Parsing
.
In short: Without (...)
, PowerShell sees "\path\to\" + (get-date -f MMddyyyy) + ".txt"
as 5 separate arguments rather than a single, synthesized string.
Alternatively, you could use a single double-quoted string with string interpolation that uses the subexpression operator, $(...)
, to embed the get-date
call:
Get-Content -path "\path\to\$(get-date -f MMddyyyy).txt"
Additional observations:
A native Send-MailMessage
is available since PowerShell version 3.
The format string for 2-digit months is MM
, not mm
(the latter is minutes).
While using pseudo method syntax new-object Net.Mail.MailMessage($from,$to,$subject,$body)
happens to work, it's better to avoid it, because it can mask a misconception of how New-Object
works: The proper form is New-Object Net.Mail.MailMessage -ArgumentList $from,$to,$subject,$body
; as you can see, because you're dealing with a cmdlet, it uses argument mode.