Change Lock Screen & lockout users during Upgrade TS

What: Changing the Lock Screen Image to warn end user that the system is performing upgrade, also preventing users from logging on during TS.

Why: So users don’t call upset when they logon to a computer then get rebooted when the TS reaches that point. (For those groups whose users don’t read all of the communications about their machines updating)

How: Downloading Pre-created Images, setting registry keys, and to lock out users, that requires a little help from group policy (1 time setup)


Back story: ProgressUI does not display on computers unless a user is logged on.  If the process starts at it’s deadline, and no one is logged on, it will start running the task sequence with no visible signs until it reboots into setup, and the user sees the Windows 10 Setup screen.  Lets say the TS has started, and it’s in the middle of downloading the content, which can take awhile on a slow link.  User starts to do work (watch cat videos), and then they see a message pop up finally saying "computer will reboot in 60 seconds, you’re welcome", they won’t be so happy, worse yet, they look away for a couple minutes, or are grabbing their coffee to come back and find their computer rebooting to setup.   How can we draw more attention to the fact the computer is doing something.. how about make a bold lock screen image warning the user of the upgrade, or even prevent them from logging on.
Here is a picture, the PC was logged into during the TS, the User has no idea it’s in the setup.exe phase of the TS, going to reboot them in a few minutes.  This is what we’re trying to avoid.

Lock Screen is pretty easy, I have a couple steps in the beginning of the TS that downloads the files I need to a local folder, then deletes them at the end.

I have this same process repeated several times, before different large steps.  In my Example, I update the Security Software, which takes 20 minutes, so I have a custom lock screen image saying it’s updating Security Software.

I then repeat the process after the Security software is installed, and change the Image to say “Upgrading Windows OS”, which will be there until it reboots into setup.  At the end, I delete the registry keys allowing the original settings to take over and original lock screen image to return. (If you’re using the registry keys to apply a custom image, just set it back to what it was before, you could easily capture that key into a variable, then set it back at the end, or manually add it if everyone is the same, or have group policy fix it later)

Please modify steps to fit your environment, file names / location are only for example.

  1. Make Temp Folder for OSD Stuff
    1. cmd.exe /c if Not Exist "%programdata%\OSDReqs\" (md %programdata%\OSDReqs)
    2. image
  2. Copy Background Images (From your package with custom backgrounds)
    1. Package Contents: - Download Mine HERE
    2. xcopy OSDImages\*.jpg %programdata%\OSDReqs /Y
    3. image
  3. Update Lock Screen Image Group (Only set to run if no one is logged on)
    1. WMI Query: select * from win32_computersystem where username is NULL
    2. Set Image 1 (Security Apps) – Modify the ImageName to match your needs.
      1. REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" /V LockScreenImage /T REG_SZ /D C:\ProgramData\OSDReqs\ImageBackGroundRed-DoNotLogonSecurity.jpg /F
    3. Tweak - Delete Legal Notice on Logon (1 of 2) –Optional – Removes the Legal Notice
      1. REG DELETE "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" /v legalnoticecaption /f
    4. Tweak - Delete Legal Notice on Logon (2 of 2) –Optional – Removes the Legal Notice
      1. REG DELETE "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" /v legalnoticetext /f
    5. Stop Process -Name WinLogon (Forces LockScreen to refresh.)
      1. powershell.exe "if((Get-WmiObject win32_computersystem).username -eq $null) {Stop-Process -Name winlogon -Force -Verbose}"
    6. Wait 5 seconds – Allows time for the Lockscreen to refresh before continuing. – Optional
      1. powershell.exe "Start-Sleep -seconds 5"

As for the locking out of users so they can’t log on, here is how I did that in my lab.

I created a group policy called “Deny Logon Locally” - TechNet

  1. Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment
  2. Set Deny logon Locally to "DenyLogonLocally" (Which is the group we’re going to create in the TS)

During the TS, I create a local group called "DenyLogonLocally" and populate it with all of the users who have logged onto the local computer (Thanks @keithga1) for the powershell code.

  1. Create Local Group DenyLogonLocally
    1. net localgroup DenyLogonLocally /add
    2. Set continue on error (it will error if you already have the group on your machine) – Recommend NOT deleting when done, but leaving for all future upgrades.  I had issues when I deleted it and recreated it, the policy didn’t take on the recreated group even with the same name.
    3. I had considered having an AD Group of all Domain Users (that were not admin accounts), but then you have one more group to keep manage in AD, so I decided against that. – that’s my greyed out step. - Note, added section at the end to show I had did set this up.
  2. Add Accounts to DenyLogonLocally – This will grab all of the accounts that have logged onto the machine, and populate them into the local group (You can specify accounts you don’t want included)
    1. Code: (Copy and paste it all, it is just one long line of code, thanks Keith) - Change the -notmatch area with your tech accounts

      Here shows the group after the script has run, both accounts garytown & cmadmin have logged on to this machine, but only garytown has been added.
  3. Remove Deny Logon Locally Group Membership – placed near the end in your clean up section, and in the roll back section, so if the upgrade fails, it will remove the users from that group, allowing them to log on again
    1. Code:


Note, do NOT kill the winlogon.exe after the setup.exe phase, bad things happen.. like it stops your TS (No errors thrown).
In the image above, you can see the "Stop Process -Name Winlogon" Step, disable / delete that.
You honestly don't need it after the setup.exe anyway, rest of the TS will be visible to your users.  After you delete the keys and clean up the images, everything will go back to how it was before once the system reboots at the end of the TS.

Hopefully this is helpful for you, not saying it’s the best or only, I’ve seen a lot of people blogging about similar things during an OSD TS, but I haven’t found much for in-place upgrade TS, so I’ve posted this.

NOTE: Sometimes the Lock Screen is buggy not showing the Lock Screen image, I’ve seen this on countless tests, I believe it is a known bug, so hopefully this gets resolved in the future.  In my last test, I changed the Background after the setup stage, but it just stayed a solid color blue, didn’t actually load the background.  This is why it’s great if you can prevent logon until the TS is complete.

I’ve also been considering removing the default “Upgrade Operating System” step with a run command line step and remove the /quiet switch.  If we don’t want users logged on, then having the UI display will assist with getting them to no be logged on, right?  Well, I still have to test this idea, if it pans out, I’ll share.

Updated 9/18 to show adding a domain group to control lock out.

In Active Directory, I created a group "DenyLogonLocallyTemp" and added all of the user accounts that I want to deny access.  This is where nested groups would be best.  Just make sure you don't have any of the tech / admin accounts in any of those groups.

Above shows the Machine after the steps "Add Domain Deny Group to Local" & "Add Accounts to DenyLogonLocally" have both run.  The Domain group was added by the first step, and the individual user by the second.  This is for demo purposes, you can pick one or the other, or both, depending on your scenarios.

Step: net localgroup DenyLogonLocally / add DOMAIN\DenyLogonLocallyTemp

Condensed Video of Progress:

ConfigMgr OSD Lab–Add AutoLogon Account

I added a local admin account (Non-Domain) that autologon’s on to the computer after OSD purely to speed up my testing.  This way I don’t have to wait for First Logon, after OSD, it will reboot, then autologon as the account I’ve Created.

Make sure you add the SMSTSPostAction to reboot, so you don’t get that Group Policy Error the first time you try to logon. (As explained by Niall)

I’ve created a Task Sequence Variable at the start of the TS, that allows you to trigger the AutoLogon Group.  Simple Enable or Disable this step to have the Group run.

I then have a group which runs all of the commands individually.  You could easily put this into one batch file, I just like to do it this way, self documenting, and requires no content.  The group is set to run if the Task Sequence Variable “AutoLogon” = True


I then have 7 “Run Command line” Steps, creating the User and registry keys.

  1. Tweak – AutoLogon - Create Tony Stark Account
    1. net user /add TonyStark CapAmericaSt1nks! /Y
  2. Tweak – AutoLogon - Tony's Password Never Expire
    1. wmic useraccount where "Name='TonyStark'" set PasswordExpires=false
  3. Tweak – AutoLogon - Make Tony Admin
    1. net localgroup Administrators %computername%\TonyStark /add
  4. Tweak - AutoLogon - Key DefaultUserName
    1. REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /V DefaultUserName /T REG_SZ /D TonyStark /F
  5. Tweak - AutoLogon - Key DefaultPassword
    1. REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /V DefaultPassword /T REG_SZ /D CapAmericaSt1nks! /F
  6. Tweak - AutoLogon - Key AutoAdminLogon
    1. REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /V AutoAdminLogon /T REG_SZ /D 1 /F
  7. Tweak - AutoLogon - Key DefaultDomainName
    1. cmd.exe /c REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /V DefaultDomainName  /T REG_SZ /D %COMPUTERNAME% /F
  8. Optional: Add two Steps to remove the Legal Notice Prompt (If you have it in your lab, GPO will probably put it back)
    1. REG DELETE "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" /v legalnoticecaption /f
    2. REG DELETE "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" /v legalnoticetext /f

After TS finishes, it will reboot and start the logon process automatically.  Now you can start your testing.


You can change this to fit your needs, use a domain account in your Lab, just change the steps, as you won’t need 1-3 to create the account, and change step 7 to the Domain Name (Contoso, ViaMonstra, etc) instead of %computername%


Please Note, this is sending the information in Clear Text, and will be available in logs, etc.  Probably fine for your lab, not a good idea for production. Smile  Please don’t say “Hey Boss, don’t worry about it, it’s totally cool, Gary does it!”

Win10 Build Updates–Persistent Tweaks

CONTEXT: (Feel free to skip my babbling)
If you haven’t figured out by now, I hate managing things that I feel should manage themselves.  If I can get out of doing extra work, and have things in place to automatically take care of it, awesome.  Even if it’s less efficient on network resources, and I lose some granularity of control, if my environment doesn’t care, then I’m going to let things auto update, and auto remediate as much as possible.  (Note, where I work now, I don’t follow my personal philosophy, my environment cares, everything is controls to super granular levels, but we have people to manage it here, at my last place, it was just a couple of us doing everything, so we had to employ methods to do things with out technicians having to get involved.)

Make Windows 10 Build Updates easier.  While I love Task Sequences, I don’t want to have to make something complex for a build update that happens every 6 months.  I want windows to update, and I want to keep the customizations I put in during OSD.
From MMS Presentation: Download full Presentation HERE

Tried and True is Group Policy, however, group policy can take a little while to kick back in, and I don’t want to wait, I want the customizations there before the user logs back in, I don’t want the user to know things changed.  I decided to go with good old scheduled tasks and two scripts, (1 batch file & 1 powershell) plus a 3rd script to build the scheduled tasks and copy the files required locally.

Basically, the batch file is a combination of all the system level tweaks crammed into one script, and the powershell file is the “remove default apps” script. Hopefully after 1709, you won’t need to keep removing the AppX packages, I’ve heard they are “fixing” it so that it will honor the appx you’ve removed, and not put them back in, however, they will probably keep adding in new AppX packages that you’ll have to decide if you want to keep or remove, so there is a good chance you’ll have to run a modified version of this script for each build upgrade forever.

Batch File to Create Scheduled Tasks & Copy Required Files to c:\ProgramData:

Powershell Script To Remove Default Apps (Thanks @Geodesicz):

Batch File to Reapply System Level Tweaks:

Once you have those, you’ll need to create the Scheduled Tasks:
I’ve provided the XML files in the download, and the scripts to import them. (At bottom of post)


First Scheduled Task – Removing Defaults Apps
image imageimage

General: Windows 10 In-Place Upgrade AppRemoval
user account: SYSTEM
Run whether user is logged on or not
Run with highest privileges (Checked)
Configure for: Windows Vista / Server 2008

Trigger: On an Event
Basic: Microsoft-Windows-AppReadiness/Admin
Source: AppReadiness
EventID: 100

Action: Start a Program
Program / Script: powershell.exe
Add arguments: -executionpolicy bypass -file "C:\ProgramData\Win10Upgrade\Windows10Tweaks\RemoveDefaultAppsWin10.ps1"


Second Scheduled Task – Reapplying Tweaks / Branding

General: Windows 10 In-Place Upgrade Tweaks
user account: SYSTEM
Run whether user is logged on or not
Run with highest privileges (Checked)
Configure for: Windows Vista / Server 2008

Trigger: On an Event
Basic: Microsoft-Windows-AppReadiness/Admin
Source: AppReadiness
EventID: 100

Action: Start a Program
Program / Script: C:\ProgramData\Win10Upgrade\Windows10UpgradeTaskFixesScript.cmd


Application Contents: (Root)

Application Contents: (Subdirectory)
1703 folder just contains the Images I used with our 1703 deployment.


Once you've run the Setup Script or Application, it will create the Scheduled Tasks, and copy the files needed to run after the build update to:

DOWNLOAD Exported Application:
This contains the raw files, you don’t actually need to import if you don’t want to.

For the Application Model of Win10 Build Upgrade, I had an application with the content source of the extracted ISO:
Install Program: Setup.exe /auto upgrade /DynamicUpdate Enable /showoobe none  (This will download and apply updates, which can take a long time, but recommend you still do this unless you manually update the install.wim file)
Detection Method: Registry: HKLM\SOFTWARE\Micrsoft\Windows NT\CurrentVersion CurrentBuild = 15063 (1703 - Change the Build number to match the Build you're deploying)

Please customize the tweaks for your environment. 🙂

As always… TEST TEST TEST.  As I mentioned in the beginning, I don't use this method any longer due to different requirements at my new employer, so I'm no longer testing and developing this process.
Please note, the Lock Screen Image can be inconsistent, sounds like MS is aware of a bug, and hopefully future builds will fix this, so if your Lock Screen doesn’t always apply right each time you test… call it good enough and move on to the next thing on your list.


Update 2017.09.07 - Jason Freeman (@loosusjason) pointed out you can do this with SetupConfig.ini - More info HERE


Dell BIOS update–WinPE–Model Independent–From Internet

Update 5/26 - Updated Script to use Dell's Enterprise Cab XML data, instead of the ever changing Support Site.  This now truly does work for all Dell Models that I know of. 🙂  Thanks Mark - POST HERE Mark gives some back story as to how we came up with this idea, and why we wanted to switch from our old method.

Updated Script: (Updated Download as well on 7/11/17 - DOWNLOAD HERE)

The new Package contents:




The Task Sequence:

Just an FYI... you might notice that it's not updating the BIOS to the latest BIOS update for that model.  Example, yesterday several bios updates were released for several models to their WebSite. Those will not install using this method.  The Enterprise CAB data has extra layers of Change Management / Testing, so you can feel even better about applying the BIOS updates automatically. Once those extra layers have completed, then they become available.


Until Then, I’ve updated scripts and added a script for the TPM update.

2 scripts now, based on Dell Driver Cab, instead of HTML scraping.

  1. DellTPMDownloadUpdatePE – Downloads and install the TPM 2.0 x64 Update for that model (if available)
  2. DellCabBiosUpdate.ps1


Original Post:

Ok, so you’re thinking, Gary, you just posted about this, and you’d be right, I did, see.., but in the past week or so, I’ve come up with an idea, after looking at Maurice Daly’s download utilities, thinking, why can’t I just do something like that, and not have to have any content (beside the script and utility) to update the bios, and have it work on any dell model?  So that’s what I did, with the help of @modaly_IT & @geodesicz (my personal powershell guy), we came up with this solution.


Goal of Script:  Update Dell Bios on Any Model without having to maintain and update packages.

What it does:

  1. Gets Model info from WMI
  2. Downloads latest Bios directly from Dell
    1. No testing with Proxy server done, you can probably add this into the script, just don’t ask me how. (I don’t know, ask Maurice, he has it figured out in his cool GUI version)
    2. Mark (@Geodesicz) was able to make the changes to have this work in PE.
  3. Applies Bios to system during WinPE
  4. Create variables to do extra steps based on exit codes


  1. Never manually download a BIOS update and build a BIOS package again
  2. Always install the latest Dell BIOS on the system you’re imaging
  3. Works on all dell models, no tracking down a bios per model
  4. See Number 1


  1. Giving up control of the Bios Version you’re installing
    1. This doesn’t bother me personally, I haven’t ever had a BIOS update brick a machine, and if the BIOS is coming directly from Dell, it’s supported by them, and they will assist if anything did happen.
  2. Uses the Internet to pull content, while only 8-12MB per Computer, if you’re imaging large numbers, and you don’t plan ahead, this could be potential issue.
  3. Uses HTML scraping, so if Dell ever changes their website, we’d have to update the script.


The Script… while very similar to my last one, it has some key differences.

  1. The Bios Password is now parametrized, no longer requiring the text file to pull password (Thanks Mark)
  2. Has large download section in which it has the logic to get the right Bios file (from Maurice) & the Actual download step, (from Mark).
  3. Validating the Bios downloaded.

This script is quite simple still, feel free to add additional logic to it for error handling.




in the TS:


Package Content:

As before, it will create logs in the SMSTSLog folder in %temp%.
The only difference now, I added a group that will only run if the Download Fails based on lines 86-90 of the script.

For more details on how to setup the rest, check out the old Post:

Maurice’s new GUI version:

Maurice’s older version, where I stole the code from:

Task Sequence Message / Pause with No Package

I’ve created messages and pauses a couple of ways, a “fancy” way with content, based on Niehaus’s blog, and a simple way just using notepad with no content, which is really handy during times you don’t want (or not able) to pull down content yet.  Nash (@kidmystic) would say to use PowerShell (example at bottom), as he has a nifty one line code that will do it for you. However, if you don’t have PowerShell in WinPE, and want to keep it super simple, just do it this way… with notepad.

In the Task Sequence, where you want to create a pause, or message, create two “Run Command line” Steps.

  1. Run Command Line Step 1 = “Create Pause - Step 1”
    1. cmd.exe /c echo "Pausing Task Sequence for Testing, Close this Box to continue the Task Sequence" >> Pause.txt
  2. Run Command Line Step 2 = “Run Pause - Step 2”
    1. cmd.exe /c notepad.exe Pause.txt

This will work even if the HDD is not formatted, as it does not require content.  To Confirm, I Diskpart –> Clean the HDD so nothing was on it, then ran these steps in WinPE.  Worked perfect.  This is great for if you want to pause / blow up your TS early if it it fails any validations, like Bios Password Missing, or UEFI not enabled, etc.

When you close the Notepad Application, the TS will Resume.



powershell.exe -command (new-object -ComObject Microsoft.SMS.TsProgressUI).CloseProgressDialog() ; (new-object -ComObject'Message Box Text Content goes Here, you can make this as detailed as you want.',0,'Message Box Title in Upper Left',0x0 + 0x30) ; Exit 1

- Set your Exit code to what make sense.  Exit 1 will “Fail” your TS and make it quit, which might be good in times that you want it to fail so something manually can be done. Exit 0 will be success and continue on.