Creating .bat file with e-mail body in Powershell - email

I'm currently working on a script which will read a mail from a certain sender, who will be sending some commands for the scripts to run.
The Main Idea:
Sender sends a mail with a command for example: ipconfig /all > result.txt and the script running at the recipients side copies this command to a .bat file and running the .bat file to process the command.
The Code:
$junk = $routlook.GetDefaultFolder(23)
$MI = $junk.items
foreach($m in $MI)
{
if($m.SenderEmailAddress -eq '<sender-address>')
{
Echo "#ECHO OFF" > com.bat
Echo $MI.item(1).Body > com.bat
.\com.bat
}
break
}
The Error:

Your problem is that you are not specifying the encoding of your output file.
The easiest way to fix this is to use the Out-File cmdlet and specify the encoding yourself. Note that the 2nd and subsequent calls to Out-File must specify the -Append parameter or you will overwrite your file.
$> "#ECHO OFF" | Out-File -FilePath cmd.bat -Encoding ascii
$> "Echo hi" | Out-File -FilePath cmd.bat -Encoding ascii -Append
$> .\cmd.bat

Related

PowerShell script to run application (with commands)

I am trying to run an application from C:\Program Files\APP\app.exe with the application built in commands. When I run from the command prompt, I can get the result I wanted. But I would like to use the script which will check other components of servers along with this one to avoid running this command manually. I tried both of the mentioned scripts below & I am not getting any output. It just opens a command prompt window, runs the result, and closes the command prompt,but I would like to get the output in an output file. Any suggestions? Please let me know.
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -ArgumentList "query mgmtclass" | Out-File $Output
Additionally, I also tried -
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -PipelineVariable "query mgmtclass" | Out-File $Output
I was also thinking that I can write a batch file & get output written in the temp directory & get those output using the command mentioned below -
Get-Content -Path 'C:\Program Files\tivoli\tsm\baclient\dsmerror.log' | select-object -last 15
Can you try using the RedirectStandardOutput parameter instead of | Out-File:
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -PipelineVariable "query mgmtclass" -RedirectStandardOutput $Output
Update:
The error you are getting ("Missing an argument") means exactly what it says. I can't see the line of code you ran to get the error, but I can replicate by omitting the value of RedirectStandardOutput. This example uses splatting so the line of code is not so long, and you can see more clearly what RedirectStandardOutput is:
$Output = "C:\Information.txt"
#{
FilePath = "C:\Program Files\APP\app.exe"
PipelineVariable = "query mgmtclass"
RedirectStandardOutput = $Output
} | % { Start-Process #_ }

Redirect output/logs to file in pipelined commands

I have the below command where I am trying to get output redirected for both commands before and after the pipe.
But this creates csv file with no data.
(some-command) > $log file | export-csv $csvpath >> $logfile
But when I run the command as below, data is returned
(some-command)| export-csv $csvpath >>$logfile
I want a way where I can redirect output for both commands in a single statement.
There are ways to use Tee-Object to pass output to a file and down the pipeline at the same time. You can also use ; to separate statements without needing a new line. Here's an example using both:
(get-date | Tee-Object -FilePath $logfile | Export-Csv $csvpath) ; gc $csvpath >> $logfile
Have a look at Tee-Object which should be pretty close to that what you want

Why did my log file get created with USC-2 Little Endian encoding?

I have a Powershell command that runs an executable and redirects all the output to a log file. It works and the log contains the correct text but the file is in USC-2 Little Endian format which is not readable by some other programs. When I use batch to do the same thing it creates the log in UTF-8. I can switch to batch as an option but my paths are UNC and batch prints a bunch of warnings about that. That's why I am try to use Powershell for this task.
Here is the script:
& .\rh.exe /connstring="Server=MYSERVER;Database=DB1;UID=U1;PWD=***" `
/files=Folder1 `
/versionfile=Version.xml `
/vx=version `
/repo=Repo1 `
> test.txt *>&1
When I open test.txt with Notepad++ and click the Encoding menu it shows USC-2 Little Endian as the selected encoding.
Update:
I tried this alternative and I now get UTF-8 encoding.
& .\rh.exe /connstring="Server=MYSERVER;Database=DB1;UID=U1;PWD=***" `
/files=Folder1 `
/versionfile=Version.xml `
/vx=version `
/repo=Repo1 `
| Out-File test.txt -Encoding utf8
This raises another question though. I was using *>&1 to make sure that all outputs get redirected and not just STDOUT. Should I add this to the end of the Out-File like so or does Out-File capture all forms of output?:
... | Out-File test.txt -Encoding utf8 *>&1

tee with utf-8 encoding

I'm trying to tee a server's output to both the console and a file in Powershell 4. The file is ending up with a UTF-16 encoding, which is incompatible with some other tools I'm using. According to help tee -full:
Tee-Object uses Unicode enocding when it writes to files.
...
To specify the encoding, use the Out-File cmdlet
So tee doesn't support changing encoding, and the help for both tee and Out-File don't show any examples of splitting a stream and encoding it with UTF-8.
Is there a simple way in Powershell 4 to tee (or otherwise split a stream) to a file with UTF-8 encoding?
One option is to use Add-Content or Set-Content instead of Out-File.
The *-Content cmdlets use ASCII encoding by default, and have a -Passthru switch so you can write to the file, and then have the input pass through to the console:
Get-Childitem -Name | Set-Content file.txt -Passthru
You would have to use -Variable and then write it out to a file in a separate step.
$data = $null
Get-Process | Tee-Object -Variable data
$data | Out-File -Path $path -Encoding Utf8
At first glance it seems like it's easier to avoid tee altogether and just capture the output in a variable, then write it to the screen and to a file.
But because of the way the pipeline works, this method allows for a long running pipeline to display data on screen as it goes along. Unfortunately the same cannot be said for the file, which won't be written until afterwards.
Doing Both
An alternative is to roll your own tee so to speak:
[String]::Empty | Out-File -Path $path # initialize the file since we're appending later
Get-Process | ForEach-Object {
$_ | Out-File $path -Append -Encoding Utf
$_
}
That will write to the file and back to the pipeline, and it will happen as it goes along. It's probably quite slow though.
Tee-object seems to invoke out-file, so this will make tee output utf8:
$PSDefaultParameterValues = #{'Out-File:Encoding' = 'utf8'}
First create the file using appropriate flags then append to it:
Set-Content out $null -Encoding Unicode
...
cmd1 | tee out -Append
...
cmdn | tee out -Append

How to redirect the output of a PowerShell to a file during its execution

I have a PowerShell script for which I would like to redirect the output to a file. The problem is that I cannot change the way this script is called. So I cannot do:
.\MyScript.ps1 > output.txt
How do I redirect the output of a PowerShell script during its execution?
Maybe Start-Transcript would work for you. First stop it if it's already running, then start it, and stop it when done.
$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
Start-Transcript -path C:\output.txt -append
# Do some stuff
Stop-Transcript
You can also have this running while working on stuff and have it saving your command line sessions for later reference.
If you want to completely suppress the error when attempting to stop a transcript that is not transcribing, you could do this:
$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Microsoft has announced on Powershell's Connections web site (2012-02-15 at 4:40 PM) that in version 3.0 they have extended the redirection as a solution to this problem.
In PowerShell 3.0, we've extended output redirection to include the following streams:
Pipeline (1)
Error (2)
Warning (3)
Verbose (4)
Debug (5)
All (*)
We still use the same operators
> Redirect to a file and replace contents
>> Redirect to a file and append to existing content
>&1 Merge with pipeline output
See the "about_Redirection" help article for details and examples.
help about_Redirection
Use:
Write "Stuff to write" | Out-File Outputfile.txt -Append
I take it you can modify MyScript.ps1. Then try to change it like so:
$(
Here is your current script
) *>&1 > output.txt
I just tried this with PowerShell 3. You can use all the redirect options as in Nathan Hartley's answer.
powershell ".\MyScript.ps1" > test.log
If you want a straight redirect of all output to a file, try using *>>:
# You'll receive standard output for the first command, and an error from the second command.
mkdir c:\temp -force *>> c:\my.log ;
mkdir c:\temp *>> c:\my.log ;
Since this is a straight redirect to file, it won't output to the console (often helpful). If you desire the console output, combined all output with *&>1, and then pipe with Tee-Object:
mkdir c:\temp -force *>&1 | Tee-Object -Append -FilePath c:\my.log ;
mkdir c:\temp *>&1 | Tee-Object -Append -FilePath c:\my.log ;
# Shorter aliased version
mkdir c:\temp *>&1 | tee -Append c:\my.log ;
I believe these techniques are supported in PowerShell 3.0 or later; I'm testing on PowerShell 5.0.
One possible solution, if your situation allows it:
Rename MyScript.ps1 to TheRealMyScript.ps1
Create a new MyScript.ps1 that looks like:
.\TheRealMyScript.ps1 > output.txt
You might want to take a look at the cmdlet Tee-Object. You can pipe output to Tee and it will write to the pipeline and also to a file
If you want to do it from the command line and not built into the script itself, use:
.\myscript.ps1 | Out-File c:\output.csv
To embed this in your script, you can do it like this:
Write-Output $server.name | Out-File '(Your Path)\Servers.txt' -Append
That should do the trick.