Deploying the ‘Upgrade Readiness Deployment Script’ via InTune

Microsoft has released the “Upgrade Readiness Deployment Script” (URDS), including a method for deployment with SCCM.

Upgrade Readiness is offered as a solution in the Microsoft Operations Management Suite (OMS), a collection of cloud based services for managing your on-premises and cloud environments. For more information about OMS, see Operations Management Suite overview.

Unfortunately, they do not provide instructions how to deploy the script using Azure InTune, the MDM solution we use.

Luckily, with the use of Advanced Installer (AI) and a short PowerShell script, I have been able to deploy via InTune 🙂

As I want to use the free version of AI, two phases are needed for deployment; the Enterprise edition of AI supports the creation of Scheduled Tasks natively, that edition costs € 1500 at time of writing.

The first phase, using AI, deploys the URDS to the target machine; the powershell script then checks if the deployment has taken place, and -if so- creates a Scheduled Task to run ‘RunConfig.bat’ on a weekly basis.

Deploying the script

Creating the MSI

Start Advanced Installer and create a ‘Simple’ installer project (these are free)

Change the Product Details -> Name to your liking and change the Version to match the version of the script you are deploying

Drag ‘n drop the files from either the ‘Production’ or ‘Pilot’ folders from the Microsoft download in the ‘Application Folder’.
Don’t forget to edit the ‘RunConfig.bat’ with the details for your tenant.

Once you’ve added the files, save the project for future use (for example when you need to deploy a new version)

Build the MSI

Upload it to Azure InTune as a Line of Business MSI and set deployment targets

Create the Powershell script


$VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"
$TaskName = "Upgrade Readiness check"
$Execute = "C:\Program Files\Microsoft\Upgrade Readiness\RunConfig.bat"
$LogPath="C:\ProgramData\Scripts\"
$LogFile = Join-Path $LogPath "UpgradeReadiness.log"

Function Write-Log {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$False)]
[ValidateSet("INFO","WARN","ERROR","FATAL","DEBUG")]
[String]
$Level = "INFO",

[Parameter(Mandatory=$True)]
[string]
$Message,

[Parameter(Mandatory=$False)]
[string]
$LogFile
)

$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
$Line = "$Stamp $Level $Message"
If($LogFile) {
Add-Content $LogFile -Value $Line
Write-Output $Line
}
Else {
Write-Output $Line
}
}

If(!(Test-Path $LogPath)){
New-Item -ItemType Directory -Path $LogPath
}
IF (Test-Path($Execute)){
Write-Log -LogFile $LogFile -Message "Script Exists"
# Get an existing local task if it exists
If ($Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue -Verbose ) {

Write-Log -LogFile $LogFile -Message "$TaskName task exists."
# If the task Action differs from what we have above, update the values and save the task
If (!( ($Task.Actions[0].Execute -eq $Execute) )) {
Write-Log -LogFile $LogFile -Message "Updating scheduled task."
$Task.Actions[0].Execute = $Execute
Write-Log -LogFile $LogFile -Message $Task.Actions[0] | Out-String
try{
$Task | Set-ScheduledTask -Verbose -ErrorAction Stop
} catch {
Write-Log -LogFile $LogFile -Level FATAL -Message "Exception caught"
Write-Log -LogFile $LogFile -Level FATAL -Message $Error | Out-String
Exit 1
}
} Else {
Write-Log -LogFile $LogFile -Message "Existing task action is OK, no change required."
exit 0
}

} Else {

Write-Log -LogFile $LogFile -Message "Creating $TaskName scheduled task."
# Build a new task object
$action = New-ScheduledTaskAction -Execute $Execute -Verbose
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 03:00 -RandomDelay (New-TimeSpan -Minutes 1) -Verbose
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -Hidden -DontStopIfGoingOnBatteries -Compatibility Win8 -Verbose
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -Verbose
$newTask = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Verbose

# No task object exists, so register the new task
try{
Register-ScheduledTask -InputObject $newTask -TaskName $TaskName -Verbose -ErrorAction Stop
} catch {
Write-Log -LogFile $LogFile -Level FATAL -Message "Exception caught"
Write-Log -LogFile $LogFile -Level FATAL -Message $Error | Out-String
exit 1
}
}
} else {
Write-Log -LogFile $LogFile -Message "script does not exist yet"
#exit with error
exit 1
}

Upload the script to Azure InTune and set the same deployment target as for the MSI
Wait for the deployment of the MSI and PowerShell to complete
Wait for the results to appear in the Upgrade Readiness solution in the Operations Management Suite

Upgrade Readiness in OMS

Once the script has run and the day the scheduled task was set to run has passed, you can go to the Upgrade Readiness ‘Solution Settings’ to get an indication of how many devices have submitted their status and any script errors that may have been encountered.

As you can tell from the screenshot, the number of devices the script was deployed to does not yet match the number of Computers reported by the report. The scheduled task has not run yet for the majority of devices, a situation which should remedy itself in a couple of days!

Thanks to the original authors:
Scheduled Task Powershell snippet is an adapted version from this blog post: “Folder Redirection to OneDrive on Windows 10 with Intune
Write-Log is borrowed from this answer on SO.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.