Running Microsoft Office as SYSTEM account

If you have ever written some code that uses one of the Microsoft Office products and intended to run it on a server without user interaction using the builtin SYSTEM account you may very well have discovered that it just does not work and troubleshooting why is difficult.

According to this extremely helpful Microsoft article doing this is basically considered a no no. What would have been even better is if they said ‘hey, we don’t support this but here is how to make it work’, especially considering how ridiculously simple the solution is.

Credit to this post that finally gave me the answer which is to create the SYSTEM accounts Desktop folder.

32 bit Office:
C:\Windows\System32\config\systemprofile\Desktop

64 bit Office:
C:\Windows\SysWOW64\config\systemprofile\Desktop

That’s it!

Note: This has been tested on Office 2010 and Office 2013

A little more information for those who are interested and some basic troubleshooting for those who do run applications as SYSTEM in general.

Firstly if you are troubleshooting running applications as SYSTEM go and grab PSEXEC.EXE from here. Put the PSEXEC.EXE file somewhere on your machine that you are testing from and then launch either a command prompt or PowerShell and change directory to the path where you placed the EXE. Now we can run powershell.exe (or cmd.exe if you prefer) as SYSTEM by using the command,

psexec.exe /i /s powershell.exe

This will load up another window which is running under the SYSTEM credentials which we can confirm in PowerShell with the following command,

[Environment]::UserName

which should give us the response,

PS C:\> [Environment]::UserName
SYSTEM

From here you can run, for example, Excel (change directory to the office folder and run using the command ‘.\EXCEL.EXE’ in PowerShell).

Using Office 2010 in this way will show you that Excel will launch and you can create a new document as normal but then when you click on the save button, or even ‘save as’, the application simply does nothing without that ‘Desktop’ folder created. Using Office 2013 in this same way shows that Microsoft have done some improvements as the application actually creates the missing folder and continues to work perfectly fine. Unfortunately the folder is still required to be created manually if you simply try to run your code as SYSTEM.

Using PSEXEC.EXE in this way is also required if you plan on generating any password hashes for PowerShell code that will run under the SYSTEM account. But more on that in another post.

Advertisements

Reading emails from Office365 account using PowerShell

Welcome fellow Sys Admins.

After spending all day trawling through the internet for a way to easily read through the mail in a O365 mailbox using PowerShell and gathering code from all over the place to do it I thought it would be good to upload my code to for everyone to share and hopefully you end up here at the start of your quest and not at the end 🙂

This code will allow you to read email directly from O365 without the need to install Outlook. All you need is the .dll file from the Microsoft Exchange Web Services Managed API 2.2 which you can download here. Ensure that you update the file path to the dll file if it is different to what is defined in the code.

Credit goes to the following post from ‘Steve Goodman’s Exchange & Office 365 Blog’ for the majority of the code,
How to export Email Headers from Exchange using Powershell

Credit also to Exchange Managed API autodiscover with Powershell resolving the issue with the security error when trying to autodiscover to O365 by adding the $TestUrlCallback function. While you could simply just call autodiscover with the second variable as $true you are basically trusting any redirections that may happen.

# Written by Ben Penney https://sysadminben.wordpress.com $mail="username@domain.com" $password="password" # Set the path to your copy of EWS Managed API $dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll" # Load the Assemply [void][Reflection.Assembly]::LoadFile($dllpath) # Create a new Exchange service object $service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService #These are your O365 credentials $Service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($mail,$password) # this TestUrlCallback is purely a security check $TestUrlCallback = { param ([string] $url) if ($url -eq "https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml") {$true} else {$false} } # Autodiscover using the mail address set above $service.AutodiscoverUrl($mail,$TestUrlCallback) # create Property Set to include body and header of email $PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) # set email body to text $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text; # Set how many emails we want to read at a time $numOfEmailsToRead = 100 # Index to keep track of where we are up to. Set to 0 initially. $index = 0 # Do/while loop for paging through the folder do { # Set what we want to retrieve from the folder. This will grab the first $pagesize emails $view = New-Object Microsoft.Exchange.WebServices.Data.ItemView($numOfEmailsToRead,$index) # Retrieve the data from the folder $findResults = $service.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$view) foreach ($item in $findResults.Items) { # load the additional properties for the item $item.Load($propertySet) # Output the results "From: $($item.From.Name)" "Subject: $($item.Subject)" "Body: $($Item.Body.Text)" "References: $($item.References)" "InternetMessageID: $($item.InternetMessageID)" "InternetMessageHeaders:" # Display the headers - using a little foreach loop $item.InternetMessageHeaders|foreach{"$($_.Name): $($_.Value)"} "" } # Increment $index to next block of emails $index += $numOfEmailsToRead } while ($findResults.MoreAvailable) # Do/While there are more emails to retrieve

Update: I just found another blog where someone has done similar with some additional coding for filtering mail based on subject and read status,
Check/Read Messages Exchange/Office365 Inbox with Powershell
So check that out as well!