20

Problem Statement: What is the most elegant and robust way to test if Cygwin mintty bash session is "Run as adminstrator"?

Why, specifically? I have typically several mintty terminals open when using Windows (mintty does not have tabs). The most awkward is when I need to find a terminal window that I started by right-clicking "Run as administrator" when for example I want to run ping or other one-time procedure. I would like to indicate the "run as administrator"-ness of the terminal session visually (by changing the bash shell prompt variable PS1 in my start-up file ~/.bashrc).

Some quick potential solutions:

  1. I can compare the value of some environmental variables. By quick look of env output there are quite many differences. It is however hard to tell which is most reliable in terms of portability to another Windows machine (perhaps running different version of Windows).
  2. id, more specifically id -Gn shows different groups if run as administrator. In my Windows 7 machine I have Administrators and root groups added to the list. Again, I am not sure if this is portable.
  3. I could try to write a file to a location that would fail as normal user. But I do not want to write any files to strange places - this could in some imagined scenarios be potentially destructive (e.g. failing storage media) and this seems utterly inelegant to my taste.
  4. Running some Windows program that will indicate by return status or output if the command is run "as administrator". Best would be some with analogous purpose to that of UNIX id(1) command (but natively existing in Windows - or Cygwin, but without too far fetched translation of Windows system concepts to POSIX emulated concepts).

Any better or more elegant suggestions? Perhaps cygwin provides a command utility dedicated for this purpose?

Update: 97% duplicate of https://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights/ - the difference is just here using bash instead of (IMHO weird and archaic) Windows cmd.exe. Please do check the answers and commentaries there.

13
  • use the "run as Administrator" unless you do this then the process is not elevated to Administrator permissions even if an Administrator account starts the process. Just create a shortcut so this is always done.
    – Ramhound
    Oct 15, 2013 at 13:17
  • 1
    I recommend trying ConEmu. It has tabs, can run tab as administrator indicated by different icon in tabbar and most importantly uses console behind the scenes so native windows applications work on it correctly unlike on mintty.
    – Jan Hudec
    Oct 15, 2013 at 13:51
  • 2
    @Ramhound You are right that my original problem (distinguishing the administrator terminal window) that I already had narrowed down into this question could be solved by making a short cut for mintty that 1. runs as administrator, 2. uses different configuration file with differing color settings and 3. uses an alternative icon. If you describe to general public how to create this, I will give you an upvote (unless you say in your answer that it cannot be done within a script :-).
    – FooF
    Oct 15, 2013 at 14:07
  • 1
    @FooF - Just because you run a process with an Administrator level user does not mean the process itself has been escalated. Windows by default will only esclate a process if the user approves of such action hence the "run as Administrator" feature in Windows. You can also provider ALL permissions to ANY group you want even the Foo user group if you wanted.
    – Ramhound
    Oct 15, 2013 at 14:12
  • 1
    @FooF - Just think it as sudo which is required even if you are running as a root user.
    – Ramhound
    Oct 15, 2013 at 14:55

6 Answers 6

14

I just wrote this function for the same reason. I never know which shell has admin privileges.

function isadmin()
{
    net session > /dev/null 2>&1
    if [ $? -eq 0 ]; then echo "admin"
    else echo "user"; fi
}

It adapted from this answer https://stackoverflow.com/a/11995662/307968 for windows cmd shell. Net Session returns 0 status if you are admin.

Now I just need to change my prompt, or maybe the titlebar color....

7
  • Nice find. Though there seems to be edge cases where this too fail, if you check the stackoverflow comments.
    – FooF
    Jul 19, 2016 at 10:08
  • Nevertheless I accepted this answer because it points to a much comprehensive discussions (the stackoverflow question and the accepted answer there currently have scores of 147 and 255, respectively).
    – FooF
    Jul 19, 2016 at 10:27
  • Thanks! I use this to selectively color the username in my prompt. If the sell is elevated, I color it red, otherwise green. Useful to keep track of which shells are elevated if you have many terminal windows open. Feb 12, 2019 at 10:46
  • This work well for MINGW64 used by Git Bash on Windows. Jul 19, 2022 at 6:37
  • @FooF These questions and answers have multiple comments. Which one mentions the edge cases where this will fail? Sep 13, 2023 at 1:41
20

The definitive answer to this question comes from the Cygwin mailing list. A process is running with Administrator rights if the user who started it is part of group 544 (Administrators). Also from the comment below by Cromax, it seems that group 114 (Local account and member of Administrator group) is also sometimes present. The test for these two groups is

id -G | grep -qE '\<(114|544)\>'

or in bash without external calls,

[[ "${GROUPS[@]}" =~ (^| )(114|544)( |$) ]]

For example,

id -G | grep -qE '\<(114|544)\>' && echo admin || echo user

In the past you also needed to check for group 0, the root group in /etc/group. But /etc/group is no longer installed in Cygwin, and should usually be removed if it's present, so it's no longer recommended to check for group 0 too.

3
  • 1
    Unfortunately this doesn't work in Mingw/Msys. Steven's answer does, although only on Windows 7.
    – sparrowt
    Mar 14, 2016 at 10:04
  • 1
    I've just tried that (on W7) and it didn't work, but I've noticed, that if Window's user one is logged as is also an administrator, then when when Cygwin is ran as administrator, there is another group that pops in id's output, namely 114 (Local account and member of Administrator group). So the regexp should be updated to: id -G | grep -qE '\<(114|544)\>' && echo admin || echo user
    – Cromax
    Jan 9, 2018 at 20:51
  • Thanks. I haven't seen that myself, but I see that group 114 does seem to be an Administrators group, so it seems reasonable to check for it too. I revised the answer. Jan 10, 2018 at 16:05
7

I use the return value of the Windows program at. I also recreated the functionality of the PROMPTING special character \$.

# Set a white $ initially
eStyle='\[\e[0m\]$'

# If 'at' succeeds, use a red # instead
at &> /dev/null && eStyle='\[\e[0;31m\]#\[\e[0m\]'  # Use # in red

PS1='\n\[\e[0;32m\]\u@\h \[\e[0;33m\]\w\[\e[0m\]\n'"$eStyle "

Examples

5
  • Assuming there is no equivalent of UNIX id command in Windows, I accept this as a correct answer. At least running at command without any arguments does not appear to have any side effects. I am going to use this method in my .bashrc file from now on! Thanks for the hack.
    – FooF
    Mar 3, 2014 at 11:57
  • 1
    doesn't seem to work on windows8.1
    – zzapper
    Oct 7, 2014 at 15:18
  • 1
    @zzapper Please be more specific. What happens / doesn't happen? Error messages?
    – Steven
    Oct 7, 2014 at 16:00
  • 4
    id returns same values, at is deprecated use schtasks.exe instead but this works whether admin or not
    – zzapper
    Oct 7, 2014 at 16:15
  • Win 10: The AT command has been deprecated. Please use schtasks.exe instead. I'm not sure how to achieve the same outcome with the latter. Sep 13, 2023 at 1:32
2

Do something that only admin could do and test for success or fail:-

if touch c:/Users/.x ; then  echo 'ok'  ; fi

or

touch c:/Users/.x && echo ok

or

touch c:/Users/.x && \rm c:/Users/.x && echo ok

or

touch c:/Users/.x  &> /dev/null && \rm c:/Users/.x && echo you are admin
2

id -G | grep -qE '\<(544|0)\>' didn't seem to work for me, as my output had neither <> or 544 even when elevated. However, since elevation is required for writing to %WINDIR%\system32, I used that to test for elevation with a shell function:

is_elevated() { 
   [[ $(uname -o) -eq "Cygwin" ]] || return 1
   touch $WINDIR/system32/.cyg_elevated &> /dev/null
}

When applied to Steven's excellent idea of a red hash character:

is_elevated && PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\[\e[0;31m\]#\[\e[0m\] '
1

In Msys on Windows try this (I found the accepted answer didn't work in Msys)

at &> /dev/null && echo "Running as admin" || echo "NOT running as admin"

This relies on the return code of at being zero only when running as admin.

3
  • 1
    This seems the same method as @Steven gave in earlier answer (which does not seem to work on Windows 8.1 according to a comment - unless MSYS "at" is somehow). While the question was about Cygwin, it is interesting to compare with similar MSYS. Thanks for the contribution.
    – FooF
    Apr 24, 2015 at 6:00
  • Very similar yes. However I ended up on this question trying to use it to check in a script (Win7, Msys) rather than setting the bash prompt style, so I thought this might be of use to someone else doing the same
    – sparrowt
    Apr 24, 2015 at 9:04
  • I agree on the usefulness.
    – FooF
    Apr 24, 2015 at 9:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .