How to run an application as shell replacement on Windows 10 Enterprise - windows

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?

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"

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.

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.
Create a new user account
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
Login as the new user
Run regedit
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
Logoff and log back on as the user to see it in action

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...

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.

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!

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.

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

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'

Related

How to start a program from an existing cmd.exe with the current user environment; as if the user would start the program from the start menu

There are a lot of questions already asking similar things but none helped me:
Start new cmd.exe and NOT inherit environment?
Is there a command to refresh environment variables from the command prompt in Windows?
What i'm f.e. after is:
Create a batch- oder powershell script which
installs python to a system where python isn't installed (this works)
after a successful installation, run python with a python script as argument
(It should also work the same way for installing and using other apps like MSVC, git for windows, ...)
After installing python from a console, the path which has been added to the system environment variables isn't reflected in the current cmd instance environment.
But it's there when i start a new cmd or elevated cmd manually from the windows start menu and not from a script.
I tried the following without luck to update the environment of the existing console or create a new instance with the new user environment from script:
start /i/b&exit
start /i/b "%windir%\explorer.exe" "%windir%\system32\cmd.exe"
powershell -Command Start-Process -UseNewEnvironment -Wait -FilePath python -ArgumentList "test.py"
But for UseNewEnvironment it's documented that
the new process starts only containing the default environment
variables defined for the Machine scope. This has the side effect that
the $env:USERNAME is set to SYSTEM. None of the variables from the
User scope are included
and for start /i that
Ignore any changes to the current environment, typically made with SET. Use the original environment passed to cmd.exe
I think both approaches cannot be used for what i'm after.
Is there a simple possibility to automatically run a script in the new environment which the installer created without extensive code or third party binaries?

Open Excel on Jenkins CI

I am working on Windows 7 (logged in as session no.1), my Jenkins CI is running as windows service in session 0.
My problem is.. I want to open an Excel file through Jenkins CI in session 0, but want to display its GUI on session 1.
I know that session 0 is isolated in Windows 7, but is it possible to run a process in session 0 and then output in another session? please help.
Edit:
Took a little trial and error, but this is what finally worked for me (Windows 7 64-bit).
Download PsTools from Microsoft site
We only need psexec.exe, but you can extract everything. Extract to some location accessible by Jenkins, preferably without spaces in the path.
Open elevated command prompt: type cmd into Start's quicksearch, right click cmd.exe, select Run as Administrator.
Type C:\path\to\psexec.exe -accepteula and press enter.
Type C:\path\to\psexec.exe -i 1 cmd and press enter. (If you see a command prompt appear, all is good, close it now)
In Job configuration, configure Execute Windows Batch command step
Write the following:
C:\path\to\psexec.exe -accepteula && C:\path\to\psexec.exe -i 1 cmd /c start C:\PROGRA~2\MICROSO~1\path\to\excel.exe
Where:
C:\path\to is your full path to psexec.exe, unless it is in your %path%
-i 1 is the session ID that you want to launch in.
C:\PROGRA~2\MICROSO~1\path\to is your full path to excel.exe without spaces. Since most Office installations are going to be under paths with spaces, like "Program Files (x86), you have to figure out the short path, or place it somewhere without spaces.
Having excel.exe under %path% and working from regular command line was not enough.
A little explanation for those that care:
psexec needs to install a services first. For that, it needs to be run from elevated command prompt for the first time. This is a one-time installation step.
To make psexec work, you need to accept the EULA prompt. This is done per session/user. So even if you run psexec -accepteula in your command prompt, it doesn't help when Jenkins service (running as Local System in session 0) tries to use it. Therefore, you have to place that into the Jenkins job, along with the command. Technically, it only needs to be there once, and can be removed afterwards, but it definitely doesn't hurt to keep it there.
I've used cmd /k and running this command from my local cmd prompt to debug. This is what made me realize I couldn't find a way to escape the spaces (tried various quoting), so had to resort to short file names. Note that short file names are not required, this is just to escape spaces.
no its not-
plus any UI interactions requires you to run Jenkins as Java web start rather than a service or you can not interact with UI elements.

how do I run an msi with SEE_MASK_NOZONECHECKS without restart

I'm trying to install a driver with a remote framework that lets me run shell commands spawned as children of the remoting/monitoring app on the remote machine, run as cmd /c "command". But the driver refuses to install due to a security feature which thinks the driver may be unsafe.
The driver also has quotes(spaces in path) so its something like
Dim command: command = "\\\\server\\driver\\folder\\Autorun.exe" /passive /norestart";
Set retVal = remote.Shell(command)
which runs
cmd /c " "\\server\driver\folder\Autorun.exe" /passive /norestart"
on the remote machine
I've tried and have had trouble using setx SEE_MASK_NOZONECHECKS 1 /m in a previous statement, I'm guessing that the subprocess don't see new global enviromental variables that weren't around when it's parent started, and won't work without a restart. I'd like to avoid a restart.
I tried running
cmd /c " set SEE_MASK_NOZONECHECKS=1 & "\\server\driver\folder\Autorun.exe" /passive /norestart"
but it doesn't seem to work. Any ideas?
You got a bit lost on the way SEE_MASK_NOZONECHECKS is used. It is not an environment variable and cannot be tinkered with from the command prompt, it is an option for ShellExecuteEx(). A winapi function that you indeed use to start programs. It isn't very clear what programming tools you have access to, using it in a batch file or VBScript isn't going to work. You'd need at least, say, VB.NET and pinvoke the function. You can get the required declarations from the pinvoke.net web site.
Let's talk about what's really going on, you might find a simpler solution. When you download a file from an Internet web site, Windows adds an extra stream to the file that indicates where the file came from. Which basically states "this file did not come from a safe place" and makes the driver installer balky. Which is rather an important feature if you think about it, your user is going to install software that can do a lot, you pretty much have free reign of the machine if you can get a driver installed.
If you right-click the file in Explorer and click Properties then you'll see this at the bottom of the window:
All that's needed is to click that Unblock button. So this is a simple way for your user to solve the problem. You could document the extra step in the install instructions. Also with the advantage that it is now the user that took responsibility of allowing potentially unsafe code to be installed.
Other ways to get the file unblocked is with PowerShell's Unblock-File command and the SysInterals' streams utility, -d option.
And you probably ought to consider the option of writing your own installer. Which will keep the driver packaged in the setup file so it won't be tinkered with by Windows. And the user gets the warning when he starts the installer instead. And it can be signed so the user has some confidence in where the file came from and that it didn't get messed with on its way to his machine. There are many utilities that help you write an installer, like InstallAware, InstallShield, NSIS, etcetera.
I beg to differ to Hans' answer:
Of course, SEE_MASK_NOZONECHECKS is as well a predefined environment variable. Changing it in a process and then starting a child process (e.g. msiexec.exe) which by defaults inherits the environment, has just the same result as using ShellExecuteEx() and providing SEE_MASK_NOZONECHECKS as a parameter to the SHELLEXECUTEINFO structure. The first method is preferred by admins or quick hacks, e.g. if you work with batch or script files which set the environment variable- or when the final call to the .msi file lying on the unsafe network drive is not done by your own code.
For example:
#echo off
set SEE_MASK_NOZONECHECKS=1
call msiexec.exe /i "\\MY_UNC_DRIVE\installs\mysetup.msi /qb /L*v "c:\logs\mysetup.log"
call "\\MY_UNC_DRIVE\installs\Just_another_setup.exe"
If you already use a ShellExecuteEx() in your code, then of course, go with the parameter as Hans mentioned, because this implementation it is more closed. (If you use CreateProcess(), think about using ShellExecuteEx() instead.
Getting back to the environment variable(s). Generally you cannot influence the environment of already started processes. You can set the default environment used by NEW processes by the "setx" command used in the question. But with "setx" you don't change the environment for your current process.This was the problem in question. For this you have to use "set" as shown. So either use both commands after each other or don't use setx at all because for running a setup on foreign machines, it is not clean to make permanent security changes without asking.
For more details on permanent changes/admin point of view, see:
https://superuser.com/questions/595211/removing-the-open-file-security-warning-in-windows-8/934283#934283
Important: As mentioned, there is no general way in Windows to influence processes which already run (only own-defined inter-process-communication maybe), so it is important to set the environment variable before starting the setup to be influenced.
One more thing: Some people think, one must use "SETLOCAL" in a batch file. Normally this is not necessary. Environment changes with "set" are not permanent, and do not incluence "other" processes- they are only inherited to subprocesses and, partly, to superprocesses. But, when the caller on first level ends, the environment is reverted to original state again.
I ended up setting "Launch applications and unsafe files" to enabled for Internet zone in Internet Explorer options under security(custom level) and then exporting the changes from HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3 to a registry file and adding it with regedit /s.
After that I can run the installer of the shared drive.
One of these days I'll pare the registry file down to the minimum I guess.
P.S. I believe this causes IE to default to a warning page on startup.
I believe you need to put everything within the same quotation:
cmd /c "set SEE_MASK_NOZONECHECKS=1 & \\server\driver\folder\Autorun.exe /passive /norestart"
You can try these and see the difference in the output:
cmd /c "echo foo & echo bar"
cmd /c "echo foo" & "echo bar"

auto run a bat script in windows 7 at login

I have recently acquired a windows 7 laptop from my late grandmother.
I have been using it for work and other things. I decided to create a VM using VirtualBox And now I want to create a user on the (Windows 7 Host) machine so that when I log into that user it autoruns a .bat script to start the VM. To make it clear I only want to run it only if the user "VM" logs in and not my normal user and it would be super awesome if it would autostart in full screen. I have a shortcut on my desktop that executes the command:
"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "VM" --startvm "12dada4d- 9cfd-4aa7-8353-20b4e455b3fa"
but how do I make an autorun.bat when I log into the User "VM"?
To run the batch file when the VM user logs in:
Drag the shortcut--the one that's currently on your desktop--(or the batch file itself) to Start - All Programs - Startup. Now when you login as that user, it will launch the batch file.
Another way to do the same thing is to save the shortcut or the batch file in %AppData%\Microsoft\Windows\Start Menu\Programs\Startup\.
As far as getting it to run full screen, it depends a bit what you mean. You can have it launch maximized by editing your batch file like this:
start "" /max "C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "VM" --startvm "12dada4d-9cfd-4aa7-8353-20b4e455b3fa"
But if VirtualBox has a truly full-screen mode (where it hides even the taskbar), you'll have to look for a command-line parameter on VirtualBox.exe. I'm not familiar with that product.
I hit this question looking for how to run batch scripts during user logon on a standalone windows server (workgroup not in domain). I found the answer in using group policy.
gpedit.msc
user configuration->administrative templates->system->logon->run these programs at user logon
add batch scripts.
you can add them using cmd /k mybatchfile.cmd if you want the command window to stay (on desktop) after batch script have finished.
gpupdate - to update the group policy.
Just enable parsing of the autoexec.bat in the registry, using these instructions.
:: works only on windows vista and earlier
Run REGEDT32.EXE.
Modify the following value within HKEY_CURRENT_USER:
Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ParseAutoexec
1 = autoexec.bat is parsed
0 = autoexec.bat is not parsed

How to change cscript.exe to wscript.exe execution for all VBScript files?

After installing the new server, I am facing an issue.
I have lot of .vbs files, all need to run in wscript, reason, I use all those command like WScript.Echo "hello"
I want to be able to see the output when I double click the VBScript file.
But when I right click on the vbs file, I see console, I want to change the default to Windows host, globally!
How can I do that?
You can change the default scripting host to wscript.exe like so:
wscript.exe //H:wscript
If you wish to set cscript as the default host, that works in the same way:
wscript.exe //H:cscript
You can execute cscript.exe with the same arguments for the same result.
You can switch the default script engine with:
wscript //H:Wscript
Good luck!
I was able to solve it by using the following steps:
selecting the VBScript file that I want to open,
right click to select default program for this,
browse to C:/windows/windows32/wscript.exe, and select this.
In command prompt (as administrator):
To set windows script host as default script host enter:
wscript.exe //H:WScript
To set command line based script host as default script host enter:
cscript.exe //H:cscript
Check the Windows Explorer settings for the filetype *.vbs (something like tools->options->file types etc.) and change the "open with" setting to cscript.
Edit: I now advise caution with the recommendations I give below. After continuing to toggle and test my settings, I find I am unable to re-establish cscript as my default script host. (Note that I also retried the procedures given by other answers to this question.)
In addition, I tried using Process Monitor (a.k.a., "ProcMon") to find the reason for my difficulties, but unfortunately have not been unsuccessful.
Finally, I also considered going back to an earlier Windows 7 restore point, but this was complicated by the fact that I just yesterday changed my domain password. So, for now, I'm going to have to put my investigation to rest as other tasks are pressing.
On last thought...I have also considered the possibility that there are network policy security settings that are thwarting my efforts.
Original Answer: Enter the following line in a Windows batch file:
ftype VBSFile="%%SystemRoot%%\System32\WScript.exe" "%%1" %%*
Then, run a Command Prompt as an Administrator and run the batch file.
I believe the above will make the change for all users on the system. To make the change for only the logged in user, do the following (on Windows 7):
Control Panel => Programs => Default Programs => Associate a file type or protocol with a program
Then, in the Name column, scroll down to .vbs and click Change program... in the upper right. Then choose one of the Recommended Programs. If you do not see Microsoft ® Windows Based Script Host, browse to the following file:
C:\Windows\System32\wscript.exe
The guy above who right-clicked to choose the default program was right, however the path should be: C:\Windows\System32\wscript.exe

Resources