0

I’ve written the below script. Its job is to take a (well-formatted) Excel file and, row by row, create new Contacts in Outlook.

Am running Windows 11 with everything recently updated (this morning, actually).

Within PowerShell (run as Administrator), the script runs without throwing any errors. The data outputted to the screen indicate the Excel file is being read correctly.

In Outlook, new contacts are created.

However, no data at all is being read into the contacts. Would appreciate any explanation as to what I've missed. Maybe the new contacts aren't being saved correctly to retain the data?

# Create an Excel application object
$excel = New-Object -ComObject Excel.Application

# Open the workbook
$workbook = $excel.Workbooks.Open("C:\Users\DW-ECM\Scripts\test_xl.xlsx")

# Select the first worksheet
$worksheet = $workbook.Worksheets.Item(1)

# Define the range of cells that contain the data
$range = $worksheet.UsedRange

# Creates a new instance of the Outlook application object 
# using the COM (Component Object Model) interface in PowerShell
$outlook = New-Object -ComObject Outlook.Application

Write-Host "Selected workbook: $($workbook.Name)"
Write-Host "Selected worksheet: $($worksheet.Name)"

# Loop through each row in the range
for ($i = 2; $i -le $range.Rows.Count; $i++) {
    # Get the current row
    $row = $range.Rows.Item($i)
    
    # Create a new contact object
    $contact = $outlook.CreateItem(2)

    # Set the properties of the contact object
    $contact.Account = $row.Cells.Item(1).Value2
    $contact.Business2TelephoneNumber = $row.Cells.Item(2).Value2
    $contact.BusinessAddress = $row.Cells.Item(3).Value2
    $contact.CompanyName = $row.Cells.Item(4).Value2
    $contact.Department = $row.Cells.Item(5).Value2
    $contact.Email1Address = $row.Cells.Item(6).Value2
    $contact.FirstName = $row.Cells.Item(7).Value2
    $contact.JobTitle = $row.Cells.Item(8).Value2
    $contact.LastName = $row.Cells.Item(9).Value2
    $contact.MobileTelephoneNumber = $row.Cells.Item(10).Value2
    $contact.User1 = $row.Cells.Item(11).Value2
    $contact.User2 = $row.Cells.Item(12).Value2
    
    # Save the contact to Outlook
    $contact.Save()

    Write-Host "Creating contact for $($row.Cells.Item(8).Value2) $($row.Cells.Item(10).Value2)"
}

# Close the workbook and quit Excel
$workbook.Close()
$excel.Quit()

# Save and close the Outlook instance
$outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook)
Remove-Variable outlook

# Stop the Outlook process
Stop-Process -ProcessName OUTLOOK -Force

*Edited for clarity of what I'm asking for help with and a typo.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Does it work if Outlook is already running and you get rid of the `$outlook.Quit()` line? – Dmitry Streblechenko Mar 03 '23 at 20:40
  • Also, why is your script running as an admin? – Dmitry Streblechenko Mar 03 '23 at 20:41
  • I turn Outlook off while running the script. I figure it's one less thing to cause a problem. The $outlook.Quit() line is there because when it wasn't, there were background Outlook processes left running that disabled me from restarting Outlook (after running the script). – koi_konneessa Mar 03 '23 at 20:41
  • Running PowerShell as admin - I think because I'm making changes to another app? – koi_konneessa Mar 03 '23 at 20:44
  • I wonder if I need to elevate the permissions of the script? But the script *does* create the contacts. Just doesn't get the data to flow into the new contact/save there. – koi_konneessa Mar 03 '23 at 21:19
  • I suggested running Outlook without quitting as a test - you shoudl be able to see contacts being created in the Contacts folder and their data populated. – Dmitry Streblechenko Mar 03 '23 at 21:34
  • Running as an admin is a bad idea - Outlook is a singleton, and if it is already running, your script will attach to the existing instance. And COM system will refuse to marshal calls between two apps (PS and Outlook) running in different security contexts. – Dmitry Streblechenko Mar 03 '23 at 21:36
  • Dmitry, if you put all that in a comment I'll mark the question as answered. Data is not showing in the new contacts. Thank you! – koi_konneessa Mar 03 '23 at 22:00
  • Contact is being saved in the default folder : https://learn.microsoft.com/en-us/office/vba/api/outlook.contactitem.save – jdweng Mar 04 '23 at 03:27

2 Answers2

0

Your PowerShell script, where two Office applications - Excel and Outlook are automated, looks good and I don't see anything strange there. Be aware, you can't run two instances of Outlook processes at the same time (unlike Excel), so if it was already run you will get a running instance. That means if you have Outlook already opened and running by a user (without administrative privileges) your code run form a command line (or any other shell) with admin privileges will not be able to connect to the running Outlook instance and contacts will not be added.

Within PowerShell (run as Administrator), the script runs without throwing any errors.

Make sure that you run all applications and the PowerShell script under the same security context to be able to add contacts in Outlook. That means Outlook should be closed (not running) when you run a script as an administrator.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • I do not have enough clout to vote on responses, but if I could I would upvote your response. Outlook does have to be closed/not running when running the script. – koi_konneessa Mar 05 '23 at 16:24
0

Running as an admin is a bad idea - Outlook is a singleton, and if it is already running, your script will attach to the existing instance. And COM system will refuse to marshal calls between two apps (PS and Outlook) running in different security contexts.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • 1
    This was totally the issue - a mismatch between the security contexts of the two apps was the underlying issue. Lamentably, I don't have enough clout to upvote. However, I *can* mark this as the solution, which I have done. – koi_konneessa Mar 05 '23 at 16:25