Skip to main content

Updating Drivers from Microsoft Update

· One min read

Creating Fields

Creating custom fields in NinjaOne

To create a custom field at the device level in NinjaOne go to Administration > Devices and select either Role Custom Fields or Global Custom Fields then select Add.

  • Role Custom Fields are custom fields that are specific to a device role.
  • Global Custom Fields are custom fields that are applicable to all devices.

Make sure you add the fields to the roles you want to use them in at Administration > Devices > Roles.

To create a custom field at the organisation level in NinjaOne go to Administration > Apps > Documentation, enable the Documentation feature if you haven't already. If you have then select Add.

We're adding three role custom fields for devices with the Windows Laptop role:

Field NameField TypeDescription
Driver Update: Reboot RequiredCheckboxWhether the latest driver update run requires a reboot to finalise.
Driver Update: Last RunDate/TimeThe date and time the driver update script last ran successfully.
Driver Update: Number Installed on Last RunIntegerThe number of driver updates installed on last script run.

The Script

[CmdletBinding()]
param ()
try {
# Create a new update service manager COM object.
$UpdateService = New-Object -ComObject Microsoft.Update.ServiceManager
# If the Microsoft Update service is not enabled, enable it.
$MicrosoftUpdateService = $UpdateService.Services | Where-Object { $_.ServiceId -eq '7971f918-a847-4430-9279-4a52d1efe18d' }
if (!$MicrosoftUpdateService) {
$UpdateService.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '')
}
# Create a new update session COM object.
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
# Create a new update searcher in the update session.
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
# Configure the update searcher to search for driver updates from Microsoft Update.
## Set the update searcher
$UpdateSearcher.ServiceID = '7971f918-a847-4430-9279-4a52d1efe18d'
## Set the update searcher to search for per-machine updates only.
$UpdateSearcher.SearchScope = 1
## Set the update searcher to search non-Microsoft sources only (no WSUS, no Windows Update) so Microsoft Update and Manufacturers only.
$UpdateSearcher.ServerSelection = 3
# Set our search criteria to only search for driver updates.
$SearchCriteria = "IsInstalled=0 and Type='Driver'"
# Search for driver updates.
Write-Verbose 'Searching for driver updates...'
$UpdateSearchResult = $UpdateSearcher.Search($SearchCriteria)
$UpdatesAvailable = $UpdateSearchResult.Updates
# If no updates are available, output a message and exit.
if (($UpdatesAvailable.Count -eq 0) -or ([string]::IsNullOrEmpty($UpdatesAvailable))) {
Write-Warning 'No driver updates are available.'
Ninja-Property-Set driverUpdateRebootRequired 0 # Adjust for RMM
Ninja-Property-Set driverUpdateLastRun (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss') # Adjust for RMM
Ninja-Property-Set driverUpdateNumberInstalledOnLastRun 0 # Adjust for RMM
exit 0
} else {
Write-Verbose "Found $($UpdatesAvailable.Count) driver updates."
# Output available updates.
$UpdatesAvailable | Select-Object -Property Title, DriverModel, DriverVerDate, DriverClass, DriverManufacturer | Format-Table
# Create a new update collection to hold the updates we want to download.
$UpdatesToDownload = New-Object -ComObject Microsoft.Update.UpdateColl
$UpdatesAvailable | ForEach-Object {
# Add the update to the update collection.
$UpdatesToDownload.Add($_) | Out-Null
}
# If there are updates to download, download them.
if (($UpdatesToDownload.count -gt 0) -or (![string]::IsNullOrEmpty($UpdatesToDownload))) {
# Create a fresh session to download and install updates.
$UpdaterSession = New-Object -ComObject Microsoft.Update.Session
$UpdateDownloader = $UpdaterSession.CreateUpdateDownloader()
# Add the updates to the downloader.
$UpdateDownloader.Updates = $UpdatesToDownload
# Download the updates.
Write-Verbose 'Downloading driver updates...'
$UpdateDownloader.Download()
}
# Create a new update collection to hold the updates we want to install.
$UpdatesToInstall = New-Object -ComObject Microsoft.Update.UpdateColl
# Add downloaded updates to the update collection.
$UpdatesToDownload | ForEach-Object {
if ($_.IsDownloaded) {
# Add the update to the update collection if it has been downloaded.
$UpdatesToInstall.Add($_) | Out-Null
}
}
# If there are updates to install, install them.
if (($UpdatesToInstall.count -gt 0) -or (![string]::IsNullOrEmpty($UpdatesToInstall))) {
# Create an update installer.
$UpdateInstaller = $UpdaterSession.CreateUpdateInstaller()
# Add the updates to the installer.
$UpdateInstaller.Updates = $UpdatesToInstall
# Install the updates.
Write-Verbose 'Installing driver updates...'
$InstallationResult = $UpdateInstaller.Install()
# If we need to reboot flag that information.
if ($InstallationResult.RebootRequired) {
Write-Warning 'Reboot required to complete driver updates.'
Ninja-Property-Set driverUpdateRebootRequired 1 # Adjust for RMM
}

# Output the results of the installation.
## Result codes: 0 = Not Started, 1 = In Progress, 2 = Succeeded, 3 = Succeeded with Errors, 4 = Failed, 5 = Aborted
## We consider 1, 2, and 3 to be successful here.
if (($InstallationResult.ResultCode -eq 1) -or ($InstallationResult.ResultCode -eq 2) -or ($InstallationResult.ResultCode -eq 3)) {
Write-Verbose 'Driver updates installed successfully.'
Ninja-Property-Set driverUpdateRebootRequired 0 # Adjust for RMM
Ninja-Property-Set driverUpdateLastRun (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss') # Adjust for RMM
Ninja-Property-Set driverUpdateNumberInstalledOnLastRun $UpdatesToInstall.Count # Adjust for RMM
} else {
Write-Warning "Driver updates failed to install. Result code: $($InstallationResult.ResultCode.ToString())"
exit 1
}
}
}
} catch {
Write-Error $_.Exception.Message
exit 1
}

The Results

Driver Update Related Custom Fields

You can set this up to run on a schedule - we run this script immediately on machine onboarding and then every 7 days on a Tuesday. This doesn't always have anything to do as our Windows Update run usually handles these updates, but it's a good way to ensure that we're always up to date with the latest drivers from Microsoft Update.