简体   繁体   中英

Create email from PowerShell using Task Scheduler (Runtime Error 429)

I created several scripts to send emails after performing certain analysis. This has worked previously. Now a few of the scripts fail and give the following error message:

run-time error '429':
ActiveX component can't create object

It then refers to the Outlook Object line of code as the error.

The script runs when I exit MS Outlook and bugs out if Outlook is running. I use a Task Scheduler to run this and Outlook is usually going to be running.

Private Sub Send_Ratings_Email()

    Dim OutApp As Object, OutMail As Object
    Dim rng As Range
    Dim StrBody As String
    StrBody = "Please find  Maturities for the Current Week Below: "

    Application.ScreenUpdating = False
    On Error Resume Next
    Set OutApp = GetObject(, "Outlook.Application")
    On Error GoTo 0
    If OutApp Is Nothing Then Set OutApp = GetObject("Outlook.Application")

    On Error GoTo cleanup
 
    Set OutMail = OutApp.CreateItem(0)
    On Error Resume Next
            
    Call AddAzureLabel(OutMail, "Restricted - Internal")
    With OutMail
        .To = " example.com"
        .Subject = "Weekly Maturities - W/C " & Format(Now, "dd-mmm-yy")
        .HTMLBody = StrBody & RangetoHTML(rng)
        .Display  'Or use .Send
    End With
    On Error GoTo 0
    Set OutMail = Nothing

cleanup:
    Set OutApp = Nothing
    Application.ScreenUpdating = True

Powershell Script works when manually run.

You are creating an instance of outlook if its running it won't work, instead check if it's already running and get the running app or create one if its not:

On Error Resume Next
Set OutApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If OutApp Is Nothing Then Set OutApp = CreateObject("Outlook.Application")

在您的任务计划程序任务中取消勾选“以最高权限运行”

Adding this as an answer for now, but really just trying to debug in a way that won't fit in comments. Similar to the other answer, but the idea is to use this to create a test case and let's see if we can get it to work in your Task Scheduler>Powershell case.

Have your PS run the foo or foo2 procedure here, and I've encapsulated the Outlook instantiation as a standalone function to try and keep things clean and isolate the error.

Option Explicit

Sub foo()
Dim olApp As Object
Set olApp = GetApplication("Outlook.Application")

End Sub

Sub foo2()
Dim olApp As Object
Set olApp = GetApplication2("Outlook.Application")
End Sub

Function GetApplication2(className As String) As Object
' function to encapsulate the instantiation of an application object
Dim theApp As Object
On Error Resume Next
Set theApp = CreateObject(className)
If theApp Is Nothing Then
    MsgBox "Unable to get a handle on " & className
Else
    MsgBox "Successfully got a handle on " & className & ", returning to caller"
End If
Set GetApplication2 = theApp
End Function


Function GetApplication(className As String) As Object
' function to encapsulate the instantiation of an application object
Dim theApp As Object
On Error Resume Next
Set theApp = GetObject(, className)
If Err.Number <> 0 Then
    MsgBox "Unable to Get" & className & ", attempting to CreateObject"
    Set theApp = CreateObject(className)
End If

If theApp Is Nothing Then
    Err.Raise Err.Number, Err.Source, "Unable to Get or Create the " & className & "!"
    Set GetApplication = Nothing
End If

MsgBox "Successfully got a handle on Outlook Application, returning to caller"

Set GetApplication = theApp

End Function

Which I'm running from PS like:

$excel = new-object -comobject excel.application
$file = "C:\debug\ps-excel.xlsm"
$wb = $excel.workbooks.open($file)
$excel.Run("Module1.foo")

And:

$excel.Run("Module1.foo2")

In the foo procedure, GetObject raises an error but it's not a 429 error, and control passes to CreateObject which successfully instantiates the application. So, unfortunately I'm not able to reproduce the error under any combination of foo / foo2 and whether Outlooks is already open does not seem to matter, either.

Here's a somewhat hack-y potential solution

So, this is a bit hack-y because I don't think it solves the root cause (and because I can't replicate your error, it might not actually solve anything) but it's worth a shot, as you note:

Important to note that the script runs when I exit MS Outlook and bugs out if Outlook is already running

My idea is to just modify your PS to check for running instance of Outlook and close it via stop-process Cmdlet.

try {
    stop-process -Name "outlook" -ErrorAction Stop
    Write-Host "Stopped the running instance of Outlook Application"
    } catch { 
    Write-Host "outlook was not already running"
    } 
    
$excel = new-object -comobject excel.application
$file = "C:\debug\ps-excel.xlsm"
$wb = $excel.workbooks.open($file)
$excel.run("Module1.foo")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM