Introduction
One area I find lacking in Intune is the native ability to execute actions based on specific system events—such as triggering a task before a restart or after a user logs on. This kind of control is incredibly useful for running background tasks without disrupting the end user’s workflow. Fortunately, there’s a workaround: if the task can be handled using Task Scheduler, you can package it as a Win32 app and deploy it via Intune, then let the scheduled trigger handle the rest.
A few scenarios come to mind, but one particular use case is renaming Hybrid Azure AD Join devices after the Autopilot process completes. Michael Niehaus covered this in his blog post Renaming Autopilot-deployed Hybrid Azure AD Join devices – Out of Office Hours. Still, I wanted to experiment with my own approach—leveraging Task Scheduler to handle the renaming automatically. My goal here is to illustrate how we can still control task execution timing, even within Intune’s current limitations.
Let’s dive in.
Why Rename Devices on Shutdown?
There are scenarios where renaming at shutdown is more appropriate:
- Devices are provisioned generically and customized later.
- Post-deployment logic determines naming (e.g., user name, site, or role).
- Users move across departments and need reclassification.
Renaming during shutdown ensures the name change happens cleanly and safely, with minimal disruption.
Solution Overview
We’ll use:
- A PowerShell script to rename the device.
- Task Scheduler XML to trigger renaming on shutdown.
- Packaging scripts for installation and uninstallation.
- Intune Win32 App Packaging Tool to create a deployable
.intunewin
file.
Step 1 :Creat the Install.ps1 Script
The Install.ps1 script was inspired from Michael Niehaus
It consists of three main parts:
- Creating a log – to track the execution and status of the process.
# Start Transcript for logging script execution
try {
Write-Verbose "Starting transcript to: $logFilePath"
Start-Transcript -Path $logFilePath -Append -ErrorAction Stop
} catch {
Write-Warning "Could not start transcript to '$logFilePath'. Error: $($_.Exception.Message)"
}
#-----
#-----
# Stop Transcript
if ($Transcript) { # Check if transcript was successfully started
try {
Stop-Transcript
Write-Verbose "Transcript stopped."
} catch {
Write-Warning "Could not stop transcript. Error: $($_.Exception.Message)"
}
}
- Creating a tag – which helps with detection logic later in the process.
# Create a tag file to indicate installation status (e.g., for Intune)
try {
Write-Verbose "Creating tag file: $tagFilePath"
Set-Content -Path $tagFilePath -Value "Installed" -Force -ErrorAction Stop
} catch {
Write-Error "Failed to create tag file '$tagFilePath'. Error: $($_.Exception.Message)"
# Decide if this should be a critical error or allow continuation
}
- Registering the scheduled task using the
Rename Device on Shutdown.xml
file.
It also copies theRename-Device-on-Shutdown.ps1
script to a secure folder:C:\ProgramData\Microsoft\Task\
.
# Schedule the task using the provided XML file
Write-Host "Attempting to create scheduled task 'Rename Device on Shutdown'..."
try {
if (-not (Test-Path $taskXmlPath -PathType Leaf)) {
Write-Error "Scheduled task XML file not found at '$taskXmlPath'. Cannot create task."
Exit 1
}
# -f (Force) will overwrite an existing task with the same name
$schtasksCommand = "schtasks"
$schtasksArgs = @("/create", "/tn", "`"Rename Device on Shutdown`"", "/xml", "`"$taskXmlPath`"", "/f")
# Using Start-Process for external commands provides more control over output and error streams
$process = Start-Process -FilePath $schtasksCommand -ArgumentList $schtasksArgs -NoNewWindow -PassThru -Wait
if ($process.ExitCode -eq 0) {
Write-Host "Successfully created scheduled task 'Rename Device on Shutdown'."
} else {
Write-Error "Failed to create scheduled task. schtasks exited with code $($process.ExitCode)."
# You might want to capture and display schtasks output for more details
}
} catch {
Write-Error "An error occurred while trying to create the scheduled task: $($_.Exception.Message)"
Exit 1
}
Step 2 :Creat the Uninstall.ps1 Script
The uninsatll.ps1 script will delete the following
- Delete the Scheduled Task
# 1. Delete the Scheduled Task
Write-Host "Attempting to delete scheduled task '$taskName'..."
try {
# Check if the task exists before trying to delete it
$taskExists = (schtasks /query /tn "`"$taskName`"" /fo LIST 2>$null) -notmatch "ERROR:"
if ($taskExists) {
$schtasksCommand = "schtasks"
$schtasksArgs = @("/delete", "/tn", "`"$taskName`"", "/f") # /f for force delete without prompt
$process = Start-Process -FilePath $schtasksCommand -ArgumentList $schtasksArgs -NoNewWindow -PassThru -Wait
if ($process.ExitCode -eq 0) {
Write-Host "Successfully deleted scheduled task '$taskName'."
} else {
Write-Error "Failed to delete scheduled task '$taskName'. schtasks exited with code $($process.ExitCode)."
}
} else {
Write-Host "Scheduled task '$taskName' not found. Nothing to delete."
}
} catch {
Write-Error "An error occurred while trying to delete the scheduled task: $($_.Exception.Message)"
# Continue with other cleanup even if task deletion fails
}
- Delete the Tag File
# 2. Delete the Tag File
Write-Host "Attempting to delete tag file: $tagFilePath"
try {
if (Test-Path $tagFilePath -PathType Leaf) {
Remove-Item -Path $tagFilePath -Force -ErrorAction Stop
Write-Host "Successfully deleted tag file: $tagFilePath"
} else {
Write-Host "Tag file '$tagFilePath' not found. Nothing to delete."
}
} catch {
Write-Error "Failed to delete tag file '$tagFilePath'. Error: $($_.Exception.Message)"
}
- Delete the application directory (if empty or only contains log files)
try {
if (Test-Path $baseDir -PathType Container) {
# Get all items in the directory
$itemsInDir = Get-ChildItem -Path $baseDir -Recurse -Force -ErrorAction SilentlyContinue
# Define files that are safe to ignore (e.g., log files)
$safeToIgnore = @(
(Join-Path $baseDir "Task.log").ToLower()
(Join-Path $baseDir "Uninstall-Task.log").ToLower()
)
# Check if there are any files other than the logs
$otherFilesExist = $itemsInDir | Where-Object {
$_.PSIsContainer -eq $false -and
($safeToIgnore -notcontains $_.FullName.ToLower())
}
if ($otherFilesExist.Count -eq 0) {
# Only remove if it's empty or contains only the specified log files
Remove-Item -Path $baseDir -Recurse -Force -ErrorAction Stop
Write-Host "Successfully removed directory: $baseDir"
} else {
Write-Warning "Directory '$baseDir' contains other files. Not removing to prevent data loss."
$otherFilesExist | ForEach-Object { Write-Warning " - Found: $($_.FullName)" }
}
} else {
Write-Host "Directory '$baseDir' not found. Nothing to remove."
}
} catch {
Write-Error "Failed to remove directory '$baseDir'. Error: $($_.Exception.Message)"
}
Step 3 : Create the Task Scheduler (Rename Device on Shutdown.xml)
I recommend creating the Task Scheduler task manually first, then exporting the .xml
file and placing it alongside your Install.ps1
script.
Check out my post on how to create a Task Scheduler,
or if you’re comfortable editing XML directly, you can use the provided template here.
This Task Scheduler XML is configured to listen for Event ID 1074 from the User32 source, which is triggered when a user initiates a shutdown or restart. Once triggered, it executes a PowerShell script that renames the device.
<Triggers>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription><QueryList><Query Id="0" Path="System"><Select Path="System">*[System[Provider[@Name='User32'] and EventID=1074]]</Select></Query></QueryList></Subscription>
</EventTrigger>
</Triggers>
Step 4: Writing the Rename Script
Create a script named Rename-Device-on-Shutdown.ps1
with your custom logic. Here’s a basic example:
# Get the computer's serial number
$serial = Get-WmiObject -Class Win32_BIOS | Select-Object SerialNumber
$serial = $serial.SerialNumber
# Set your desired new computer name here (e.g., "Shtech" + SerialNumber)
$newName = "Shtech" + $serial
# Get the current computer name
$currentName = $env:COMPUTERNAME
# Check if a rename is needed
if ($currentName -ne $newName) {
Write-Host "Renaming computer from '$currentName' to '$newName'..."
# Rename the computer without forcing a restart
Rename-Computer -NewName $newName -Force -ErrorAction Stop
exit 0
}
📝 Tip: Use more sophisticated naming logic (e.g., serial number, domain, department) for enterprise needs.
Step 5: Package Task Scheduler as a Win32 App
Folder Structure
Place the following in a working folder:
📁 RenameDeviceWin32App
├── Install.ps1
├── Uninstall.ps1
├── Rename Device on Shutdown.xml
├── Rename-Device-on-Shutdown.ps1
Use IntuneWinAppUtil tool Content Prep Tool
Download the IntuneWinAppUtil tool, then run:
IntuneWinAppUtil.exe -c "C:\RenameDeviceWin32App" -s Install.ps1 -o C:\Output
This generates a .intunewin
file for upload.
Step 6: Deploy with Intune
- Go to Intune Admin Center → Apps → Windows → + Add.
- Choose App type: Windows app (Win32).
- Upload the
.intunewin
file. - Create Name for the application <Rename Laptops>
- Install behavior: System
- Configure:
- Install command:
powershell.exe -ExecutionPolicy Bypass -File Install.ps1
- Uninstall command:
powershell.exe -ExecutionPolicy Bypass -File Uninstall.ps1
- Detection Rule: Check for existence of
C:\ProgramData\Microsoft\Task\Task.Tag
- Install command:

- Dependencies/Requirements: Optional based on environment
- Assign to appropriate device groups.
Step 7: Validate the Task Scheduler
- On the target machine, open Task Scheduler (run as administrator as the task will run at system level) → Task Scheduler Library.
- Look for the task: Rename Device on Shutdown.
- Shutdown the machine — upon startup, confirm the hostname has changed.

You can also inspect the Event Viewer for EventID 1074
in the System log to confirm the task trigger.
Security and Permissions Considerations in Creating Task Scheduler
- Ensure the scheduled task runs with SYSTEM privileges for full permission to rename.
- Sign the PowerShell scripts if you’re in a secure environment.
- Avoid hardcoding sensitive info — use parameters and environment variables.
Benefits of using Task Scheduler Approach
Feature | Benefit |
---|---|
Flexible Timing | Renames after full user setup or policy application |
Fully Automated | No manual input needed post-deployment |
Intune Deployable | Scales enterprise-wide easily |
Custom Naming Logic | Use any scriptable logic to define device names |
Final Thoughts
By combining PowerShell, Task Scheduler, and Intune Win32 app deployment, you gain a powerful, flexible mechanism to automate device naming — even outside of Autopilot flows. It’s especially useful in hybrid environments or when reassigning devices with dynamic contexts.