Running Powershell script from batch - Send-MailMessage not functioning - powershell

I am facing unusual issue with Powershell script. I have written script to run DB queries which runs one STORED Procedure. Below is the complete script:
$server="DBServer,Inst"
$Database = "DATABASE"
$ConnectionTimeout = 30
$QueryTimeout = 120
$Query="STORED_PROCEDURE"
Import-Module “sqlps” -DisableNameChecking
$ds=Invoke-Sqlcmd -Query $Query -Database $Database -ServerInstance $server -ConnectionTimeout $ConnectionTimeout -QueryTimeout $QueryTimeout
$date=(Get-Date).ToString()
$ret=$ds.Return
--Query returns 0 or 1, 0 means SP Passed otherwise failed.
$From="abc#xyz.com"
$SendCC= "aabbcc.b#xyz.com"
If ($ret -eq '0')
{
$Body=" STORED_PROCEDURE: <FONT COLOR=#00FF00> <b>PASS </b> </FONT> in <b> $server</b>:<i>$Database</i>; TimeStamp: $date"
$msg="Test: STORED_PROCEDURE - SUCCESS "
Write-Host "Sending Mail Notification - Ret 0"|
Send-MailMessage -From $From -To $SendCC -Subject $msg ($Body |Out-String) -BodyAsHtml -SmtpServer mail.xyz.com
Write-Host "Notification Sent!!"
}
This script works absolutely fine from my computer which is in xyz domain. I have created batch file to run this script as:
#pushd "D:\Temp\SM_SP"
powershell -ExecutionPolicy Bypass -File .\SP_SM.ps1 -noconsole
#popd
Even this batch file works fine in my computer, sends mail.. Works as expected! But the real issue is running the same in one of the test server (win Ser 2008 R2). Where the batch file when executed manually returns no errors – however I am not getting any mail notification.
Note-
• I have mentioned proper smtp server details in script, as I said the same script and batch are working fine in my computer which is in the same domain as this server.
• I have tested Powershell inbuilt command “Send-MailMessage” in the server as:
Send-MailMessage -From $from -To $to -Subject Test -SmtpServer mail.xyz.com
Where $from and $to both are my address and am receiving the mail absolutely fine. But in the server when I execute the above script in Powershell console or through wrapped Batch file – am not receiving mail.
Any help on this is greatly appreciated. Thanks in advance!
Regards
-Raaj

I've run into this issue several times as a result of Receive Connector settings in Exchange. We typically will just add the IP of a server to allow it to relay if we are going to start using it for sending email, otherwise we want connections refused.
If you're using exchange go to Server Configuration->Hub Transport and check what you have listed under "Receive mail from remote servers that have these IP addresses" on the Network tab. If you're using some other mail server I'd refer to the documentation on connection permissions for it. Also, if you're using a different user account on the server than you are using on your desktop you may want to try a Run as different user and see if it's something with the permissions of the account you're using on the server.

Related

Powersheel script to fetch logs from remote desktop

We are working on one application and for that application there is one module called replicator and this replicator shows the status whether failed or successful in every h hrs it runs. So, I want to create a powershell script which will check the logs from my remote desktop server and email me the status of replicator .
Can somebody help me in this.
Are the logs in a text file? Does it have a particular format? Something like:
$logline = Get-Content \\path\to\file.txt -Last 1
Send-MailMessage -smtpserver smtp0 -from me#me.com -to me#me.com -Subject "Latest Result is $logline"

What is the best way to store account credentials (especially password) for an automated email script?

I am writing a simple script (windows powershell) to send automated emails. A computer will be running at all times collecting data and then sending emails at regular intervals. Part of sending an email obviously is collecting credentials, and since its automated we cant have somebody there everytime to enter the user and password. The obvious solution is to just store info in $user and $pass vars in the script but this seems horribly unsafe to me, and prone to attacks. Is there any better way to do this? Maybe setup a secure email connection once with the user address and not have to enter it in again? I am new to powershell so im not really clear on the best ways to do this. Currently what I am doing is:
$from = 'UserEmail#anotherEmail.com'
$to = 'someEmail#SomeMail.com'
$smtpServer = 'smtp-mail.outlook.com'
$smtpPort = '587'
$mailSubject = 'PowerShell Script Email Test'
$password = 'p#ssword'
$mailBody = 'body text'
$credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $from, $($password | ConvertTo-SecureString -AsPlainText -Force)
Send-MailMessage -To "$to" -From "$from" -Subject $mailSubject -SmtpServer $smtpServer -UseSsl -Credential $credentials -BodyAsHtml -Body $mailBody
Any advice or documentation to read would be much appreciated
You may want to investigate the Protect-CMSMessage cmdlet, which allows you to encrypt/decrypt data using public key cryptography so that only users with the correct certificate would be able to decrypt the password.
If that seems like overkill, another, easier but possibly less secure, option is to export the credentials to XML and read them back when required.
To create the file, do this:
Log on as the user the script will be running as
Execute this command: Get-Credential | Export-CliXml <path>\cred.xml
When prompted enter the username/password to be used in the script
The resulting XML file will have the username and password securely stored and can be read back like this:
$cred = Import-CliXml <path>\cred.xml
You can then pass $cred to any cmdlet that has a -Credential parameter.
The password is encrypted in such a way that it can only be opened by the same user on the same computer, so if someone else opens it they won't be able to access the details. Obviously, if they can log on as the user who encrypted it (or convince that user to run a 'bad' script), then they will have access to the details, but otherwise this is pretty secure.
A third option is to use the built-in Credential Manager in Windows. This needs some complicated .NET interop for older systems, but luckily some nice person has already done the hard work for you:
PowerShell Credentials Manager
This is a bit easier in Windows 10:
PasswordVault Class

PowerShell 5.0 Send-MailMessage with Attachment

The following command successfully sends an e-mail using the parameters specified in the command:-
Send-MailMessage -From "<mailbox#domain.com>" -To "<mailbox#domain.com>" -Subject "Sending the Attachment" -Body "Forgot to send the attachment. Sending now." -SmtpServer "fqdn.smtprelay.com"
As soon as I add any kind of attachment, regardless of size, file extension (.txt, .zip etc.) the command apparently completes without generating any kind of error into the console output but the e-mail never hits the SMTP relay when I track the mail, it's almost as if the command fails but according to PowerShell it hasn't, it executes the command without any kind of output.
This is the command I'm using:
Send-MailMessage -From "<mailbox#domain.com>" -To "<mailbox#domain.com>" -Subject "Sending the Attachment" -Body "Forgot to send the attachment. Sending now." -SmtpServer "fqdn.smtprelay.com" -Attachments "C:\Temp\targetfile.zip"
Does any body have any advice on how I can go about troubleshooting further? It seems to be such a simple issue but I feel that I have now exhausted all options. I have verified that the target file exists and can be accessed from the PowerShell console.
Also, I can successfully establish a telnet connection to the SMTP relay on port 25 without authentication and generate a basic e-mail, the problem seems to be when I add an attachment.
New hosted e-mail security system was rejecting mail based on security policies, because the attachment was an unzipped HTML file attached to the e-mail it was being rejected as a potential security threat.
Added new code to firstly compress file before attaching to e-mail and sending - now works perfectly.

PowerShell script for System state backups of domain controller not working

Hello I am trying to get an automated backup for my domain controller to a network share using a script and windows task scheduler - our domain controller is windows server 2008r2
this is the code for the script i have written as seen below, however when i run the scrip it does create the folder on the network share but fails to initiate the system state backup power shell returns this error when i run the script.
any suggestions on what i can do to resolve this issue? i am also rather new to powershell so there many be a much easier way of going about it.
many thanks
Gordon
wbadmin 1.0 - Backup command-line tool
(C) Copyright 2004 Microsoft Corp.
ERROR - One of the parameters or options specified is invalid: [quiet].
See the syntax below.
Syntax: WBADMIN START SYSTEMSTATEBACKUP
-backupTarget:<VolumeName>
[-quiet]
Description: Creates a system state backup of the local computer and stores
it on the location specified.
To use this command, you must be a member of the Backup Operators group
or Administrators group.
Parameters:
-backupTarget Specifies the location where you want to store the backup.
The storage location requires a drive letter or a GUID-based
volume of the format: \\?\Volume{GUID}.
-quiet Runs the command with no prompts to the user.
Example:
WBADMIN START SYSTEMSTATEBACKUP -backupTarget:f:
#adds windows server backup powershell snapin
Add-Pssnapin windows.serverbackup
#gets date
$date = Get-Date -Format dd.MM.yyyy
#declares backup location and adds date
$backdir = ("\\backupserver\bpdbackups\DC\$date")
#makes backup directory on network share
mkdir $backdir | out-null
#runs system statebackup
wbadmin start systemstatebackup -backupTarget:$backdir -[quiet]
#sends and email at the nd of the process
$smtp = "192.168.xxx.xxx"
$from = "Domain Controller <support#domain.com>"
$to = "Network Admin <network.helpxxx#xxx.com>"
$body = "The backup operation has been successfully done! Date: $date"
$subject = "Backup on $date"
#Send an Email to User
send-MailMessage -SmtpServer $smtp -From $from -To $to -Subject $subject -Body $body - BodyAsHtml
write-host "Backup Successful"
OK so you have a couple of problems here. Firstly square brackets around a command line switch indicates that it is optional and should not be included. Secondly I think you need to enclose the string variable since you are not calling a powershell applet.
Try changing:
wbadmin start systemstatebackup -backupTarget:$backdir -[quiet]
to
wbadmin start systemstatebackup -backupTarget:"$backdir" -quiet

How to execute an external console application with PowerShell and send the result to email?

I need to execute some periodic console applications that give me some results (on the console)... How can I execute it and have its return data sent to my email?
I tried to use [Diagnostics.Process]::Start() and it launches my application but i don't know how to get the return... I do not want the exitCode, I want the text that the application prints on screen.
Using PS V2 CTP3.
*** UPDATE
The solutions presented worked fine but i have a problem... this application that i need to execute is gfix from the firebird database and now i discovered a thing, I can't redirect the output of gfix to a file, if i execute on command prompt the line:
gfix.exe -v -f dabatase.gdb > c:\test.txt
it print the output on the screen and the file is empty.
Same thing if I try to assign it to a variable... I don't know what difference gfix has from the other console apps that I use, but looks like its output can't be redirected.
Has someone seeing this?
*** UPDATE 2
Even if I use Start-transcript /Stop-Transcript, although on the screen I see the gfix output, on the file there is only the commands :/
*** UPDATE 3
Found the solution here
http://edn.embarcadero.com/br/article/25605
Something like this could work:
# temporary file
$f = [io.path]::GetTempFileName()
# start process and redirect its output to the temp file
ping localhost > $f
# create and send email
$emailFrom = "user#yourdomain.com"
$emailTo = "user#yourdomain.com"
$subject = "results"
$body = (Get-Content $f) -join "`r`n"
$smtpServer = "your smtp server"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom, $emailTo, $subject, $body)
# delete the file
remove-item $f
I think in this case [Diagnostics.Process]::Start() is not needed. Besides that there is a cmdlet Start-Process that does almost the same.
PowerShell v2 is now out, so you could consider upgrading.
Then, you can simply try:
PS > [string]$ipconfig=ipconfig
PS > send-mailmessage -to some_email -from from_email -subject PowerShell -body $ipconfig -bodyashtml -smtp my_smtp_server
Now, it depends on how complicated your command-line output is, because the above method will collapse multiple lines into a single on.