Deploy a customized Windows 11 Start Menu, that allows users to change pinned apps

Microsoft documentation describes how to customize the Start menu, the only issue is that this will reset the pinned apps each time the device syncs back to Intune. For the use case where you want to set the initial start menu configuration and then allow the user to pin their own apps is not currently available. But in this blog post we will do just that, set initial start menu configuration, and allow the user to change it afterwards.

There have been multiple other blog post around this, but after testing out a lot of them I have had no success. I tried setting registry values, I tried applying the LayoutModifciation.json and I tried to copy the start.bin file, all failed in one way or another. Copying of the start.bin file failed due to the profile being created during enrollment did not use the start.bin from the default Windows profile, and when I tried to copy it to all users on the device it would simply not copy it to the current user that the device was being deployed to. I ended up using a way of copying the start.bin file with a combination of creating a schedule task, this way I always get the correct start menu instantly.

Customize the Start menu layout on Windows 11

When you customize the Start layout, you overwrite the entire full layout. A partial Start layout isn’t available. Users can pin and unpin apps, and uninstall apps from Start. When a user signs in or Explorer restarts, Windows reapplies the MDM policy. This action restores the specified layout and doesn’t retain any user changes.

Preparing your Start Menu

How to pin and unpin apps to the Start menu

Prepare the way you want your Start Menu to look like on a Windows 11 device.

Worth mentioning is that if you have devices that are being deployed on a Windows build less then 22H2 then you will need to have two versions of the start.bin file. Windows Build 22H2 uses a file named start2.bin instead of start.bin.

The way I did this was by setting up a fresh VM with Windows 11  build 21H2, I then removed the pinned apps that I did not want and added the once that I wanted.

Next, I ran Windows update and installed the Windows 11 22H2 build, this will generate the second start2.bin once restarted.

Exporting the start.bin file(s)

The start.bin files are located in your user profile.
Full location: %LocalAppData%\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState

Copy the start.bin and start2.bin file into a folder, we will need these later on.

Windows 11 Start menu layout files
start.bin files

PowerShell Script to copy files and create scheduled task

This is the script I use to copy the correct start.bin file and deploy it during the enrollment process, you may want to modify this as I create some folder where I store the files, you may want to use the temp folder etc.

The part that will make this work is the schedule task. The GroupId I use in this task is the Default Users group in Windows. This part is what makes it able to copy the files to the current user during the enrollment process.

Save the script as install.ps1 in the same folder you placed your start.bin file(s)

If ($ENV:PROCESSOR_ARCHITEW6432 -eq "AMD64") {
    Try {
        &"$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -File $PSCOMMANDPATH
    }
    Catch {
        Throw "Failed to start $PSCOMMANDPATH"
    }
    Exit
}

if (!(Test-Path "$env:SystemDrive\ProgramData\AutoPilotConfig\Start-Menu")) {
    New-Item -ItemType Directory -Path "$env:SystemDrive\ProgramData\AutoPilotConfig\Start-Menu"
}

$Destination = "$env:SystemDrive\ProgramData\AutoPilotConfig\Start-Menu"

# Check Windows Build to copy start.bin or Start2.bin depending in build number
$BuildNumber=[INT](Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select-Object -ExpandProperty CurrentBuildNumber)

If ($BuildNumber -lt 22621) {

    $Source = "$PSScriptRoot\start.bin", "$PSScriptRoot\StartMenu.ps1"
    Copy-Item -path $Source -Destination $Destination -Force

}

else {

    $Source = "$PSScriptRoot\start2.bin", "$PSScriptRoot\StartMenu.ps1"
    Copy-Item -path $Source -Destination $Destination -Force
}

# Define the principal
$principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -RunLevel Highest

# Define the task settings
$taskSettings = New-ScheduledTaskSettingsSet `
    -AllowStartIfOnBatteries `
    -DontStopIfGoingOnBatteries `
	-ExecutionTimeLimit (New-TimeSpan -Hours 72)

# Define the task trigger
$taskTrigger = New-ScheduledTaskTrigger -Once `
    -At (Get-Date).AddSeconds(5)

# Define the task action
$taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $Destination\StartMenu.ps1"



# Register the scheduled task
Register-ScheduledTask -TaskName "StartMenu" `
    -TaskPath "\" `
    -Principal $principal `
    -Settings $taskSettings `
    -Trigger $taskTrigger `
    -Action $taskAction `
    -Force
       

As you can see the script refers to a StartMenu.ps1 and we will create this next. This is used to trigger the copy of the file to the current user during the enrollment.

StartMenu.ps1 (The file the scheduled task runs)

StartMenu.ps1 copy’s the file to the current user profile. I’m using Stop-Process to restart the StartMenuExperienceHost.exe, if this is not done then the user will have to restart the device one time before seeing the new Start Menu layout.

Save the StartMenu.ps1 file in the same folder you placed your start.bin file(s)

If ($ENV:PROCESSOR_ARCHITEW6432 -eq "AMD64") {
    Try {
        &"$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -File $PSCOMMANDPATH
    }
    Catch {
        Throw "Failed to start $PSCOMMANDPATH"
    }
    Exit
}

#Copy Start.bin file(s) to folder
Copy-Item -Path "$env:SystemDrive\ProgramData\AutoPilotConfig\Start-Menu\*.bin" -Destination "$env:UserProfile\AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\" -Force -Verbose

#Delay
Start-Sleep -Seconds 10

#Restart Start Menu Experince
Stop-Process -Name StartMenuExperienceHost -Force

Packaging the files as a Win32 application

You should now have a folder with two start.bin files (start.bin and start2.bin), the folder should also contain the install.ps1 and the StartMenu.ps1 file.

We will use the Microsoft Win32 Content Prep Tool to package the files.

  • Start the Microsoft Win32 Content Prep Tool as Administrator
  • Select the location where stored your files.
  • Specify the setup file: install.ps1
  • Select the folder where you want the output.
  • The file .intunewin will contain all the files you had in the folder.
  • A file named install.intunewin should now have been created.

Deploy the package using Intune

Go to Intune and select Apps, Add a new Win32-based app.

Win32 app in Intune
Win32 App Intune

Add the package that we just created install.intunewin
Add a name, description, Publisher, Version etc.

Program settings

Install command: powershell -executionpolicy bypass -file install.ps1
Install behavior: System

Win32 app program settings in Intune
Program Settings Intune

Requirements

App requirements in Intune
App Requirements

Detection rules

For this I just made it simple, it only verifies that the files being copied are in the location we wanted them to be. If you modify the script, make sure you modify the detection rules. (I know this is not really checking if the full process was completed, but you can modify this or add create register files depending on success or failure.)

Rule type: File
Path: %SystemDrive%\ProgramData\AutoPilotConfig\Start-Menu
File or folder: start.bin
Detection method: File or folder exist

Detection rule for application in Intune
Detection rule

Assign the newly created app to “All users” as Required (This will overwrite any current user settings they have, so you can assign it to only new users if you like)

Custom Detection script, checks the file and task (UPDATE)

Instead of using the detection rules mentioned above you can use this detection script, this is going to verify that the files are create and the scheduled task is also created.

If you edited anything in the script, please edit the detection script to fit your need.


Add the app as Required to the Enrollment Status page profile

Go to your enrollment status page and make sure you add the app to the required apps, this will make sure it will be deployed during the enrollment.

Enrollment page, required apps
Enrollment page Required Apps

You are done.
When a new device is deployed, the start menu layout will be instantly applied for the end-user and they can then pin their own apps.

Extra

In my script I do not delete the task, you could call it at a later stage if needed. If you want it to be deleted, you can always add something like the below, this would delete the task.

# Wait for the task to finish running
Start-Sleep -Seconds 180

# Delete the scheduled task
Unregister-ScheduledTask -TaskName "StartMenu" -TaskPath "\" -Confirm:$false
5 5 votes
Article Rating
Subscribe
Notify of
guest

34 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Karl
Karl
1 year ago

So this installed really fine on my already enrolled work PC, with the only downside being the Powershell window popping up.

However, the start menu layout is not applied if the app is installed during ESP device setup step. Via company portal I see that the app was successfully installed. I guess that it is applied before the user account is created.

JohnT
JohnT
Reply to  Everything365
10 months ago

I’m having a similar issue, I see that the app installed successfully but the modified time on the start.bin file is not changing. So for some reason, the start.bin file in the app is not overriding the one created on the user’s initial login. Any ideas on how to address that? I’ve just published the app to the company portal and run it after the user logs in., but it would be great to automate this.

Connor G
Connor G
Reply to  Karl
4 months ago

To hide the powershell popup:

$taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -NoLogo -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File "$Destination\StartMenu.ps1""

Replace this in install.ps1. The WindowStyle Hidden quickly hides the popup, barely noticeable this way.

Anthony H.
Anthony H.
1 year ago

Hi, do you know if this works on your user profiles? I’d really appreciate it.

Sam
Sam
1 year ago

This is not working for me however it is worth saying I am only using Windows 11 Pro 22H2 so I only have one start2.bin file and not a start.bin since all my network is 22H2 or above do I still need a start.bin ?

Recky
Recky
1 year ago

Just copy the file here and all (new) users will get the start layout :
C:\Users\Default\AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState

Recky
Recky
Reply to  Everything365
1 year ago

Interesting, I did notice it’s not working well. The file is copied fine, but not applied it seems. Do you know why this is?

Recky
Recky
Reply to  Everything365
1 year ago

Sorry, I meant to ask if you know why just copying the file does not work? Your workaround solution works great, thank you.

Paul
Paul
1 year ago

First…I’m no PS expert but can typically figure stuff out. What I don’t understand is how the packaged intunewin app will have access to the start2.bin file I exported. Does the Win32 App Creation tool automatically package the start2.bin file from the source folder where the app is created? ($Source = ”$PSScriptRoot\start2.bin) ?
Nowhere in this process did I designate the start2.bin file to be used.
You mention a temp folder above, which may address this but it may be over my head.
Love your site!

Paul
Paul
Reply to  Everything365
1 year ago

I finally got this to work and it works perfectly. I had my startmenu.ps1 script named incorrectly bc the one I downloaded saved as startmenu-2.ps1 or something. Got that fixed.
Beyond the scope here but as an intune noob I am also finding that intune doesn’t respond super quickly even when just making changes to a policy. Sometimes you have to wait an hour or more for the policy change to be effective after you save it. I made a change, did a new Autopilot deployment about 30 min later to test it. No bueno. I thought my corrections were bunk.
Then…the script ran an hour-plus after the initial deployment. I saw the foreground output and the 10-second delay language, lol ! all of a sudden it was perfect. like I’d run the script myself. My hunch is that it will work on the next deployment now that my corrections have ‘taken’. But MAN that is frustrating about Intune. Iterative testing takes monumental amounts of time.

Sam
Sam
1 year ago

This worked a charm, thanks very much!
One thing I was wondering however, we have a URL shortcut for a SIP address to dial in Teams. I created this on the machine I wanted to deploy the Start Menu to and it pins every app bar this one. Is it possible to package something like this in Intune?

Elza
Elza
1 year ago

Do I have to set the $PSScriptRoot myself in the install script? And if yes what folder do I use?

Elza
Elza
Reply to  Everything365
1 year ago

Thank you, we tried it and it works, but the installation fails when we add the app to the ESP profile. Still figuring out what the problem is.

Psch
Psch
7 months ago

How can I change an entry afterwards? Like Microsoft splitTeams to ”Classic” and ”New”. I have enrolled ”Classic” back then but now have to change it to ”New” without the user have to re-do their customized Start Menu

Connor G
Connor G
4 months ago

This is also not working for us for during OOBE with Intune. The behavior is the script will run before the user first signs in (during OOBE provisioning), and therefore the start menu task is run while the appdata\local\packages folder does not exist. The user signs in and the start menu is not configured, no surprise there. Intune reports it as install success.

I made quite a few changes to add a file detection script to intune that corrects this. The detection looks for a separate file in the packages folder during install. If it can’t find it, it retries, which is what we needed. Install success/ failure reporting is now accurate in Intune.

Not sure where to upload these suggested changes but a few tweaks in Install.ps1 and StartMenu.ps1 were necessary in addition to the detection script change.

Connor G
Connor G
Reply to  Everything365
3 months ago

I posted the link as a reply here but I don’t see it. Does the reply need to be approved?

AwesomeBailey
AwesomeBailey
Reply to  Connor G
8 days ago

We’re having this same issue. I’d love to see your additions too.

Alfredo
Alfredo
4 months ago

This worked perfectly for me, thanks for your work, although I have a slight issue, with which I’m hoping you’ll be able to help. The script only worked for the person that was initially logged in to the PC. I asked another person to log-in, and unfortunately it didn’t work for him, the start menu icons were still default. Any suggestions, so it runs every time when new user logs in? Thank you.