Skip to main content

Hello. I wanted to get assistance on correcting a office 365 installation worklet. This was previously working and now it is receiving the following error.

 

You cannot call a method on a null-valued expression.
At C:\Program Files (x86)\Automox\execDir519974115\execcmd211621094.ps1:225 char:5
+     $postVer = $64Config.getvalue("VersionToReport")
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) n], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 

COMMAND TIMED OUT.

 

The script

<#
.SYNOPSIS
    Install M365 Apps - Evaluation Script
    OS Support: Windows 8.1 and above
    Powershell: 3.0 and above
    Run Type: Evaluation or OnDemand
.DESCRIPTION
    This Worklet is designed to grant an Admin the ability to install Microsoft 365 Apps (Office) on devices that do not
    currently have them installed.

    While it is possible to remove legacy MSI installations (Office 2016/etc) as part of the ODT, the default configuration
    of this worklet does not support it. Please feel free to modify this script to suite your enviromental needs.

    Office Deployment Tool: You will need to upload the most recent Office Deployment Tool (Setup.exe) when creating this
    Worklet policy. The ODT can be found at https://aka.ms/ODT

    Usage:
    This evaluation script requires no modification and simply looks for the "VersionToReport" value that is present in all
    M365 Apps installations.
.LINK
    https://www.microsoft.com/en-us/download/details.aspx?id=49117
.NOTES
    Author: eliles
    Date: June 1, 2021
#>
# Locating Office config and version
if(0System.Environment]::Is64BitOperatingSystem)
{
    $64Hklm = tMicrosoft.Win32.RegistryKey]::OpenBaseKey(rMicrosoft.Win32.RegistryHive]::LocalMachine, iMicrosoft.Win32.RegistryView]::Registry64)
    $64Config = $64Hklm.OpenSubKey("SOFTWARE\Microsoft\Office\ClickToRun\Configuration")
    if($64Config)
    {
        $installedVersion = $64Config.getvalue("VersionToReport")
    }
    $64Hklm.close()
}
else
{
    $86Config = "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration"
    $installedVersion = (Get-ItemProperty -Path $86Config -Name "VersionToReport" -ErrorAction SilentlyContinue).VersionToReport
}

# Checks for VersionToReport
if($installedVersion)
{
    Write-Output "Compliant - Microsoft 365 apps are already installed"
    Exit 0
}
Write-Output "Microsoft 365 Apps not found - Flagging for remediation"
Exit 1

 

<#
.SYNOPSIS
    Install M365 Apps - Remediation Script
    OS Support: Windows 8.1 and above
    Powershell: 3.0 and above
    Run Type: Evaluation or OnDemand
.DESCRIPTION
    This Worklet is designed to grant an Admin the ability to install Microsoft 365 Apps (Office) on devices that do not
    currently have them installed. Devices will need firewall access to the publicly available Microsoft Office CDN's. By
    default the installation language will attempt to match the OS. If the OS language is not present on the CDN, a fallback
    of EN-US will be used. This can be changed by modifying the $fallbackLang variable near the top of the code portion of
    the script.

    While it is possible to remove legacy MSI installations (Office 2016/etc) as part of the ODT, the default configuration
    of this worklet does not support it. Please feel free to modify this script to suite your enviromental needs.

    Office Deployment Tool: You will need to upload the most recent Office Deployment Tool (Setup.exe) when creating this
    Worklet policy. Only the Setup.exe is needed, as the worklet will automatically generate the configuration XML upon
    remediation. The ODT can be found at https://aka.ms/ODT

    Usage:
    This remediation script uses several variables to define the configuration and behavior of the M365 Apps install.

    $channel: This is the channel that will be installed on the device. If a policy key is already present on a device,
    it will default to the channel defined in the policy and output this change in the Activity Log.

    The following values are supported:

        Current: Provides users with new Office features as soon as they are ready, but on no set schedule.
        FirstReleaseCurrent: Preview release of Current channel.
        MonthlyEnterprise: Provides users with new Office features only once a month and on a predictable schedule.
        Deferred: For select devices in your organization, where extensive testing is needed before deploying new Office features.
        FirstReleaseDeferred: Preview release of Deferred channel.
        InsiderFast: Beta release channel. Frequent updates. Stable builds are sent to FirstReleaseCurrent.

    $excludeApps: This defines an application, or list of applications to be excluded from the installation. Each
    app should be enclosed in single quotes and separated by a comma. For a full list of App ID's that are supported visit
    https://docs.microsoft.com/en-us/deployoffice/office-deployment-tool-configuration-options

    $visibility: This defines the visibility of the M365 Apps installer.

        FULL: This is the default setting and will display the progress bar to the user, but does not require interaction.
        NONE: This will make the installation completely silent to the user.

    $bitness: This specifies the archetecture of the Office installation. Use '32' or '64'. On 32bit devices, this will default to 32.
.EXAMPLE
    $channel = 'Current'
    $excludeApps = 'Groove','Lync','Teams','OneDrive'
    $visibility = 'FULL'
    $bitness = '64'
.LINK
    https://www.microsoft.com/en-us/download/details.aspx?id=49117
.NOTES
    Author: eliles
    Date: June 2 2021
#>
######## Make changes within this block ########
$channel = ''
$excludeApps = ''
$visibility = ''
$bitness = ''
################################################

# Predefined Variables that could be modified if needed
$prodID = 'O365ProPlusRetail' #Office ProductID to install
$runAsaccount = 'USERS' # Account used to run scheduled task USERS or SYSTEM preferred
$fallbackLang = 'EN-US' # Fallback Language to use if "MatchOS" is not available on CDN

# Define Script directory
$scriptDir = Split-Path $Script:MyInvocation.MyCommand.Path -Parent

# Capturing Office config
if(eSystem.Environment]::Is64BitOperatingSystem)
{
    # Opening 64bit config
    $64Hklm = #Microsoft.Win32.RegistryKey]::OpenBaseKey(rMicrosoft.Win32.RegistryHive]::LocalMachine, PMicrosoft.Win32.RegistryView]::Registry64)
    $64Config = $64Hklm.OpenSubKey("SOFTWARE\Microsoft\Office\ClickToRun\Configuration")

    # Config fail-safe
    if($64Config)
    {
        $64Hklm.close()
        Write-Output "Compliant - Microsoft 365 apps are already installed"
        Exit 0
    }
}
else
{
    # x86 Config path
    $86Config = "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration"

    # Locate x86 config
    if(Test-Path $86Config)
    {
        Write-Output "Compliant - Microsoft 365 apps are already installed"
        Exit 0
    }
}

# Check for UpdateBranch policy
$curPolicy = (Get-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Office\16.0\Common\OfficeUpdate -Name UpdateBranch -ErrorAction SilentlyContinue).UpdateBranch

# Check for policy key and set for XML
if($curPolicy)
{
    Write-Output "Policy Found: Reverting to channel $curPolicy"
    $xmlChannel = $curPolicy
}
else
{
    $xmlChannel = $channel
}

# x86 bitness override
if(!(nSystem.Environment]::Is64BitOperatingSystem))
{
    $bitness = '32'
}

# Create XML file and Add root Configuration Element
System.XML.XMLDocument]$ConfigFile = New-Object System.XML.XMLDocument
>System.XML.XMLElement]$ConfigurationRoot=$ConfigFile.CreateElement("Configuration")
$ConfigFile.appendChild($ConfigurationRoot) | Out-Null

# Add "Add" Element and set attributes
pSystem.XML.XMLElement]$addElement=$configFile.CreateElement("Add")
$configurationRoot.appendChild($addElement) | Out-Null
$addElement.SetAttribute("OfficeClientEdition","$bitness") | Out-Null
$addElement.SetAttribute("Channel","$xmlChannel") | Out-Null

# Add the Product Element under Add and set the ID
System.XML.XMLElement]$productElement=$configFile.CreateElement("Product")
$addElement.appendChild($productElement) | Out-Null
$productElement.SetAttribute("ID","$prodID") | Out-Null

# Add the Language Element under Product and set the IDs
NSystem.XML.XMLElement]$languageElement=$configFile.CreateElement("Language")
$productElement.appendChild($languageElement) | Out-Null
$languageElement.SetAttribute("ID","MatchOS") | Out-Null
$languageElement.SetAttribute("Fallback","$fallbackLang") | Out-Null

# Add the ExcludeApp Element under Product and set the IDs
if($excludeApps)
{
    foreach($app in $excludeApps)
    {
        (System.XML.XMLElement]$exAppelement=$configFile.CreateElement("ExcludeApp")
        $productElement.appendChild($exAppelement) | Out-Null
        $exAppelement.SetAttribute("ID","$app") | Out-Null
    }
}

# Add the Updates Element under Configuration
pSystem.XML.XMLElement]$updElement=$configFile.CreateElement("Updates")
$configurationRoot.appendChild($updElement) | Out-Null
$updElement.SetAttribute("Enabled","TRUE") | Out-Null

# Add the Display Element under Configuration
tSystem.XML.XMLElement]$dispElement=$configFile.CreateElement("Display")
$configurationRoot.appendChild($dispElement) | Out-Null
$dispElement.SetAttribute("Level","$visibility") | Out-Null
$dispElement.SetAttribute("AcceptEULA","TRUE") | Out-Null

# Saves config to script directory
$configFile.Save("$scriptDir\update.xml") | Out-Null
$xmlpath = "$scriptDir\update.xml"

# Creates scheduled task to run in USER context and deletes task when done
$ShedService = New-Object -comobject 'Schedule.Service'
$ShedService.Connect()

$Task = $ShedService.NewTask(0)
$Task.RegistrationInfo.Description = "Install M365 Apps"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$task.Settings.DisallowStartIfOnBatteries = $false
$Task.Principal.RunLevel = 1

$trigger = $task.triggers.Create(7)
$trigger.Enabled = $true

$action = $Task.Actions.Create(0)
$action.Path = "$scriptDir\setup.exe"
$action.Arguments = "/configure $xmlpath"

$taskFolder = $ShedService.GetFolder("\")

# Initializing Install
$taskFolder.RegisterTaskDefinition("Install M365 Apps", $Task , 6, "$runAsaccount", $null, 4) | Out-Null

# Check status until task has completed
DO
{
(Get-ScheduledTask -TaskName 'Install M365 Apps').State | Out-Null
}
Until ((Get-ScheduledTask -TaskName 'Install M365 Apps').State -eq "Ready")
Unregister-ScheduledTask 'Install M365 Apps' -Confirm:$false

# Capture post-install info
if($System.Environment]::Is64BitOperatingSystem)
{
    $64Hklm = DMicrosoft.Win32.RegistryKey]::OpenBaseKey(sMicrosoft.Win32.RegistryHive]::LocalMachine, rMicrosoft.Win32.RegistryView]::Registry64)
    $64Config = $64Hklm.OpenSubKey("SOFTWARE\Microsoft\Office\ClickToRun\Configuration")
    $postVer = $64Config.getvalue("VersionToReport")
    $64Hklm.Close()
}
else
{
    $postVer = (Get-ItemProperty -Path $86Config -Name "VersionToReport").VersionToReport
}

# Installation eval
if($postVer)
{
    Write-Output "Successfully Installed M365 Apps $postVer"
    Exit 0
}
Write-Output "ERROR: Installation Failed - See logs at $env:WINDIR\Temp for more information"
Exit 1

 

Hi @justlooking!

 

A fix has just been released for this worklet.

 

Please grab the new copy here: Windows - Software Lifecycle - Install M365 Apps and replace your existing worklet with it.

 

As noted in the updated instructions, be sure to download the ODT tool from the link provided in the worklet’s help comments.  You’ll want to run the ODT locally on a device to extract the setup.exe file. You’ll then attach the extracted file to the Worklet’s payload.


Additionally, you’ll want to make sure you complete these variables with the Remediation Code:

$channel = ''

$excludeApps = ''

$visibility = ''

$bitness = ''

 

Let us know if you are still experiencing any issues or have any questions about implementation.

 

Have a great day!


Hi @JohnG-Automox 

 

Thank you so much for providing this new worklet and guiding me on what input I need to get it to work.

It is working perfectly!


Hey I am trying to use this worklet, but not having any luck.  I’ve downloaded the ODT file and just stuck now.  Do I need to configure or download with a XML file?  I’d like the whole office suite and onedrive and Teams.

Any help would be highly appreciated.


Hello, @JohnG-Automox this worklet appears to be not working as of recently.

 

Not sure what changed but a few of the support team have contacted me regarding the worklet showing command time out in the log results after running the script.

 

Can you advise on anything?


Hi @justlooking !

I just tested this worklet and was able to install M365 office successfully on my device.

 

You’ll want to ensure that you download and run the ODT tool so it extracts the file. You’ll then need to upload the extracted setup.exe file to the payload of the worklet.

After running the ODT it’ll extract these files.

 

Upload the extracted setup.exe file to the worklet’s payload.


Additionally, you’ll need to configure the parameters on lines 84-87 in the remediation code. 
 

Example,

######## Make changes within this block ########
$channel = 'Current'
$excludeApps = 'Groove','Lync','Teams','OneDrive'
$visibility = 'NONE'
$bitness = '64'


If you are still having issues, please open a case with our support team can investigate further: https://help.automox.com/

 

Thanks!


Thank you for the response @JohnG-Automox 

 

After some troubleshooting, I figured out the issue. I renamed the setup.exe file with a capital S and it appears to work fine now. I did this after reading the comments in the worklet instructions to have Setup.exe. The original setup.exe final with all lowercase wasn’t working for me.


Ah got it!

 

You are correct.  setup.exe is hardcoded in the worklet’s remediation code (line 209), so it would have to match that name exactly. 

 

Nice catch on that, and glad you were able to figure it out! 😎


Reply