Office 365 - Critical Update Deployment Help

Hi,

Having received an email this morning stating Microsoft are releasing a critical patch for Outlook for Windows, I wondered how other MSPs are rolling out fixes like this?

I have been search this forum and the web to find an automated way to do this via Syncro, Chocolatey or PowerShell but am finding nothing works.

I am aware I can instruct customer to use the Click to Run feature within Outlook to prompt for the upgrade but it doesn’t look great. If I can say Microsoft have released a critical security update but if you are a managed customer this has already be done. It not only looks good but may encourage other customers to see the value of having our RMM service.

Any help would be very much appreciated.

1 Like

I haven’t dug into the Outlook issue yet but we have a script to force Office Click to Run versions to update. Take note that the “forceappshutdown=true” option will close any open Office apps. Either run it after-hours or change it to false.

# Check if running as System
$sid = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
if ($sid -ne "S-1-5-18") {
    Write-Host "This script needs to be run as System."
    Exit 1
}

$updateExePath = "$($env:ProgramFiles)\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"

# Exit if execuatable not found
$pathExists = Test-Path -Path $updateExePath -PathType Leaf
if(!($pathExists)) {
    Write-Host "Office C2R not found on this system."
    Exit 0
}

# Update Office using ClickToRun
try {
    Write-Host "Updating Office..."
    $result = Start-Process -FilePath $updateExePath -ArgumentList "/update user displaylevel=false forceappshutdown=true" -PassThru -Wait
    if($result.ExitCode -eq 0) {
        Write-Host "Office was sucessfully updated."
    } else {
        Write-Host "Office was not updated successfully."
        Exit 1
    }
} catch {
    Write-Host "An error occurred while updating Office."
    Exit 1
}
1 Like

Amazing, thank you very much.

I will try that shortly.

This worked amazingly, thank you very much.

FYI, C2R can be in two possible locations, so you probably want to wrap that all in a foreach something like this:

$C2RPaths = @(
        "$env:SystemDrive\Program Files (x86)\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
        "$env:SystemDrive\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
)
$C2RPaths | ForEach-Object {
    if (Test-Path -Path $_) {
yadayada
}

Good catch! I forgot about 32-bit Office on 64-bit Windows. Here’s an updated version for anyone that needs it.

Import-Module $env:SyncroModule

# Check if running as System
$sid = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
if ($sid -ne "S-1-5-18") {
    Write-Host "This script needs to be run as System."
    Exit 1
}

$c2rPaths =@(
    "$($env:ProgramFiles)\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
    "${env:ProgramFiles(x86)}\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
)

# Check each path to see which is correct
foreach ($c2rPath in $c2rPaths) {
    $pathExists = Test-Path -Path $c2rPath -PathType Leaf
    if ($pathExists) {
        Write-Host "Updating Office using C2R located at '$($c2rPath)'."
       
        try {           
            $result = Start-Process -FilePath $c2rPath -ArgumentList "/update user displaylevel=false forceappshutdown=true" -PassThru -Wait
        } catch {
            Write-Host "An error occurred updating Office."
            Exit 1
        }
        
        if ($result.ExitCode -eq 0) {
            Write-Host "Successfully called the Office C2R updater."
        } else {
            Write-Host "The Office C2R updater was not called successfully. Please investigate."
            Rmm-Alert -Category "Windows | Application Management" -Body "The Office C2R updater was not called successfully. Please investigate."
        }
    }
}
1 Like

We have had a few computers I cannot get this to run on. I log in and click update in the actual Office app and it updates fine, so I’m perplexed why some machines just will not take it with no apparent error.

We have found that this script needs one more variable or it doesn’t always work.

updatepromptuser=false displaylevel=false forceappshutdown=true

The updatepromptuser=false also needed to be there. And if you wanted to NOT force apps shutdown, then displaylevel=true because the user has to push OK or the update won’t work.

So to be clear, and for those of us without the Powershell skills you folks possess, the command should look like this?
$result = Start-Process -FilePath $c2rPath -ArgumentList “/update user updatepromptuser=false displaylevel=false forceappshutdown=true” -PassThru -Wait

Thanks for this. Takes a long time to learn to use Powershell, and this sort of thing really helps.

1 Like

Out of curiosity, what was happening when the “updatepromptuser=false” parameter was not included?

You’ve got to love Microsoft for it’s edge cases!

That’s a great question.

Nothing! With no logs, feedback, output from the command, or evidence otherwise.

It looks like the CTR executable runs and “does a bunch of stuff”. I THINK that the failure is when people are using Office and never do anything, something like … “times out”?

Others are reporting that this may actually work but require a PC reboot to be updated anyhow. If this is true, then my comment should just be modified to “this works AFTER a PC reboot”. However, I wasn’t testing for that. It might work great by the time everyone restarts their PC.

Thanks Neil, works like a charm.

I had chatGPT 4 read the Syncro scripting documentation and update this script with the correct error code status. Let me know what you all think.

Title: Update Microsoft Office Using RMM Tool with Error Handling

Description: This PowerShell script is designed to update Microsoft Office installations using the Click-to-Run (C2R) technology via a Remote Monitoring and Management (RMM) tool, specifically Syncro. The script first checks if it is running as System, as this is required for the update process. If not running as System, the script exits with an error code of 1. It then searches for the OfficeC2RClient.exe file, which is responsible for handling C2R updates, in two possible locations (both 32-bit and 64-bit Program Files directories).

The script iterates through each potential path and, if the file is found, attempts to update Office with the appropriate command-line arguments. These arguments ensure that the update process runs silently, without prompting the user, and forces the shutdown of Office applications to apply the updates. If the update is successful, the script outputs a success message. If an error occurs during the update process, the script outputs an error message, sends an RMM alert, and exits with an error code of 1.

The script includes a flag to track whether the update was performed or not. If the script iterates through all paths but doesn’t find the OfficeC2RClient.exe file, it outputs a message indicating that the file wasn’t found and the update couldn’t be performed. In this case, the script exits with an error code of 2. These error codes help the Syncro RMM tool correctly report the script’s status based on the provided error codes, ensuring proper monitoring and error reporting.

Import-Module $env:SyncroModule

# Check if running as System
$sid = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
if ($sid -ne "S-1-5-18") {
    Write-Host "This script needs to be run as System."
    Exit 1
}

$c2rPaths =@(
    "$($env:ProgramFiles)\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
    "${env:ProgramFiles(x86)}\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe"
)

# Add a flag to indicate whether the update was performed or not
$updatePerformed = $false

# Check each path to see which is correct
foreach ($c2rPath in $c2rPaths) {
    $pathExists = Test-Path -Path $c2rPath -PathType Leaf
    if ($pathExists) {
        Write-Host "Updating Office using C2R located at '$($c2rPath)'."

        try {           
            $result = Start-Process -FilePath $c2rPath -ArgumentList "/update user displaylevel=false updatepromptuser=false forceappshutdown=true" -PassThru -Wait
        } catch {
            Write-Host "An error occurred updating Office."
            Exit 1
        }
        
        if ($result.ExitCode -eq 0) {
            Write-Host "Successfully called the Office C2R updater."
            $updatePerformed = $true # Set the flag to true when the update is successful
        } else {
            Write-Host "The Office C2R updater was not called successfully. Please investigate."
            Rmm-Alert -Category "Windows | Application Management" -Body "The Office C2R updater was not called successfully. Please investigate."
            Exit 1
        }
    }
}

# Output a message if the OfficeC2RClient.exe file wasn't found and exit with error code 2
if (-not $updatePerformed) {
    Write-Host "OfficeC2RClient.exe was not found. Unable to update Office."
    Exit 2
}