SetupComplete.cmd not executing

dansutton24

New Member
Hi, I’m fairly new to using NTLite and am currently working on an image that executes 2 scripts after setup. 1 needs internet to run. I am using a Windows 11 Enterprise iso. The issue I am having is once the setup completes, the post setup commands don’t execute - I am guessing this is as windows has automatically activated. I have tested without internet and this executes fine - of course failing as the script requires internet.

I’ve read that the setupcomplete.cmd should execute if using Windows 11 Enterprise but did notice posts in the forum saying that the box under unattended for OEM SetupComplete needs to be checked in most cases so it can run. This option isn’t available under unattended for me. Is there any other way for this to be done?
 
Latest NTLite version should not have any issues executing post-setup.
Didn't understand the "I have tested without internet and this executes fine", does that mean it's not the issue with Post-setup, but that you need internet working before it?
In that case try the After logon portion, or if it's WIFI you can integrate a script which restores connection, we can talk about that if it is the case here.

If the Before logon post-setup still does not execute, please provide a way how to confirm that issue, be it a command, a script or an installer which should have installed.
 
Latest NTLite version should not have any issues executing post-setup.
Didn't understand the "I have tested without internet and this executes fine", does that mean it's not the issue with Post-setup, but that you need internet working before it?
In that case try the After logon portion, or if it's WIFI you can integrate a script which restores connection, we can talk about that if it is the case here.

If the Before logon post-setup still does not execute, please provide a way how to confirm that issue, be it a command, a script or an installer which should have installed.
Thanks for the response nuhi. I have a folder added to the machine section which adds PSTools to the machine and then 2 scripts which are added to the user section which I would expect to run after the machine logs in.

The PSTools folder is added without issue as expected but the scripts don’t seem to run after connecting to WiFi at OOBE. The scripts run fine and I can see them after login when not connected to the internet but installing Windows and connecting to the internet, they don’t run after the account logs in.

Might be a Windows issue more than NTLite?
 
nuhi, we need you to explain what was intended in this NTLite redesign.

The current advice for adding a Wi-Fi profile under the old NTLite:
Code:
netsh wlan add profile filename="%WINDIR%"\Setup\Files\profile.xml user=all

But now, when you add profile.xml, it's moved to:
Code:
"%SYSTEMROOT%\Setup\profile.xml"

Is backwards compatibility gone? If that's the case, it needs to be clearly highlighted.
 
Thanks for the response nuhi. I have a folder added to the machine section which adds PSTools to the machine and then 2 scripts which are added to the user section which I would expect to run after the machine logs in.

The PSTools folder is added without issue as expected but the scripts don’t seem to run after connecting to WiFi at OOBE. The scripts run fine and I can see them after login when not connected to the internet but installing Windows and connecting to the internet, they don’t run after the account logs in.

Might be a Windows issue more than NTLite?
Are you saying MSAccount is not supported by Post-setup - After logon?
Or you're using the local account?
There is no reason for commands not to run, if they ran without the internet, only quirk could be that MS Account type is different.

On a potentially separate note, even though I don't think the topic here is the internet connection itself:
If you used WIFI profile as garlin mentioned, make sure to correct the path in the netsh command, to the UI specified in the profile.xml row after adding it to the list.
"%SYSTEMROOT%\Setup\profile.xml" is now the default.

garlin, if you can update your WIFI profile guide, that would be great, I don't recall having my own somewhere.
I'll for sure update the site these days to reflect new post-setup changes.
 
I may have warned you this might happen when changing file handling. Backwards compatibility is imperative because we have too much user experience ingrained in "\Windows\Setup\Files".

If you're placing files in newly created presets to "\Windows\Setup" that's fine, but you really need to put a Files folder symlink pointing back up one level for compatibility reasons. Unless you want to actively fix every old preset after loading and remove "\File\..". Not to mention a number of user contributed scripts which all expect to use "\Windows\Setup\Files".

There's a ridiculous number of threads out there which are now broken unless the Files symlink gets implemented in the next release.
 
The post-setup issues were due to the quick change of the post-oobe script call, which silly me didn't test properly.
I forgot to rename setupcomplete.cmd during testing, to emulate OEM machines, and of course it worked.

Corrected the calls now in the build 9832+, post-setup before-logon should work again for OEM machines as well.

That said, I think this topic is about MSAccount, not about wifi preset path, nor it's a big deal for people to adjust location to the new system where they can choose where to save files anyway.

Updated your guide here.
 
Hi nuhi - thanks for the updates here. I’ll be testing again next week so will come back if I have any further issues.

This was just using a local account so don’t think it’s related to the MS Account. This wasn’t signed in to an MS Account at any point. Wi-Fi was also just connected at OOBE so not related to this either.

Just to confirm, how are the scripts actually ran after logon? I was under the impression that setupcomplete.cmd runs these but this runs straight after the OOBE so this would be before logon meaning the machine post setup runs at this point. Is there something else executed after logon which runs the user post setup executing these scripts?

Just trying to gain a better understanding of what actually runs at what stage and how these run.
 
Machine tasks are executed after OOBE, from a Windows built-in task queue in the registry that runs SetupComplete.cmd.

User tasks are executed after the primary user's first desktop logon, from a RunOnceEx registry key. The major difference is because you're logged on, user profile settings are now available for modification. These tasks run with Admin rights, but under your profile.

Tasks which update your profile, or need user interaction (you clicking on some app screen) need to run under Post-Setup (User).
 
Machine tasks are executed after OOBE, from a Windows built-in task queue in the registry that runs SetupComplete.cmd.

User tasks are executed after the primary user's first desktop logon, from a RunOnceEx registry key. The major difference is because you're logged on, user profile settings are now available for modification. These tasks run with Admin rights, but under your profile.

Tasks which update your profile, or need user interaction (you clicking on some app screen) need to run under Post-Setup (User).
Thanks for the info garlin. Appreciate it!
 
Finally managed to test this and seemed to work fine this time round. The post setup user deployed successfully. I have ran in to an issue when trying to run 2 commands though.

Initially, I added my post setup machine with the PSTools directory. Added my Poweshell script and then a second script within the PSTools folder which I called via a command in post setup user. This works fine.

When I add both of my scripts in to the PSTools directory, it seems to skip the first script completely.

I have checked the registry and can see that the runonceex entries are being created when the image is saved.

The other issue I noticed is once the script is added and runs once. It doesn’t seem to run again on a different machine which is why I added it in to the directory so it’s always there. Is there any reason this would happen? Is the script copied to the machine and wiped from the image when copying?
 
Please provide a preset example of the non-working scenario with two psscripts, not sure what to test for exactly.

As for the second part, the running on a different machine, not sure what that means, isn't the ISO a starting point, all machines are first to it?
If a file or a script is having "Temporary" destination location on the right of it (on the Post-setup list), then it will be deleted after running once.
 
Hi nuhi please see the attached. The only other thing that is copied is PSTools which had the scripts added for when I was attempting to run both as commands so it looked for the file in C:/Windows/Setup/PSTools

Just to confirm my working process:
PSTools folder is copied to the machine using post setup (before logon). This integrates the wipemachine.ps1 script. Once machine is logged in, Autopilot.ps1 runs - this is added as an actual script in post-setup (after login -user) and then wipe machine.ps1 is ran as a command as it needs PSExec to execute. Command used is:
“C:\Windows\Setup\PSTools\psexec.exe -accepteula -s powershell.exe -file C:\Windows\Setup\PSTools\wipemachine.ps1”

The above works - the Autopilot.ps1 script executes and then the manual command executes carrying out the expected actions.

The process I can’t get to work is:
PSTools folder is copied to the machine using post-setup (before logon). This time around, the PSTools folder has both scripts added (Autopilot.ps1 and Wipemachine.ps1). I then add the 2 below commands to post setup (after login -user):
1. “powershell.exe -file C:\Windows\Setup\PSTools\Autopilot.ps1”
2. “C:\Windows\Setup\PSTools\psexec.exe -accepteula -s powershell.exe -file C:\Windows\Setup\PSTools\wipemachine.ps1”

The above doesn’t seem to work as expected. I don’t see the post-setup screen but the machine does restart and start to reset so the 2nd command is running but the first command doesn’t seem to run.

I have reloaded the ISO and the registry shows both runonceex commands and they look to be in order so not too sure why the first command is being skipped doing it this way.

The only reason I have tested this second way is as I mentioned, the working way seems to work once and then won’t work when testing on a second machine. The registry entry for the script to run is integrated in to the ISO, correct? If so, not too sure why I’m seeing this behaviour. Or is the script registry entry cut from the ISO meaning it is run once on one machine and then never again?

I could of course just be doing this all wrong!! Just trying to get clarity on it.

Appreciate the help.

Just to note, I’ve removed some sensitive information from Autopilot.ps1 for sending these files - the information is there when I’m executing it.
 

Attachments

  • Scripts2.zip
    6.2 KB
Hi everyone, I will use this thread to post my problem since it's about same topic.

I have a script made by me on Post Setup. I want this script to run after my first login after installed a new version of windows 11 using an ISO file I created on NTLITE.
My Script:

The problems I am facing is:
1) To run the script the first time using PowerShell I need to add this command line first: Set-ExecutionPolicy RemoteSigned
or the script will not run.

My ISO file already has a Local Account set to be create with a password set to autologin.

I just need help to figure it out how to make this work, it will help me a lot if you guys can help me.

2) I attached my NTLITE Config (23H2_Config_Full.xml)) used to change my ISO`s if anybody is interested to load the configuration to add or check the alterations I made and I will add the PowerShell Script to (Apps.7ZIP = Apps.ps1).

#Script Start
# List of applications to install
$apps = @(
"7zip.7zip.exe",
"IObit.Uninstaller",
"nilesoft.shell", # Microsoft Shell Fix DropDown Menu
"9NFKC78BRS8W", # Fury CTRL DDR4 LEDs
"CrystalRich.LockHunter",
"MiniTool.PartitionWizard.Free",
"HermannSchinagl.LinkShellExtension",
"OpenDesignAlliance.ODAFileConverter",
"Bitdefender.Bitdefender",
"SoftDeluxe.FreeDownloadManager",
"Flow-Launcher.Flow-Launcher",
"Glarysoft.GlaryUtilities",
"Nlitesoft.NTLite",
"Oracle.VirtualBox",
"BlueStacks.Bluestacks",
"Microsoft.WindowsTerminal.Preview",
"Microsoft.PowerShell.Preview",
"QL-Win.QuickLook",
"keyviz",
"9NH1P86H06CG", # Radiograph Hardware Info Monitortying
"REALiX.HWiNFO",
"Logitech.GHUB",
"9MSPC6MP8FM4", # Microsoft Whiteboard
"OBSProject.OBSStudio",
"VideoLAN.VLC",
"SMPlayer.SMPlayer",
"Audacity.Audacity",
"HulubuluSoftware.AdvancedRenamer",
"IrfanSkiljan.IrfanView",
"IrfanSkiljan.IrfanView.PlugIns",
"Mirillis.Action",
"Inkscape.Inkscape",
"Canva.Canva",
"Zoom.Zoom",
"Discord.Discord",
"HandBrake.HandBrake",
"9NBLGGH5L9XT", # Instagram
"9WZDNCRFJ2WL", # Facebook
"Ubisoft.Connect",
"EpicGames.EpicGamesLauncher",
"Valve.Steam",
"ElectronicArts.EADesktop",
"Google.PlayGames.Beta",
"SomePythonThings.WingetUIStore",
"Crunchyroll.MasterofGarden"
)

# Loop through the list and install each application
foreach ($app in $apps) {
Write-Host "Installing $app"
winget install --id $app --accept-package-agreements --silent
}
#Script End

I hope someone can help me finally solve this annoying issue that I tried for so long and have failed miserably.

To help, the answer Copilot Pro gave me is:

Sure, I can guide you on how to set up a PowerShell script to run after the first login on a new version of Windows 11 using NTLite’s Post Setup option. Here are the steps:
  1. Create a PowerShell script: You already have your PowerShell script Apps.ps1 that installs the applications you listed.
  2. Change the execution policy: To run PowerShell scripts on Windows 11, you need to change the execution policy. Open PowerShell as an administrator and run the following command1:
Set-ExecutionPolicy RemoteSigned

  1. Set up the script to run at logon: There are two ways to set up a PowerShell script to run at logon23:
    • Local Group Policy Editor: Press Win+R, type gpedit.msc, and hit Enter. Navigate to Computer Configuration > Administrative Templates > System > Scripts. Double-click on Run Windows PowerShell scripts first at user logon, logoff, select the Enabled option, and click Apply and OK.
    • Registry Editor: Press Win+R, type regedit, and hit Enter. Navigate to HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System. Right-click on System > New > DWORD (32-bit) Value and name it as RunUserPSScriptsFirst. Double-click on it and set the Value data as 1.
  2. NTLite Post Setup option: In NTLite, navigate to the Post-Setup section. Here, you can add commands and application installations that are executed after the operating system setup completes4. According to the NTLite community, Post-Setup commands are executed by a CMD wrapper script56. So, you can add your PowerShell script here.
Here is an example of how you can add your script to the Post Setup option:
%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy Bypass -File "C:\\Path\\To\\Apps.ps1"

Replace "C:\\Path\\To\\Apps.ps1" with the actual path to your Apps.ps1 script. This command will run your PowerShell script in Bypass execution policy mode, which means nothing is blocked and warnings do not appear.
Please note that you should test these steps in a controlled environment before deploying them in a production environment. Let me know if you need further assistance!

Iven so, I didn`t understand the answer, but maybe someone here will understand if it correctly the Copilot Pro answer.
 

Attachments

  • 23H2_Config_Full.xml
    14.9 KB
  • Apps.7z
    1 KB
Last edited:
Hi N7Commander you should just be able to add the script to post setup user (after-logon) and NTLite does everything else. It’ll create the relevant registry entry to execute this after logon. You shouldn’t need to add the set-execution policy to this, all scripts are ran with this already I’ve read in previous threads.

I am unable to try this on mine at the minute as I’m not on my Laptop but have you tested the script manually to ensure it is working?
 
Hi nuhi please see the attached. The only other thing that is copied is PSTools which had the scripts added for when I was attempting to run both as commands so it looked for the file in C:/Windows/Setup/PSTools

Just to confirm my working process:
PSTools folder is copied to the machine using post setup (before logon). This integrates the wipemachine.ps1 script. Once machine is logged in, Autopilot.ps1 runs - this is added as an actual script in post-setup (after login -user) and then wipe machine.ps1 is ran as a command as it needs PSExec to execute. Command used is:
“C:\Windows\Setup\PSTools\psexec.exe -accepteula -s powershell.exe -file C:\Windows\Setup\PSTools\wipemachine.ps1”

The above works - the Autopilot.ps1 script executes and then the manual command executes carrying out the expected actions.

The process I can’t get to work is:
PSTools folder is copied to the machine using post-setup (before logon). This time around, the PSTools folder has both scripts added (Autopilot.ps1 and Wipemachine.ps1). I then add the 2 below commands to post setup (after login -user):
1. “powershell.exe -file C:\Windows\Setup\PSTools\Autopilot.ps1”
2. “C:\Windows\Setup\PSTools\psexec.exe -accepteula -s powershell.exe -file C:\Windows\Setup\PSTools\wipemachine.ps1”

The above doesn’t seem to work as expected. I don’t see the post-setup screen but the machine does restart and start to reset so the 2nd command is running but the first command doesn’t seem to run.

1. Post-Setup (Machine) or "Before logon" runs under the SYSTEM context. Therefore, "psexec -s" isn't required for any special elevation rights.

2. When adding a *.ps1 file, NTLite implictly calls that PS script using "-NoProfile -ExecutionPolicy Bypass".

3. When you manually add a PS command with provided parameters, it's up to you to remember to copy that, otherwise your default Execution Policy refuses to execute unsigned scripts.

4. When adding commands, the correct format is "(base) Command" | "Parameters".

Right:
CommandParameters
powershell-nop -ep bypass -file C:\Windows\Setup\Autopilot.ps1

Wrong:
CommandParameters
powershell -nop -ep bypass -file C:\Windows\Setup\Autopilot.ps1
 
The problems I am facing is:
1) To run the script the first time using PowerShell I need to add this command line first: Set-ExecutionPolicy RemoteSigned
or the script will not run.

My ISO file already has a Local Account set to be create with a password set to autologin.

I just need help to figure it out how to make this work, it will help me a lot if you guys can help me.

2) I attached my NTLITE Config (23H2_Config_Full.xml)) used to change my ISO`s if anybody is interested to load the configuration to add or check the alterations I made and I will add the PowerShell Script to (Apps.7ZIP = Apps.ps1).
#Script Start
# List of applications to install
$apps = @(
"7zip.7zip.exe",
"IObit.Uninstaller",
"nilesoft.shell", # Microsoft Shell Fix DropDown Menu
"9NFKC78BRS8W", # Fury CTRL DDR4 LEDs
"CrystalRich.LockHunter",
"MiniTool.PartitionWizard.Free",
"HermannSchinagl.LinkShellExtension",
"OpenDesignAlliance.ODAFileConverter",
"Bitdefender.Bitdefender",
"SoftDeluxe.FreeDownloadManager",
"Flow-Launcher.Flow-Launcher",
"Glarysoft.GlaryUtilities",
"Nlitesoft.NTLite",
"Oracle.VirtualBox",
"BlueStacks.Bluestacks",
"Microsoft.WindowsTerminal.Preview",
"Microsoft.PowerShell.Preview",
"QL-Win.QuickLook",
"keyviz",
"9NH1P86H06CG", # Radiograph Hardware Info Monitortying
"REALiX.HWiNFO",
"Logitech.GHUB",
"9MSPC6MP8FM4", # Microsoft Whiteboard
"OBSProject.OBSStudio",
"VideoLAN.VLC",
"SMPlayer.SMPlayer",
"Audacity.Audacity",
"HulubuluSoftware.AdvancedRenamer",
"IrfanSkiljan.IrfanView",
"IrfanSkiljan.IrfanView.PlugIns",
"Mirillis.Action",
"Inkscape.Inkscape",
"Canva.Canva",
"Zoom.Zoom",
"Discord.Discord",
"HandBrake.HandBrake",
"9NBLGGH5L9XT", # Instagram
"9WZDNCRFJ2WL", # Facebook
"Ubisoft.Connect",
"EpicGames.EpicGamesLauncher",
"Valve.Steam",
"ElectronicArts.EADesktop",
"Google.PlayGames.Beta",
"SomePythonThings.WingetUIStore",
"Crunchyroll.MasterofGarden"
)

# Loop through the list and install each application
foreach ($app in $apps) {
Write-Host "Installing $app"
winget install --id $app --accept-package-agreements --silent
}
#Script End
I hope someone can help me finally solve this annoying issue that I tried for so long and have failed miserably.
Same answer as above, NTLite implicitly runs every added *.ps1 with "-NoProfile -ExecutionPolicy Bypass", so changing your Execution Policy isn't required unless you wanted a different default PS setting.

1. Your commands are incorrect, they're not invoked from PS.

CommandParameters
powershellSet-ExecutionPolicy RemoteSigned -force
powershellSet-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force

2. winget scripts will fail because winget isn't ready when it's called. Either execute a winget installer script from Post-Setup (User) or "After logon" which forces winget to be updated immediately, or follow the instructions on this thread:

What changed? Post-Setup After Logon Script not run
 
Back
Top