Need help converting PowerShell commands to run in batch. I can get the following to run fine as .ps1:
$filecontent = Get-Content -path C:\temp\status.txt | Out-string
Send-MailMessage -to "tester#test.com" -from "ServerAdmin#test.com" -subject "STATUS: PASS" -body "$filecontent" -smtpServer mail2.co.test.ca.us
When I put it into a batch:
PowerShell -command "$filecontent = Get-Content -path C:\temp\status.txt | Out-String" ^
Powershell -command Send-MailMessage ^
-to \"tester#test.com\" ^
-from \"ServerAdmin#test.com\" ^
-subject \"STATUS: PASS \" ^
-body \"$filecontent\" ^
-smtpServer mail2.co.test.ca.us
I get this error:
Out-String : A positional parameter cannot be found that accepts argument 'Send-MailMessage'.
At line:1 char:55
+ ... tatus.txt | Out-String Send-MailMessage -to "tester#test.com" -from " ...
+ CategoryInfo : InvalidArgument: (:) [Out-String], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.OutStringCommand
Is the only way to make this work in a batch is to put the original PowerShell syntax into a .ps1 and call it from the batch? The send-mail portion works fine. Tried the $filecontent line without " and -Raw instead of the pipe and Out-string.
You should try to put it in one command :
PowerShell -command "$filecontent = Get-Content -path d:\temp\status.txt | Out-String; Send-MailMessage -to \"tester#test.com\" -from \"ServerAdmin#test.com\" -subject \"STATUS: PASS \" -body \"$filecontent\" -smtpServer mail2.co.test.ca.us"
Because in the second command $filecontent no longer exist.
Related
I am on windows in a git bash hook script and want to pipe output from a git command to a powershell script, but can not get to work in bash what otherwise works in a windows command shell:
The command in question is the following:
dir | powershell.exe -NoProfile -NonInteractive -Command "$Input | send_mail.ps1"
Here is the content of send_mail.ps1:
[CmdletBinding()]
Param
(
[Parameter(ValueFromPipeline)]
[string[]]$Lines
)
BEGIN
{
$AllLines = ""
}
PROCESS
{
foreach ($line in $Lines)
{
$AllLines += $line
$AllLines += "`r`n"
}
}
END
{
$EmailFrom = "from#sample.com"
$EmailTo = "to#sample.com"
$Subject = "Message from GIT"
$Body = $AllLines
$SMTPServer = "smtp.sample.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("from#sample.com", "asdf1234");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
}
If the command is run from powershell or windows command line i successfully receive an email with the contents of the directory.
If the command is run from bash the following error is displayed:
In Zeile:1 Zeichen:2
+ | C:\Temp\Test\send_mail.ps1
+ ~
Ein leeres Pipeelement ist nicht zulässig.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement
This translates roughly to "An empty pipe element is not allowed" and means $Input is empty here. Does anyone have a working example for bash?
Bash is probably expanding the $Input in double quotes to an empty string, because Input probably isn't defined as a variable in Bash, so PowerShell gets the command | send_mail.ps1. One way to fix it is to use single quotes instead of double quotes:
dir | powershell.exe -NoProfile -NonInteractive -Command '$Input | send_mail.ps1'
I'm trying to make e Powershell script to check a specific service(name) with Status and StartType and additional information like time and date of the servers and server names.
List of servers from .txt is only the FQDN's.
I have the desired output in powershell but can't get it properly to send via SMTP.
In one case it doesn't show the state or won't show to processes only the names of the servers and all the information is plain text not in containers for the different servers.
Desired output :desired output in powershell need to transfer to smtp email
$ServerList = Get-Content -Path "C:\new_folder\servers.txt"
Foreach ($server in $ServerList){
$time = "---"
$time = ([WMI]'').ConvertToDateTime((gwmi win32_operatingsystem -computername $server).LocalDateTime)
$server + ', ' + $time
Get-Service -ComputerName "$server" | where-object {$_.name -like '*goge*'} | Select #{Name="server";Expression={$server}},Name,DisplayName,StartType,Status
}send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high
Try to use this little fix, i leave comments
$ServerList = Get-Content -Path "C:\new_folder\servers.txt"
$array=#() #array which will contain result get-service
Foreach ($server in $ServerList){
$time = "---"
$time = ([WMI]'').ConvertToDateTime((gwmi win32_operatingsystem -computername $server).LocalDateTime)
$server + ', ' + $time
#add to our array result of each get-service from servers
$array+=Get-Service -ComputerName "$server" | where-object {$_.name -like '*goge*'} | Select #{Name="server";Expression={$server}},Name,DisplayName,StartType,Status
}
send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $array -BodyAsHtml -Priority high
I'm having a PowerShell script for comparing two text files and displaying the output:
Compare-Object $(Get-Content c:\scripts\x.txt) $(Get-Content c:\scripts\y.txt) -includeequal
But I want the output in the form of a notification, like an Email...
How can I forward the output to an Email-Body and then send it the mail?
To put the output comparison into an Email and send it over gmail, you can use the Send-MailMessage command like this:
$From = "YourEmail#gmail.com"
$To = "ToMail#Domain.com"
$Cc = "CCMail#Domain.com"
$Subject = "String Comparison"
$comparison = (Compare-Object (Get-Content c:\scripts\x.txt) (Get-Content c:\scripts\y.txt) -includeequal).InputObject
foreach($line in $comparison)
{
$Body+= $line
}
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential (Get-Credential)
For more information look into Send-MailMessage and Google SMTP Config
I have a Windows batch file for cmd.exe. It has a single line of code to invoke the PowerShell Send-MailMessage cmdlet and exit back to cmd.exe. Currently the line reads like:
PowerShell -Command "Send-MailMessage -To one.person#somewhere.com, another.person#sameplace.com -Subject 'A rather lengthy text' -From info#my.com -SmtpServer hostname.subdomain.mycompany.com -UseSsl -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'UserName',('SecretePassword1234'|ConvertTo-SecureString -AsPlainText -Force)) -Body 'A static text.'"
It works great. But I find it difficult to edit it in NotePad or any text editor because the line is way too long. What I want is to use the CMD.EXE's caret ^ character to break up the long string within the double quotes into multiple lines. However, the PowerShell.EXE command requires that:
PowerShell -Command <string>
The above syntax requires that CMD.EXE parse everything after -Command to be a SINGLE string, aka a single argument. I've tried the following that didn't work:
PowerShell -Command "Semd-MailMessage Blab Blab " ^
"More Blah Blah"
If I break up the line in my batch file as above, CMD.EXE will parse the first part of the string as one argument, and the string on the next line as another argument. Wrong. So what should I do?
I would put your command into a powershell script and then call that from cmd using the following command (or something similar):
powershell.exe -noprofile -executionpolicy bypass -file "path to my file.ps1"
then your editing can all happen inside the powershell ide and you can split your command up as required; either by using variables and/or by using the ` (back tick) character. Your Powershell script could then look like the following with is a lot easier to manage; plus you get the benefit of intellisense as you edit the script:
Send-MailMessage `
-To one.person#somewhere.com, another.person#sameplace.com `
-Subject 'A rather lengthy text' `
-From info#my.com `
-SmtpServer hostname.subdomain.mycompany.com `
-UseSsl `
-Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'UserName', ('SecretePassword1234'|ConvertTo-SecureString -AsPlainText -Force)) `
-Body 'A static text.'
I can agree as you've indicated that this doesn't work:
PowerShell -Command "Semd-MailMessage Blab Blab " ^
"More Blah Blah"
…and also agree that this doesn't either:
#Echo Off
PowerShell -Command "Get-WmiObject -Class Win32_Product "^
"| Select-Object -Property Name | Sort-Object Name"
Pause
However this does:
#Echo Off
PowerShell -Command "Get-WmiObject -Class Win32_Product "^
"| Select-Object -Property Name | Sort-Object Name"
Pause
…note the very small but seemingly very important single space at the beginning of the continuation line!
I think this is the simplest and clearest way to solve this problem because this method does not require additional files nor additional options, just plain PowerShell code:
PowerShell ^
Send-MailMessage ^
-To one.person#somewhere.com, another.person#sameplace.com ^
-Subject 'A rather lengthy text' ^
-From info#my.com ^
-SmtpServer hostname.subdomain.mycompany.com ^
-UseSsl ^
-Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'UserName',('SecretePassword1234'^|ConvertTo-SecureString -AsPlainText -Force)) ^
-Body 'A static text.'
Just be sure to properly escape special Batch characters, like ^|.
You either set variables in a batch file or you can do something completely hokey like this.
#echo off
setlocal enabledelayedexpansion
set "pscommand="
FOR %%G IN (
"Send-MailMessage -To one.person#somewhere.com, "
"another.person#sameplace.com "
"-Subject 'A rather lengthy text' "
"-From info#my.com "
"-SmtpServer hostname.subdomain.mycompany.com "
"-UseSsl -Credential "
"(New-Object -TypeName System.Management.Automation.PSCredential "
"-ArgumentList 'UserName',('SecretePassword1234'|ConvertTo-SecureString -AsPlainText -Force)) "
"-Body 'A static text.'"
) DO (
set "pscommand=!pscommand!%%~G"
)
PowerShell -Command "%pscommand%"
I have wrote a script for automated email using powershell.
The email sends however how can i configure it so that the file that is attached is moved to another folder inside the folder it was originally located?
#Searches dir for list , formats
$Attachment = Get-ChildItem -Path $dir -Filter "*$($Region.name)*" -Recurse
$AttachmentName = $Attachment.BaseName
$Subject = "$AttachmentName # $Time"
$Body = "Please find attached the file needed for $($Region.name).
Regards,
Me
"
#Actions Email
Send-MailMessage -From $Region.From -To $Region.To -CC $Region.Cc -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Attachments $Attachment.FullName
Move-Item Get-ChildItem -Path $dir -Filter "*$($Region.name)*" -Recurse "C:\Users\users\Desktop\MissingImageLists\OldLists"
}
Remove your Move-Item command and replace it with:
$Attachment | Move-Item -Destination "$dir\subfolder"