Follow-up on "Setting color for *all* CMD shells based on admin/elevation status"


[Updated, 2007-06-27] 


This is the (overdue) follow-up to my earlier blog post about setting the color and title of all CMD windows based on the admin/elevation status of that window.


First of all, as some commenters noted — and as I had discovered as well — having the COLOR command run in the CMD autorun causes strange build failures in Visual Studio (at least in C++ projects) when it invokes commands via CMD.  My workaround is to specify the COLOR command only in the branch that I don’t run Visual Studio in.  E.g., I always run Visual Studio as a non-admin, so I keep the “COLOR FC” statement in the admin branch, and don’t run any COLOR statement in the non-admin branch.  If you always build as an elevated/admin, then you should reverse that so that the COLOR statement runs in the non-admin branch — or don’t use COLOR to differentiate and instead just use TITLE.


[Added 2007-06-27]  It turns out that following COLOR with a single ampersand and another command makes the build problem go away!


Second, Pavel suggested a more portable test than bootcfg/bcdedit:  cacls.exe %windir%\system32\config\systemprofile.  That folder grants access only to Administrators and the SYSTEM account; cacls.exe fails with “access denied” unless you’re running as elevated/admin.  I don’t know whether that folder exists on Windows 2000, but the test definitely works on XP, 2003, and Vista.


[Added 2007-06-27]  But as “anonymous” points out in the comments below, FSUTIL works, too, and is a lot easier to type.


Third:  CMD on Vista already prepends the word “Administrator” in the window title if it’s running with an enabled Administrators SID in its token, so it’s redundant for the autorun to append it.  (Not true on XP/2003, of course.)


Fourth:  why not put the current username into the title as well?  Good idea!  I’ve added that to my current config.


So, now my current CMD autorun looks like this: [Updated 2007-07-05 with full path to FSUTIL]



%windir%\system32\FSUTIL.exe > nul 2> nul && (color FC & title %USERDOMAIN%\%USERNAME%) || (color 07 & title NONADMIN – %USERDOMAIN%\%USERNAME%)


One minor point is that unlike the CMD /T option, COLOR sets only the current color — not the default color — for the current window.  If you run the COLOR command in that window, it will revert to the default color for the window — either the user account’s default setting or that set by a /T option when the CMD was started.


So… let me go on record by saying that while Microsoft has made a lot of fine products, Windows PowerShell is the coolest and most revolutionary technology we have shipped in a very long time.  (But that’s as off-topic as I’m going to get on the subject.)  PowerShell is gradually becoming my default command shell, so naturally I’d like to be able to distinguish between elevated and non-elevated instances, both with color and with the window title.  Starting with what commenters wrote on my previous post, here’s what’s in my $profile now:



function Get-AdminStatus
{
    $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $p = New-Object System.Security.Principal.WindowsPrincipal($id)
    return $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}


$AmIAdmin = Get-AdminStatus
if ( $AmIAdmin )
{
    cmd.exe /c COLOR FC
}



# Make the window title follow the current directory
function prompt
{
    ‘PS ‘ + $(Get-Location) + $(if ($nestedpromptlevel -ge 1) { ‘>>’ }) + ‘> ‘
    if ( $AmIAdmin )
    {
        $host.UI.RawUI.WindowTitle = “Administrator: ” + $(Get-Location)
    }
    else
    {
        $host.UI.RawUI.WindowTitle = $(Get-Location)
    }
}


 

Comments (11)

  1. anonymous says:

    Ehm… why don’t you simply use FSUTIL? For non-admin privileges (due to its LUA problem) it returns with error code 1, which is best for the cmd.exe shell.

    BTW, what is this PingBack SPAM all about?

    @anonymous:  Excellent idea — FSUTIL works fine for this purpose on both XP and Vista.  And a lot shorter than the cacls command line.

    I deleted one instance of the pingback.  It happens whenever a blog post references another blog post.

    — Aaron

  2. MSDN Archive says:

    Even better choice may be AT.EXE since it exists in Windows 2000 while FSUTIL.EXE was new to Windows XP.

    Al

    @Al:  I haven’t tested the use of AutoRun on 2000, but I would guess that it would work the same way.  And AT.EXE is definitely more portable for this purpose.  Thanks!

    — Aaron

  3. anonymous says:

    Oh oh… two big issues there:

    At first, I patched fsutil so it runs without admin privileges, since some of its functionalities (hardlinks, sparse, files) don’t require either. Now it has become unsuitable for this purpose. Better go bck to cacls.

    The second problem is that is invokes the program from the current directory. If you have a malicious cacls.exe (or a freshly patched fsutil.exe) laying around and you’re launchung the shell from the explorer context menu, it will execute the local program, which is a security vulnerability. One should always reference it with the complete path, thus %windir%system32cacls.exe.

    [Aaron Margosis] Hopefully you’re first “big issue” won’t affect anyone else.  (Patching system binaries is… risky.  BTW, on Vista, “mklink /h” now lets standard users create hard links).  You are absolutely correct about the second issue — I’ll update the post accordingly.

    Note though that when you choose “Run as administrator”, the current directory is set to %windir%system32, so that attack won’t work in the elevated case.

  4. Hofi says:

    Just a tiny correction. You should use

    %SystemRoot% because %windir% is does not exist in a command.com

    [b]%SystemRoot%system32FSUTIL.exe > nul 2> nul && (color FC & title ADMIN – %USERDOMAIN%%USERNAME%) || (title NONADMIN – %USERDOMAIN%%USERNAME%)[/b]

    works fine both for cmd.exe and command.com

    [Aaron Margosis] But command.com doesn’t invoke the AutoRun line anyway, does it?

  5. Hofi says:

    If ntcmdprompt present in config.nt then AutoRun will be invoked.

    Give it a try, on my XP SP2 box that is the way it works.

  6. anonymous says:

    Patching system binaries is… risky? Come on, it’s IDA Pro with the PDB debug data, and seeing a

    call _IsUserAdmin(void)

    test eax,eax

    jnz short check_params_and_run

    complain_not_admin()

    is obvious. Now it’s just 6 NOPs and making the jump unconditional. And then loading it into IDA and checking it again.

    Sorry, this really can’t go wrong.

    For the command.com issue: Huh? command.com? Does this thin even exist? And I though it just launched cmd.exe. Anyway, %windir% exists on command.com since Windows 95, but %systemroot% might not.

  7. Hofi says:

    I’ve tried it once again.

    There is no %windir% environment variable just %systemroot%.

    Tried it on XP SP2 fully patched and a clean Vista installation also.

    start cmd.exe

    type

    set

    check for %windiw%

    You will find it.

    type command.com

    type

    set

    check for %windir%

    You won’t find it

    (i’ve checked that it is not depending on the ntcmdprompt, %windir% is not defined in XP and Vista command.com)

  8. Daniel says:

    Hi is it possible to close all command shells from one command shell?

    [Aaron Margosis] Not that I’m aware of.

  9. MSDN Archive says:

    @Daniel

    You can try "TASKKILL /IM cmd.exe". It should work if the cmd shell you are running the command in is the last one open otherwise it’ll be killed before all other cmd windows are closed.

    Or you can write a script that will determine PID of cmd process it is running under and skip it while closing all other windows. I’m not sure though it is what you’re after.

  10. Sam Black says:

    Is there any way to get Vista to *NOT* put “Administrator” in the title (or at least not at the beginning of the title)? When you’ve got multiple command windows open, it’s impossible to tell which is which on the task bar.

    [Aaron Margosis] There’s no way built into Windows to do that.  But a custom program that calls the SetWindowText Windows API can change the title to anything you want it to (*).  But if CMD changes its own title to something else (e.g., using the “TITLE” command) it will prepend “Administrator:” (or non-English equivalent) again if running in an elevated context.

    (*) Note that this is subject to change at any time.

  11. 0jThank’s.7s I compleatly disagree with last post .  xle

    <a href="http://skuper.ru">паркет</a&gt; 8k