Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ShellExecute with "RunAs" verb ignores the working directory argument

148 views
Skip to first unread message

JJ

unread,
Mar 20, 2019, 10:31:03 AM3/20/19
to
I'm trying to write a script for Win7 that will run a program with elevated
priviledge. Just like what the "Run as administrator" context menu does. I
know that this is done by using shell with the "RunAs" verb instead of the
default "Open" verb. However with "RunAs" verb, the working directory
argument passed to the ShellExecute is ignored, and I always end up getting
the Windows' SYSTEM32 directory as the working directory instead.

Here's the "elevate.vbs" script. Note: everything here are minimal code for
the sake of reproducing the problem.

cd = createobject("wscript.shell").currentdirectory
wscript.echo "elevate.vbs: " & cd
set sh = createobject("shell.application")
sh.shellexecute wscript.arguments(0), wscript.arguments(1), cd, "runas", 1

Here's the "test.vbs" script that I use for testing.

cd = createobject("wscript.shell").currentdirectory
wscript.echo "test.vbs: " & cd

When I tested it, I use non elevated Command Prompt with "E:\WORK" as the
current directory. All of the script files are in this directory. If I use
below command line:

elevate wscript test.vbs

"elevate.vbs" script shows the message box with the correct working
directory:

elevate.vbs: e:\WORK

But the elevated WSCRIPT complained with this error message box:

Can not find script file "C:\Windows\system32\test.vbs".

Now if I use full path to the "test.vbs" file like this:

elevate wscript e:\work\test.vbs

"elevate.vbs" script shows the same message as expected, but the elevated
"test.vbs" script shows this message:

test.vbs: C:\Windows\system32

Meaning that the "RunAs" verb did ignored or messed up the given working
directory. FYI, if the Command Prompt is already elevated, everything works
fine. So is there a solution other than manually readjusting the working
directory?

Mayayana

unread,
Mar 20, 2019, 1:46:59 PM3/20/19
to
"JJ" <jj4p...@vfemail.net> wrote

| Meaning that the "RunAs" verb did ignored or messed up the given working
| directory. FYI, if the Command Prompt is already elevated, everything
works
| fine. So is there a solution other than manually readjusting the working
| directory?

Just guessing as I'm not on a restricted system. My
first guess would be that, of course, why should it
cooperate with a programmatic attempt to elevate?
That would defeat the purpose of restrcitions.

My second guess is... what? I can't find ShellExecute
as being available either in the WSH docs or in Win7
MSDN for the Shell object. I've only seen it as an
API call. Nor do I see it in the typelib on XP.

This is a longshot, but you might test this:

MsgBox WScript.ScriptFullName
Set SH = CreateObject("WScript.Shell")
MsgBox sh.CurrentDirectory
Set sh = Nothing

That will not always return the same path for both. The
first is the path of the script. The second can vary. You
may be getting the path of cscript parent folder.


JJ

unread,
Mar 21, 2019, 10:48:11 AM3/21/19
to
On Wed, 20 Mar 2019 13:45:13 -0400, Mayayana wrote:
> "JJ" <jj4p...@vfemail.net> wrote
>
>| Meaning that the "RunAs" verb did ignored or messed up the given working
>| directory. FYI, if the Command Prompt is already elevated, everything
> works
>| fine. So is there a solution other than manually readjusting the working
>| directory?
>
> Just guessing as I'm not on a restricted system. My
> first guess would be that, of course, why should it
> cooperate with a programmatic attempt to elevate?
> That would defeat the purpose of restrcitions.

Well, the shell framework itself is automatable. Be it from a VBScript, or
any native application that can use COM. The shell's "runas" verb is a known
method to run an application elevated. The UAC is the one which is
responsible for allowing the elevation or not, by showing the UAC prompt.

> My second guess is... what? I can't find ShellExecute
> as being available either in the WSH docs or in Win7
> MSDN for the Shell object. I've only seen it as an
> API call. Nor do I see it in the typelib on XP.

The ShellExecute is a method of the IShellDispatch2 interface, but MSDN
separate it from the Shell automation object. The Shell automation object
actually implements multiple interfaces: IShellDispatch, IShellDispatch2,
IShellDispatch3, and IShellDispatch4; for shell versions that support those
interfaces. IShellDispatch is the main interface for the Shell object. It's
just like the FolderItems object which also implement FolderItems2 and
FolderItems3.

> This is a longshot, but you might test this:
>
> MsgBox WScript.ScriptFullName
> Set SH = CreateObject("WScript.Shell")
> MsgBox sh.CurrentDirectory
> Set sh = Nothing
>
> That will not always return the same path for both. The
> first is the path of the script. The second can vary. You
> may be getting the path of cscript parent folder.

I only use CurrentDirectory which is already proven as correct by
"elevate.vbs", and that same directory is also used for ShellExecute's
working directory argument.

If "elevate.vbs" (i.e. the parent process) is already elevated, the child
process (i.e. "test.vbs") will have the correct working directory
("test.vbs" shows that too, using CurrentDirectory).

However, if "elevate.vbs" (i.e. the parent process) is not elevated, the
child process (i.e. "test.vbs") will *not* have the correct working
directory ("test.vbs" shows that too, using CurrentDirectory).

None of the script is modified, and the same command line is used, to
reproduce both results.

To sum it up, all of below conditions must be met in order to reproduce the
problem.

1. Windows version is Vista or later.

2. Parent process is not elevated.

3. Working directory of parent process is not Windows's SYSTEM32 directory.
e.g. is not "c:\windows\system32"

4. Child process is executed using VBScript using Shell object's
ShellExecute method.

5. When calling ShellExecute, parent process' working directory is used for
the working directory (vDirectory) argument, and "runas" is used for the
verb (vOperation) argument.

Expected result:
The initial working directory of the child process is same as parent
process'.

Actual result:
The initial working directory of the child process is always the Windows's
SYSTEM32 directory.

Mayayana

unread,
Mar 21, 2019, 11:36:05 AM3/21/19
to
"JJ" <jj4p...@vfemail.net> wrote

| The ShellExecute is a method of the IShellDispatch2 interface, but MSDN
| separate it from the Shell automation object. The Shell automation object
| actually implements multiple interfaces: IShellDispatch, IShellDispatch2,
| IShellDispatch3, and IShellDispatch4; for shell versions that support
those
| interfaces. IShellDispatch is the main interface for the Shell object.
It's
| just like the FolderItems object which also implement FolderItems2 and
| FolderItems3.

Interesting. Thanks. I never noticed that. This is really obscure.
2,3,4,5 haven't been added to the original shell object listing,
but they're in the help file from the Win7 SDK. But runas is
undocumented. Secrets within secrets.

At first I was excited, but aside from what you're doing
and the ability to stop/start services (which can be done
with WMI) they haven't added anything interesting.

I found this, in case it's useful:

https://ss64.com/vb/shellexecute.html

"When a script is run with elevated permissions several aspects of the user
environment may change: The current directory, the current TEMP folder and
any mapped drives will be disconnected."

JJ

unread,
Mar 23, 2019, 12:11:34 AM3/23/19
to
On Thu, 21 Mar 2019 11:34:16 -0400, Mayayana wrote:
>
> At first I was excited, but aside from what you're doing
> and the ability to stop/start services (which can be done
> with WMI) they haven't added anything interesting.

That no longer apply to Windows Vista and newer versions.

> I found this, in case it's useful:
>
> https://ss64.com/vb/shellexecute.html
>
> "When a script is run with elevated permissions several aspects of the user
> environment may change: The current directory, the current TEMP folder and
> any mapped drives will be disconnected."

I guess "runas" verb in IShellDispatch2.ShellExecute is bugged. The flat
API's ShellExecute/Ex function seems to be the only ones that handle it
reliably.

Mayayana

unread,
Mar 23, 2019, 9:29:37 AM3/23/19
to
"JJ" <jj4p...@vfemail.net> wrote

| > At first I was excited, but aside from what you're doing
| > and the ability to stop/start services (which can be done
| > with WMI) they haven't added anything interesting.
|
| That no longer apply to Windows Vista and newer versions.
|

No longer applies? What? WMI is still there. Do you mean
shell ability to stop/start services was removed? I have Win7
help files for WMI and Shell, from the Win7 SDK. I don't
see anything discontinued.


JJ

unread,
Mar 24, 2019, 2:37:24 AM3/24/19
to
Everything is still there, but to start/stop a service requires an elevated
process, or the SYSTEM account. Even if the user is already a member of the
Administrators group, it still require elevation.

Some other things also require elevation. e.g. changing process priority to
Real Time.

Mayayana

unread,
Mar 24, 2019, 11:19:23 AM3/24/19
to
"JJ" <jj4p...@vfemail.net> wrote

| > No longer applies? What? WMI is still there. Do you mean
| > shell ability to stop/start services was removed? I have Win7
| > help files for WMI and Shell, from the Win7 SDK. I don't
| > see anything discontinued.
|
| Everything is still there, but to start/stop a service requires an
elevated
| process, or the SYSTEM account. Even if the user is already a member of
the
| Administrators group, it still require elevation.
|

I guess I've never needed to do that, but I don't
see any issue. Can't you just run a script or HTA
elevated? My impression was that the only total
loss in a restricted system was drag-drop, because
there's no way to right-click -> Run as Admin when
you drop a file onto a VBS.

In other words, I've written tools that use WMI
in VBScript to manage services on XP. If I used Win7
very much I imagine it might be useful for me to
write a similar tool for that. Is there any reason I
couldn't just right-click my HTA and choose Run
as Admin, and thereby have it fully functional? Are
you saying I'd need to log on as the real admin to
do that?


Thomas Langer

unread,
Mar 24, 2019, 5:50:34 PM3/24/19
to

JJ

unread,
Mar 25, 2019, 9:12:41 AM3/25/19
to
On Sun, 24 Mar 2019 11:17:34 -0400, Mayayana wrote:
>
> I guess I've never needed to do that, but I don't
> see any issue. Can't you just run a script or HTA
> elevated? My impression was that the only total
> loss in a restricted system was drag-drop, because
> there's no way to right-click -> Run as Admin when
> you drop a file onto a VBS.

The point of using VBScript is to automate things. If manually
right-clicking on the file then choose Run as administrator is acceptable,
then I wouldn't need VBScript in the first place. Moreover, the context menu
of *.vbs file doesn't have a "Run as administrator" menu, like *.bat file
does.

> In other words, I've written tools that use WMI
> in VBScript to manage services on XP. If I used Win7
> very much I imagine it might be useful for me to
> write a similar tool for that. Is there any reason I
> couldn't just right-click my HTA and choose Run
> as Admin, and thereby have it fully functional?

Batch files and VBScript that start/stop service(s), and works in WinXP,
won't work in Vista+ unless it's run elevated. Without elevation, the
start/stop service action would be denied by the system.

> Are you saying I'd need to log on as the real admin to do that?

No. The "Run as administrator" context menu is not the same as running a
process using a different user. You can find out more about UAC here:

https://en.wikipedia.org/wiki/User_Account_Control

Mayayana

unread,
Mar 25, 2019, 10:54:20 AM3/25/19
to
"JJ" <jj4p...@vfemail.net> wrote

| The point of using VBScript is to automate things. If manually
| right-clicking on the file then choose Run as administrator is acceptable,
| then I wouldn't need VBScript in the first place.

Ah. I typically run them by mouse. Or in an HTA.
I can see what you mean if you're doing something
like putting them in the startup folder.

| > Are you saying I'd need to log on as the real admin to do that?
|
| No. The "Run as administrator" context menu is not the same as running a
| process using a different user.

I didn't mean just a different user. I meant the
"Administrator" user. The real admin. I wrote a program
to remove file restrictions easily, for instance. It
works fine with Run as Admin. But it would also work
fine if I logged in as Administrator, because that user
really is an admin. :)

If I ever get stuck running on NTFS I might just
do that -- use the Administrator account.


0 new messages