22

I need to create a special account on a computer running Windows 10 Enterprise. This account would launch an application directly on login instead of the default shell and exiting the application should force the computer to restart.

I was able to do this easily on Windows 8.1 Embedded Industry Pro using the configuration console and lockdown features.

Now, on Windows 10 I try to follow the two tutorials on technet WESL_UserSetting and Set up a kiosk on Windows 10 Pro, Enterprise, or Education

However, neither of the tutorials work. I have managed to execute the scripts described in them but they have no effect (I've modified them so they do not remove the shells set).

Finally I've ended up with the following code:

$COMPUTER = "localhost"
$NAMESPACE = "root\standardcimv2\embedded"
$ACCOUNT_NAME = "cmp"

$ShellLauncherClass = [wmiclass]"\\$COMPUTER\${NAMESPACE}:WESL_UserSetting"


$NTUserObject = New-Object System.Security.Principal.NTAccount($ACCOUNT_NAME)
$NTUserSID = $NTUserObject.Translate([System.Security.Principal.SecurityIdentifier]).Value

$NTUser_Shell = Get-WmiObject -namespace $NAMESPACE -computer $COMPUTER -class WESL_UserSetting | 
    where {$_.Sid -eq $NTUserSID}

if ($NTUser_Shell) {
    "`Custom shell already set for [$ACCOUNT_NAME] removing it"
    $ShellLauncherClass.RemoveCustomShell($NTUserSID)
}

$restart_shell = 0
$restart_device = 1
$shutdown_device = 2

$ShellLauncherClass.SetCustomShell($NTUserSID, "cmd.exe", ($null), ($null), $restart_device)

"`nCurrent settings for custom shells:"
Get-WmiObject -namespace $NAMESPACE -computer $COMPUTER -class WESL_UserSetting | Select Sid, Shell, DefaultAction

Executing this script in an admin powershell produces the desired output:

Custom shell already set for [cmp] removing it

Current settings for custom shells:

Sid                                            Shell   DefaultAction
---                                            -----   -------------
S-1-5-21-3842421150-1098587697-2315725148-1002 cmd.exe             1

However logging as the 'cmp' user simply shows the standard Windows 10 shell.

What should I change in order to be able to run a program instead of a standard shell?

Jan
  • 2,060
  • 2
  • 29
  • 34
Jozef Legény
  • 1,157
  • 1
  • 11
  • 26
  • According to your 'Set up a kiosk' link, the following needs to be true: A Universal Windows app that is installed for that account. I don't believe cmd is a universal app. – Eris Nov 05 '15 at 18:56
  • When you scroll down on the site you will see that there is a section about Classic Windows applications. That is where part of this script comes from and they are also using it to launch cmd. – Jozef Legény Nov 06 '15 at 08:49

9 Answers9

12

I had the same problem right now. And yes, Microsoft has changed the way to do a shell replacement. You can install and use the Embedded Shell Launcher to customize windows as you like it for kiosk mode. But this is only available for Enterprise and Education.

If you don't want to buy the Enterprise version you can use the already known registry locations in HKCU and HKLM. https://msdn.microsoft.com/en-us/library/ms838576(v=WinEmbedded.5).aspx

But wait, oh no since Windows 10 it is only possible to use Microsoft signed applications, so your normal .net application isn't started and the screen keeps being black after login. But we've figured out a workaround.

Just use a Batch-File as bootstrapping. If you set the registry keys you like to a Batch-File and the Batch-File starts the real application, then it works like a charm.

@echo off
echo Bootstrapping, please wait ...
start /b "Bootstrap" "C:\vmwatcher\VMViewClientWatcher.exe"
Steven Spyrka
  • 678
  • 7
  • 18
9

Have you tried changing the users shell?

https://msdn.microsoft.com/en-us/library/ms838576(v=WinEmbedded.5).aspx

There are a few registry keys you need to set. First one enables the ability to give the user a unique shell, the second one defines the executable that starts instead of explorer.

kevmar
  • 808
  • 6
  • 6
  • Yes, setting a custom shell works. However I did not find a way to specify the exit-code behaviour, i.e.: I want the system to restart if the application is closed by any means. This is possible to do with the Custom Shell. – Jozef Legény Nov 18 '15 at 12:27
  • 1
    My solution was to execute a powershell script in a hidden window. That script then calls the app and handles the exit code. In my case it was just a log off, but a reboot would be easy to do too. – kevmar Nov 18 '15 at 19:04
  • 1
    This is the solution I went with in the end. Using a custom powershell script which is launched through the registry keys + some Group Policy magick. – Jozef Legény Apr 29 '16 at 16:54
  • 1
    @kevmar can you please share how did you managed to solve the issue of login out of the custom shell, via powershell script. Maybe an article on Medium, thanks, I'm dealing with the same exact issue. – digitai May 02 '17 at 23:37
  • 2
    This does not appear to work on Windows 10 IoT Enterprise – 17 of 26 Dec 06 '19 at 16:17
  • 2
    Setting a custom shell for a single user on Win10 Enterprise 1909 worked fine only by adding a single registry entry at "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell" as a string containing the path to the application. @kevmar 's link worked fine to discover it, but setting the HKLM keys (1 and 2 as per tutorial) did not make a difference towards the custom shell. However I was only able to call .exe applications or similar. In order to open my startup app, I've had to point the registry to a .bat file with commands to run the application. – MZanetti Dec 10 '20 at 11:29
5

I wanted to do something similar, and I borrowed heavily from other answers, but none of them were a complete working answer for me. Here's what I ended up doing.

  1. Create a new user account
  2. Setup the following vbs script (largely inspired by this thread) to launch the shell application and name it something like "launch.vbs"
set oShell=createobject("wscript.shell") 
sCmd="d:\launchbox\launchbox.exe" 
oShell.run sCmd,,true 'true forces it to wait for process to finish 
sCmd="shutdown /r /t 0" 
oShell.run sCmd
  1. Login as the new user

  2. Run regedit

  3. Add a new string value named Shell to HKEY_Current_User\Software\Microsoft\Windows NT\CurrentVersion\Winlogon with a value of the command that you need to run to execute your script:

wscript d:\launchbox\launch.vbs
  1. Logoff and log back on as the user to see it in action
Scott
  • 1,223
  • 2
  • 16
  • 35
4

I battled with this one myself. If you look at the notes for Windows 10 Shell Launcher, it only works in the Enterprise or Education version. If you try using this in Home or Pro versions it simply boots to a blank screen. Using the same script in Enterprise, I confirmed works perfectly...

Michael
  • 41
  • 1
  • 2
    Really frustrating, because the MS TechNet article about this says the shell launcher will work on Pro. And it even lets you enable it... – Weston Wedding Jul 13 '16 at 22:56
3

I think you set up correctly the custom shell for the user, but maybe you need to activate the ShellLanuncher behaviour. Try this (at the end of your script):

$ShellLauncherClass.SetEnabled($TRUE)

This way the standard windows 10 shell is not launched when you log on with the other account, but (at least in my case) the command line does not start and the result is a black screen.

You can still run the task manager and run a new task from there, but I don't understand why the command line does not automatically start.

Giovanni
  • 39
  • 4
  • You are right that I have forgotten this line in my script. However, as you say the program set up as shell does not actually start. – Jozef Legény Mar 14 '16 at 11:28
2

I ran into the same issue, and that's because the Script from TechNet on how to configure ShellLauncher actually enables, then disables the same Shell!

# Enable Shell Launcher

$ShellLauncherClass.SetEnabled($TRUE)

$IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()

"`nEnabled is set to " + $IsShellLauncherEnabled.Enabled

# Remove the new custom shells.

$ShellLauncherClass.RemoveCustomShell($Admins_SID)

$ShellLauncherClass.RemoveCustomShell($Cashier_SID)

# Disable Shell Launcher

$ShellLauncherClass.SetEnabled($FALSE)

$IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()

"`nEnabled is set to " + $IsShellLauncherEnabled.Enabled

I was lazily just copying and pasting the code and expected it to work.

If you comment out the final ten lines, this process will work.

Remember Kids: don't just copy and paste code from Strangers!

Community
  • 1
  • 1
FoxDeploy
  • 12,569
  • 2
  • 33
  • 48
2

I want to begin by apologizing for commenting on a very old thread.

I have struggled for the past 6 months trying to get a custom app to run as a default shell, and retain administrator rights. Like many people, these scripts and/or commands just weren't working, and I needed something quick, effective and EASY!

Simply replacing the "explorer.exe" (HKLM\SOFTWARE\Microsoft\Window NT\Winlogon\Shell) with a custom app location provided a black screen.

A much simpler way, and it works great, was to create a BATCH script to call the custom app through elevated powershell...

powershell -nologo -noprofile -executionpolicy bypass -command "start-process -verb 'runas' -filepath <full path of custom app executable>"

By replacing "explorer.exe" with this batch script I was able to successfully create a kiosk style lockdown under Windows 10 PRO with a non-UWP app.

1

My fist attempt to help where I have received much. Not a complete answer, but maybe enough to get you to your destination. This worked on my "Kiosk" app which is on "my" Windows 10 Enterprise system which was built specifically for my app. It will set your "shell" to start on system startup and then start your click once program. Hope this helps.

Imports System.Threading

Public Class Form1

# Path to your ClickOnce app
Dim startPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Programs) _
& '"\"' & '"remaining path to your app"' & '".appref-ms"'

# Path to your shell which is also a clickonce app(this one)

Dim spath As String = Application.StartupPath & '"\"' & My.Application.Info.AssemblyName _
& '".exe"'

# This sets the registry to start your shell which in turn starts your app. 
# I did this so that if the app is closed, they see the shell background.
# You can add controls to your shell to restart the app, shutdown.... 
#Just be cautious, make sure your app is 100% done and updates on it's own before you 
# disable the ability to get back to windows explorer.
# Other wise you could have a very bad day.

My.Computer.Registry.SetValue('"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\ _
CurrentVersion\Winlogon"', '"Shell"', spath)


Thread.Sleep(500)

Process.Start(startPath)

End Class
HeloDriver
  • 11
  • 1
  • 4
1

You can create a Provisioning Package using Windows Configuration Designer. The gui will help in creating a simple shell replacement when you choose 'provision kiosk devices'

Johan A.
  • 378
  • 3
  • 7