A common challenge faced by administrators transitioning from ConfigMgr (SCCM) to Intune is the perceived lack of control over application installation and reboot timing. ConfigMgr’s robust capabilities allow precise scheduling for application installations and reboots, minimizing disruption for end users. Intune, while powerful in its own right, lacks some of these granular controls, leading to concerns about application deployment timing and system reboots.
To address this gap, we’ve developed a PowerShell script that offers a simple yet effective solution for controlling application installations in Intune. While it doesn’t replicate the full feature set of ConfigMgr, this script provides a practical workaround to manage installation timing, aiming to install applications during specified maintenance windows.
This PowerShell script determines whether the current local time falls within a predefined maintenance window (10 PM to 5 AM). If it does, the script allows the application installation to proceed. If not, it creates a scheduled task to run an Intune Management Extension (IME) sync during the next maintenance window. This sync increases the chances that the computer checks for policy updates and installs the application during the maintenance window.
The script performs the following tasks:
For your reference, here’s the complete script:
<#
.SYNOPSIS
This PowerShell script determines if the current local time falls between 10 PM (22:00) and 5 AM (05:00).
.DESCRIPTION
Retrieves the current local time, extracts the hour, and checks if it is within the specified range.
Based on the result, it either proceeds with the installation or creates a scheduled task to sync Intune during the maintenance window (MW).
If the current time is within the MW, it outputs a message to install and exits with a success code.
If the current time is not within the MW, it outputs a message not to install, creates a scheduled task to run hourly from 11 PM for 5 hours syncing Intune policies, and exits with a non-success code.
Script Name: Intune_MaintenanceWindow.ps1
Author: John Marcum (PJM)
Date: 7/01/2024
Version: 1.0
.NOTES
This script can be used as a requirement rule for Intune Win32 app deployments to control installation timing based on maintenance windows.
# LEGAL DISCLAIMER
# This script is provided "as is" without any warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, or non-infringement. The entire risk as to the quality and performance of the script is with you.
# In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the script or the use or other dealings in the script.
# You should never run any script from the Internet without understanding its contents and effects. It is highly recommended that you thoroughly test the script in a safe environment before running it in production.
#>
# Get the current local time and extract the hour as integer
$currentTime = Get-Date -UFormat %R
$Hour = $currentTime.Split(":")[0]
$intHour = [int]$Hour
# Check if the current time is between 10 PM (22:00) and 5 AM (05:00)
$isInMaintenanceWindow = ($intHour -ge 22) -or ($intHour -le 5)
# Output the boolean value
Write-Host " Is in maintenance windows? $($isInMaintenanceWindow)"
# If the current time is within the maintenance window, exit with success code
if ($isInMaintenanceWindow) {
# Current time is within the maintenance window. Install the app
Write-Host "Install at $($intHour)"
Write-Output -inputobject $isInMaintenanceWindow
Exit 0
} else {
# Current time is not within the maintenance window. Do not install the app. Create a scheduled task to sync Intune during the MW in hopes of getting the app to install when we want it to.
Write-Host "Do Not install at $($intHour)"
# Define the folder and script path
$folderPath = "C:\Temp"
$scriptPath = "$folderPath\Invoke-IntuneSyncApp.ps1"
# Ensure the folder exists
if (-not (Test-Path -Path $folderPath)) {
New-Item -Path $folderPath -ItemType Directory | Out-Null
}
# Check for and delete any old script
if (Test-Path -Path $scriptPath) {
Remove-Item -Path $scriptPath -Force
}
# Create the PowerShell script
@"
$Shell = New-Object -ComObject Shell.Application
$Shell.open("intunemanagementextension://syncapp")
"@ | Set-Content -Path $scriptPath
# Define the task name
$taskName = "IntuneSyncApp"
# Check if the scheduled task already exists
$taskExists = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
if ($null -eq $taskExists) {
try {
# Define the start time
$startTime = (Get-Date).Date.AddHours(23) # 11 PM today
# Create and register the task with the EndBoundary set after creation
Register-ScheduledTask -TaskName $taskName -User "NT AUTHORITY\SYSTEM" -InputObject (
(
New-ScheduledTask -Action (
New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-noprofile -executionpolicy bypass -File `"$scriptPath`""
) -Trigger (
New-ScheduledTaskTrigger -Once -At $startTime
) -Settings (
New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 1) -DeleteExpiredTaskAfter (New-TimeSpan -Minutes 1)
)
) | % { $_.Triggers[0].EndBoundary = $startTime.AddMinutes(60).ToString('s') ; $_ } # Run through a pipe to set the end boundary of the trigger
)
Write-Host "Scheduled task '$taskName' created successfully."
} catch {
Write-Host "Failed to create scheduled task '$taskName'. Error: $_"
}
} else {
Write-Host "Scheduled task '$taskName' already exists. No action taken."
}
# Exit with false so the app does not install!
Write-Output -inputobject $isInMaintenanceWindow
Exit 0
}
To use this script as a requirement rule in an Intune Win32 app deployment, follow these steps:
While this script provides a simple and effective solution for controlling application installation timing in Intune, it does have some limitations compared to ConfigMgr:
Despite these limitations, this script offers a practical workaround for administrators looking to regain some control over application deployment timing in Intune.
Transitioning from ConfigMgr to Intune can be challenging, especially when it comes to managing maintenance windows. This PowerShell script provides a simple yet effective solution for controlling application installations during specified maintenance windows, helping to minimize disruption for end users. While it may not offer the full robustness of ConfigMgr, it serves as a valuable tool for administrators seeking to enhance their control over Intune deployments.
By incorporating this script into your Intune deployment process, you can aim for applications to be installed during designated maintenance windows, providing a more controlled and predictable deployment experience. However, it’s important to note that this solution is not foolproof and relies on systems being powered on during the maintenance windows as well as other unforeseen factors.
Cookie | Duration | Description |
---|---|---|
cookielawinfo-checkbox-analytics | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics". |
cookielawinfo-checkbox-functional | 11 months | The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional". |
cookielawinfo-checkbox-necessary | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary". |
cookielawinfo-checkbox-others | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other. |
cookielawinfo-checkbox-performance | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance". |
viewed_cookie_policy | 11 months | The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data. |