Calling a VB Script from a Powershell script produces unexpected runtime errors when sending automated emails - powershell

I have the following VB Script:
Set MSOutlook = CreateObject("Outlook.Application")
Set MailMsg = MSOutlook.CreateItem(0)
With MailMsg
.To = "xyz#gmail.com"
.Subject = "my subject"
.HTMLBody = "my text"
.Display
SendKeys "{TAB}{DOWN}{DOWN}{ENTER}", True
.Send
End With
Set MSOutlook = Nothing
Set MailMsg = Nothing
This script runs fine when executed within a VB compiler, such as Microsoft Visual Basic for Applications.
The SendKeys is required because of this damn Titus classification system we have in place at work to classify everything, such as emails and documents.
The email sends fine and it is classified correctly.
Now I am trying to call this script from the following Powershell script:
& cscript 'C:\Documents\sendEmail.vbs' //nologo
But the following error is received either in the Powershell ISE or when calling the vb script directly from a PowerShell console:
cscript.exe : C:\Documents\sendEmail.vbs Microsoft VBScript runtime error: Type mismatch: 'SendKeys'
Anyone know much about this and why the SendKeys function apparently cannot be used this way?
To pre-empt comments, yes, I would really like to move this vb functionality into the PowerShell script but the TITUS plugin is causing all sorts of headaches around that right now.
Thanks

In VBA, the SendKeys command is a member of the global Interaction module and, thus, always in scope.
In VBScript, you need to use the SendKeys method of the WScript.Shell object instead:
Dim shell
Set shell = CreateObject("WScript.Shell")
shell.SendKeys "{TAB}{DOWN}{DOWN}{ENTER}", True

Related

Prepopulate "from:" field on outlook email using commands

I've followed different tutorials about prepopulating an email using outlook, and I've been successful on filling the "To:", "CC:", "Subject:" and the body.
outlook.exe /c ipm.note /m test#gmail.com?v=1
&cc=otherEmail#gmail.com
&subject=hello
&body=hi%20there
The point is, I would want to change the "From:" field, since I have 3 different accounts on my Outlook. I was wondering if there are some command to do that.
I didnt find anything about how to do it, I tried this but didnt work:
outlook.exe /c ipm.note /m test#gmail.com?v=1
&from=secondaryAccount#gmail.com
&cc=otherEmail#gmail.com
&subject=hello
&body=hi%20there
This also didnt work:
outlook.exe /c ipm.note /profile=secondaryAccount#gmail.com
/m test#gmail.com?v=1
&cc=otherEmail#gmail.com
&subject=hello
&body=hi%20there
Im using Outlook installed on my local PC, Office365.
You need to automate Outlook to set the MailItem.SendUsingAccount property available in the Outlook object model. Not all properties are available in the command line unfortunately. Here is a VBA macro which shows hot to set up the property:
Sub SendUsingAccount()
Dim oAccount As Outlook.account
For Each oAccount In Application.Session.Accounts
If oAccount.AccountType = olPop3 Then
Dim oMail As Outlook.MailItem
Set oMail = Application.CreateItem(olMailItem)
oMail.Subject = "Sent using POP3 Account"
oMail.Recipients.Add ("someone#example.com")
oMail.Recipients.ResolveAll
Set oMail.SendUsingAccount = oAccount
oMail.Send
End If
Next
End Sub
Also you may find the Automating Outlook from Other Office Applications article helpful.

Powershell script how to access variable

I have a master script master.ps1 which executes two child ps1 scripts like below:
& "child1.ps1"
& "child2.ps1"
The problem I have now is at the end of master.ps1 script, based on certain variable values set in child1.ps1 and child2.ps1, I need to determine if I need to send an email or not.
Is there anyway this can be acheived? I'm using powershell 2.0
Thanks,
What you want to do is execute the child1.ps1 and child2.ps1 scripts in the scope of the calling script.
You can do this easily by dot-sourcing the scripts (. <command>), rather than using the call operator (& <command>):
. child1.ps1
. child2.ps1
# $a is now available

How to call a function within & in powershell?

Suppose I have a function in test.ps1, its name is show the code is like below:
. "some_path\some_other_script.ps1"
function show {
write-host "Hello World"
#some other function call from some_other_script.ps1
...
}
How can I call show in follow format (in a & - call operator)
powershell.exe "& '%test_script_path%\test.ps1'\show"
I think I need to dot source test.ps1 first in order to get dependencies in show function from some_other_script.ps1
I know I can create a new script and put the code in show in the new script instead of in a function. In that way, when do &... the script will be invoked. But I don't want to create a new script just for a very simple function
Thanks for any suggestion
You could dot source it and then call it like this.
powershell -Command ". '%test_script_path%\toolsql.ps1'; show"
The ; is used as a separator between commands.
I am really appreciated for the help and time from #Patrick Meinecke, the following command works.
powershell -command ". .\test.ps1;show"
Like he mentioned in the chat,
"So to explain that
the .\ just indicates it's in the current directory
it still needed the other . to tell powershell to load the script into the current context"

Running VB Script file with arguments

I have to run a VB script which has 2 arguments. So I am running a command below.
Delete_Dummy1.vb
s C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml.csv C:\Users\c6342\Deskto
p\XML_to_CSV\Temp_Files\xml1.txt
**VB Script Sample - not working:**
**sourceloc** = WScript.Arguments.Item(0)
**destloc** = WScript.Arguments.Item(1)
Dim objFSO, dataArray, clippedArray()
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set oTextStream = objFSO.OpenTextFile("**sourceloc**")
Set newFile = objFSO.CreateTextFile("**destloc**")
It throws the error as file not found. But if I hard code the sourceloc and destloc and remove the arguments it is working fine. it is throwing error only when i am using arguments.
**Working VB Script sample:**
Set oTextStream = objFSO.OpenTextFile("C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml.csv")
Set newFile = objFSO.CreateTextFile("C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt")
This works fine. But as per my project requirement, I cant hard code these file locations. I can pass as parameters from command.
After a length discussion in the comments think it will be best to just update my answer.
The reason for the Arguments not working is you never pass them to the OpenTextFile() and CreateTextFile() methods. Instead you are passing literal strings containing the variable name instead of the actual variables.
sourceloc = WScript.Arguments.Item(0)
destloc = WScript.Arguments.Item(1)
Dim objFSO, dataArray, clippedArray()
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Pass the variables not a string literal
Set oTextStream = objFSO.OpenTextFile(sourceloc)
Set newFile = objFSO.CreateTextFile(destloc)
As it stands VBScript keeps trying to locate a file called sourceloc and destloc instead of the actual file names from the passed Arguments collection. Which is what likely causes the
Microsoft VBScript Runtime Error: File Not Found
Note: Below is based on initial question which has since been revised.
This comes down to how you are passing the arguments to the script, any spaces in the values will be treated as new arguments. At the moment this is how the arguments are passed;
0. C:\Users\enter
1. code
2. herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv
3. C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt
I'm sure this isn't what you expect. To avoid this enclose each argument in double quotes ("...").
Delete_Dummy1.vbs "C:\Users\enter code herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv" "C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt"
That way you get more what you expected
0. C:\Users\enter code herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv
1. C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt

batch file programming to get email notification with text file data as a body of e mail

I want a batch file program to get email.
For example I have a text file main.txt with some data
I want this to my mail id. Can you please help me in this programming.
Thanks in advance.
If you've got an email server you can send the emails to, I'd first recommend Blat as mentioned by PA's comment.
If you're running Microsoft Outlook email client, you can drive that with a VBScript script - not strictly a batch file but VBScript is generally part of Windows. Of course you can use a batch file to call the vbscript file with the right parameters.
(I've used this technique to schedule things in Outlook - schedule sending an email with a particular subject at a particular time.)
'SendMail.vbs
option explicit
' Script for sending mails to myself, with given subject and optionally file contents for body
' Note this only works with particular Schedule service settings, i.e.,
' it has to log on as me and have access to the Desktop
dim fso, f, oMailItem, oOlApp
' Create the mail
Set oOlApp = CreateObject("Outlook.Application")
Set oMailItem = oOlApp.CreateItem(0) '0 = olMailItem
oMailItem.Subject = WScript.Arguments(0)
oMailItem.Recipients.Add ("receiver.name#somemailserver.com")
if WScript.Arguments.Count > 1 then
Set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(WScript.Arguments(1), 1 )
oMailItem.Body = f.ReadAll
f.Close
end if
oMailItem.Send
set f = nothing
set oMailItem = nothing
set oOlApp = nothing
Call it with a command like
sendmail.vbs My_Subject_Line contents_file.txt