bluebearr Posted December 31, 2007 Posted December 31, 2007 (edited) Ever tried to run as a regular user in Windows XP on a box that you own? You know you should, because it is the more secure way to compute. However, it can be pretty inconvenient. If you need to install software, add a printer, change your network connection, etc, you either need to switch users, Shift-Right click a shortcut to Run As another account, or use the runas command line tool. If you've ever done this, you realize that there are problems with running Administrator functions under another account: changes that affect the profile go to the Administrator account profile, you don't have your normal account's network access, etc.Aaron Margosis came up with a solution with his MakeMeAdmin batch file. I've extended this concept with my RunAsAdmin AutoIt script. This script prompts for the name and password of an account in the Administrator's group, and for my current account's password. It then runs an Explorer-like window (using the A43 file management utility) under my normal account. However, within this one window, my account has Administrator access. Thus, I have Administrator access, but any changes I make affect my own profile and not the profile of some other account. More details about what it does can be found on my blog.Here is the script:expandcollapse popup; ---------------------------------------------------------------------------- ; ; AutoIt Version: 3.1.0 ; Author: Bluebearr ; Website: http://www.bluebearr.net ; Copyright 2007 Bluebearr. Use of this code is governed under the ; Creative Commons Attribution 3.0 Unported license code (see http://creativecommons.org/licenses/by/3.0/) ; Any use of this script must note "Portions copyright BlueBearr." A link to http://www.bluebearr.net is appreciated. ; ; Script Function: ; Add current user to the Administrators group, run a command as an Administrator, ; then remove the account from the Administrators group ; Inspired by Aaron Margosis http://blogs.msdn.com/aaron_margosis/archive/2004/07/24/193721.aspx ; ; ---------------------------------------------------------------------------- ; Script Start #include <GUIConstants.au3> #include <Constants.au3> #include <Array.au3> #Include <process.au3> #include <File.au3> #Include <string.au3> ; Dimension global variables Global $Key, $ScriptNameCore, $AdminDefVal, $WinTitle, $AdminUsersA, $AdminDef, $LocalAdminGroup Global $AdminAcct, $AdminPass, $CurrentUser, $CurrentPass, $AdminAcctDomain, $CurrentUserDomain ; Main _Init() ; Initialize _CheckAdmin() ; Check if we are already an Admin. If so, just call _RunAsAdmin _GetAcct() ; Prompt user for the Admin account and logon credentials _MakeAdmin() ; Add the current account to the local Administrators _RunAsAdmin() ; Run the commands under the current account, which is now an Admin account _DelAdmin() ; Remove current account from the local Administrators ; ======================= ; Functions ; ======================= Func _Init() ; Show splash screen, and initialize variables Local $TempDir ; Show Splash $TempDir = _TempFile() DirCreate($TempDir) FileInstall("C:\Program Files\RunAsAdmin\RunAsAdminSplash.jpg", $TempDir & "\splash.jpg", 1) SplashImageOn("", $TempDir & "\splash.jpg", 240, 101, -1, -1, 1) ; Initialize variables $WinTitle = "RunAsAdmin" ; Title for program windows $Key = 'HKCU\Software\Scripts\' & $WinTitle ; Key where the default account is kept $ScriptNameCore = StringLeft(@ScriptName, StringInStr(@ScriptName, ".", 0, -1) - 1) ; "Core" name of this script, ; so we can find files of the same name but different extension $AdminDefVal = $ScriptNameCore & "_AdminDef" ; Value in registry where the default account is kept $AdminSID = "S-1-5-32-544" ; Get Administrator accounts and default admin account $LocalAdminGroupA = _GetMemberNameFromSID($AdminSID, @ComputerName) ; Name of the local Administrators group If $LocalAdminGroupA[1] = "None" Then MsgBox(0, $WinTitle, "ERROR: Could not find Administrators Group!") Exit EndIf $LocalAdminGroup = $LocalAdminGroupA[0] $AdminDef = RegRead($Key, $AdminDefVal) ; default admin account to use $CurrentUser = @UserName $CurrentUserDomain = EnvGet("USERDOMAIN") SplashOff() DirRemove($TempDir, 1) EndFunc ;==>_Init Func _CheckAdmin() ; Check if we are already an Administrator. If so, just run the command(s). If IsAdmin() Then _RunAsAdmin() SplashTextOn($WinTitle, "Account " & @UserName & " is already an Administrator.", 300, 50, -1, -1, 2, "Tahoma", 10) Sleep(3000) SplashOff() Exit EndIf EndFunc ;==>_CheckAdmin Func _GetAcct() ; Show the interface where the user can choose the account, and then enter the passwords. ; == GUI generated with Koda == $MMADialog = GUICreate($WinTitle, 316, 260, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, _ $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS)) GUICtrlCreateLabel("Adiminstrator account user name:", 16, 8, 161, 17, $WS_GROUP) ; Admin accounts $AdminAcctEdit = GUICtrlCreateInput($AdminDef, 48, 32, 217, 21) GUICtrlRead($AdminAcctEdit) $AdminDefaultChk = GUICtrlCreateCheckbox("&Make this account the default.", 48, 64, 177, 17, _ BitOR($BS_CHECKBOX, $BS_AUTOCHECKBOX, $WS_GROUP)) ; Admin account password GUICtrlCreateLabel("Admin account password:", 16, 88, 200, 17, $WS_GROUP) $AdminPassEdit = GUICtrlCreateInput("", 48, 112, 217, 21, BitOR($WS_EX_CLIENTEDGE, $ES_PASSWORD)) If $AdminDef <> "" Then GUICtrlSetState(-1, $GUI_FOCUS) EndIf ; Current account GUICtrlCreateLabel("Current account password:", 16, 152, 200, 17) GUICtrlCreateLabel("[" & $CurrentUserDomain & "\" & $CurrentUser & "]", 20, 170, 196, 17) ;GUICtrlSetFont (-1, 8.5, 400, 2) ; Current account password $CurrentPassEdit = GUICtrlCreateInput("", 48, 187, 217, 21, BitOR($WS_EX_CLIENTEDGE, $ES_PASSWORD)) ; Buttons $OKBtn = GUICtrlCreateButton("&OK", 200, 220, 73, 25, $BS_DEFPUSHBUTTON) $CancelBtn = GUICtrlCreateButton("&Cancel", 32, 220, 73, 25) ;$SettingsBtn = GUICtrlCreateButton("&Settings", 112, 256, 89, 25, 0) GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop Case $msg = $OKBtn ; Verify that the passwords have been entered If GUICtrlRead($AdminPassEdit) = "" Or GUICtrlRead($CurrentPassEdit) = "" Then MsgBox(48, $WinTitle, "Please enter the password for both accounts.") Else ; Get the selected Admin account $AdminAcct = GUICtrlRead($AdminAcctEdit) $AdminPass = GUICtrlRead($AdminPassEdit) ; Get the current account password $CurrentPass = GUICtrlRead($CurrentPassEdit) ; Save the default account to the registry If BitAND(GUICtrlRead($AdminDefaultChk), $GUI_CHECKED) Then RegWrite($Key, $AdminDefVal, "REG_SZ", $AdminAcct) EndIf ExitLoop EndIf Case $msg = $CancelBtn ExitLoop Case Else ;;;;;;; EndSelect WEnd GUIDelete() If $AdminAcct = "" Then Exit EndFunc ;==>_GetAcct Func _MakeAdmin() ; Make the Current user an Administrator, then the run the command under the elevated account ; and then remove the privileges ; Get the domain If StringInStr($AdminAcct, "\") Then $AdminAcctDomain = StringLeft($AdminAcct, StringInStr($AdminAcct, "\") - 1) $AdminAcct = StringRight($AdminAcct, StringLen($AdminAcct) - StringInStr($AdminAcct, "\")) Else $AdminAcctDomain = @ComputerName EndIf ; Make me an Administrator SplashTextOn($WinTitle, "Making account " & $CurrentUserDomain & '\' & $CurrentUser & " an Administrator.", _ 300, 50, -1, -1, 2, "Tahoma", 10) RunAsSet($AdminAcct, $AdminAcctDomain, $AdminPass) RunWait(@ComSpec & ' /c net localgroup ' & $LocalAdminGroup & ' "' & $CurrentUserDomain & '\' & $CurrentUser _ & '" /ADD', @SystemDir, @SW_HIDE) ControlSetText($WinTitle, "Making account ", "Static1", "Launching app...") ; Change the RunAsSet here rather than in _RunAsAdmin so that _CheckAdmin can call _RunAsAdmin without any problem RunAsSet($CurrentUser, $CurrentUserDomain, $CurrentPass) EndFunc ;==>_MakeAdmin Func _DelAdmin() ; Remove the current account from the Administrators group Sleep(1000) SplashOff() RunAsSet($AdminAcct, $AdminAcctDomain, $AdminPass) RunWait(@ComSpec & ' /c net localgroup ' & $LocalAdminGroup & ' "' & $CurrentUserDomain & '\' & $CurrentUser _ & '" /DELETE', @SystemDir, @SW_HIDE) EndFunc ;==>_DelAdmin Func _RunAsAdmin() ; Just run the command(s) that you want to run as an Administrator ; Look for one of several filenames in the current directory to run $AllCmdRuns = @ScriptDir & "\" & $ScriptNameCore & ".bat" & @LF _ & @ScriptDir & "\" & $ScriptNameCore & ".cmd" & @LF _ & @ScriptDir & "\A43.exe" $CmdRunA = StringSplit($AllCmdRuns, @LF) $CmdRun = "***None***" For $i = $CmdRunA[0] To 1 Step - 1 If FileExists($CmdRunA[$i]) Then $CmdRun = $CmdRunA[$i] Next If $CmdRun = "***None***" Then ; No external batch files to run, just open command prompt Run(@ComSpec & ' /k title *** ' & $CurrentUserDomain & '\' & $CurrentUser & ' as Admin *** & ver & color 4f') Return EndIf If StringRight($CmdRun, 7) = "A43.exe" Then $CmdRun = $CmdRun & " C:\" Run($CmdRun, @ScriptDir) SplashTextOn($WinTitle, "Starting A43...", 300, 50, -1, -1, 2, "Tahoma", 10) WinWaitActive("A43 ->", "", 15) SplashOff() Else Run(@ComSpec & ' /c "' & $CmdRun & '"', @ScriptDir, @SW_MINIMIZE) EndIf EndFunc ;==>_RunAsAdmin Func _GetMemberNameFromSID($strSID, $strDomain) ; Return the name of a user or group account based on the SID. ; Returns a 2 item array. Item 1 is the name, and item 2 is "User", "Group", or "None" ; Generated by AutoIt Scriptomatic $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = $strDomain Dim $MemberNameA[2] ; Test the group names $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Group", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $strItemSID = $objItem.SID If $strItemSID = $strSID Then ; Found a match. Return the name and that it is a group $MemberNameA[0] = $objItem.Name $MemberNameA[1] = "Group" Return $MemberNameA EndIf Next EndIf ; Test the User names $colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_UserAccount", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $strItemSID = $objItem.SID If $strItemSID = $strSID Then ; Found a match. Return the name and that it is a user $MemberNameA[0] = $objItem.Name $MemberNameA[1] = "User" Return $MemberNameA EndIf Next EndIf $MemberNameA[0] = "##ERROR_NOT_FOUND##" $MemberNameA[1] = "None" SetError(1) Return $MemberNameA EndFunc ;==>_GetMemberNameFromSID Edited December 31, 2007 by bluebearr BlueBearrOddly enough, this is what I do for fun.
DW1 Posted December 31, 2007 Posted December 31, 2007 Very Nice BlueBearr, thanks for sharing. AutoIt3 Online Help
ptrex Posted January 1, 2008 Posted January 1, 2008 @bluebearr Very nice start of the scripting year 2008 !! regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
Oldschool Posted January 5, 2008 Posted January 5, 2008 within this one window, my account has Administrator accessA Magic Box!TYVM !!!
JusGellin Posted January 5, 2008 Posted January 5, 2008 It looks so very useful!!! But how can I find that it really has those admin permissions? I tried running gpresult from a command line - it didn't show it had admin permissions. I ran computer management and looked at administrator group and didn't see it either. But I know it works because that user account couldn't run any au3 scripts from the Scite editor, but if I started it in from the command prompt after I ran a complied version of your script, it worked. What dos command tells me I have elevated permissions? Also, I didn't notice any splash screen come up when I ran this. I gave it a .jpg with the name you had and placed it in the folder you show. Is it because it happens so fast? Thanks very much for this. Great example.
program builder Posted January 18, 2008 Posted January 18, 2008 Easy. Just build a macro that will change the administrator password. and then stick it inside of the start up menu for programs start up all users. And then when any of the administrators log on it will change the password of the account named administrator. It's that simple. If you don't know how to do it respond to my post, with your email. and i will build it for free.
program builder Posted January 18, 2008 Posted January 18, 2008 Ohh, I could really use this!i will buil;d it for you. I will upload it here.just respond if you want it.
JusGellin Posted January 18, 2008 Posted January 18, 2008 i will buil;d it for you. I will upload it here.just respond if you want it.That would be very helpful for everyone if you could do that. Thanks for the help.
Valik Posted January 19, 2008 Posted January 19, 2008 How is such a script going to be helpful? Let's think about this for about half a second here. The idea is to change the administrator password. That's going to work only if 1) You know the current password; 2) There is no password set. If either of those is the case, what's stopping the person from logging on manually and changing the administrator's password? I also don't see how "a script to change the administrator's password" is at all relevant to the project posted here. This is about intentionally running as a limited user but providing a convenient way of gaining administrator rights for privileged actions. In short, it's a poor man's manual UAC to relate this to Vista's integrated approach.
Siddhartha Posted January 19, 2008 Posted January 19, 2008 That's going to work only if 1) You know the current password; 2) There is no password set.Although I agree with the rest of your post, your number is false. The current password does not have to be known to change the password.~Niko
Valik Posted January 19, 2008 Posted January 19, 2008 Commenting on the script from the original poster. There is a very large security issue with the script. Namely, if anything fails between the time you add the user to the administrators group and the time you delete it from the group, you will leave your account stuck in the administrators group and won't even realize it. The best approach to doing all you can to guarantee proper cleanup is to simply not run the group-add and group-remove stuff in the same process you do everything else. A second instance should do nothing but add the account to the administrators group, wait on some sort of synchronization event then remove the account from the group when the event fires. Nikolai, I see that you are correct. I realize there needs to be some way of overriding passwords but I never expected it to be so blindingly easy. At any rate, the script still won't work, at least according to the security tab. Limited users don't have write access to the All Users startup entry.
Draygoes Posted January 21, 2008 Posted January 21, 2008 What do I do if neather account has a password. Im not living in a house where I need one. Spoiler  "If a vegetarian eats vegetables,What the heck does a humanitarian eat?" "I hear voices in my head, but I ignore them and continue on killing." "You have forced me to raise the indifference warning to beige, it's a beige alert people. As with all beige alerts please prepare to think about the possibility of caring." An optimist says that giving someone power DOESN'T immediately turn them into a sadist. A pessimist says that giving someone power doesn't IMMEDIATELY turn them into a sadist.  Â
bluebearr Posted January 29, 2008 Author Posted January 29, 2008 Sorry, been away for a while. @ draygoes : I haven't tested it, but I believe that the script requires that the Administrator account have a password, since runas won't work with an account with a blank password. @ Valik : Thanks for your evaluation. You are right, there is the possibility that the user could remain in the Administrators group. As far as I can tell, the "group-add process" and the "launching-as-an-Admin process" steps have to happen in the same process. This is because other processes won't "see" that the account is a member of the Administrator's group. So, if the group-add step occurs in a second process, the first process won't be able to run a command as an Administrator because it will appear to it that the user is not a member of the Administrators group. However, the idea of having a "watchdog" process that focuses on locking down the group access has merit. It might be good to have the _MakeAdmin() function launch a second process under the Administrator account that would wait (with timeout) for the synchronization event you mention and then remove the user from the Administrators group. I did a test, and it looks like this could work, i.e., the second process "sees" that the user is in the Administrators group. It would also help in my current script if I moved the $CmdRun evaluation that occurs in the _RunAsAdmin() function to some other place earlier in the script. This would reduce the number of steps between the group-add and group-remove events (and thus reduce the possibility of the script hanging between these two events. Thanks again. BlueBearrOddly enough, this is what I do for fun.
asilus Posted December 1, 2009 Posted December 1, 2009 hi, I'd like to put some modifications on your script. Do you give me the right to do it and publish the new code on this forum?
vadablond Posted December 6, 2009 Posted December 6, 2009 thank pro. i have a question. I want to runas a program with another user, can you help me? thank!
DoktorTTM Posted December 7, 2009 Posted December 7, 2009 Very nice script. I may show it to my brother since he is stuck to limited after the "Messes" he caused a while back. Molenoid Fan Girl! And fully fledged nerd-bird! And soon to be Cosplayer~
asilus Posted December 10, 2009 Posted December 10, 2009 thank pro. i have a question. I want to runas a program with another user, can you help me? thank! hi, for start a program with another user, you must use the command "RunAs" or "RunAsWait". RunAs ( "username", "domain", "password", logon_flag, "filename" [, "workingdir" [, show_flag [, opt_flag ]]] ) RunAsWait ( "username", "domain", "password", logon_flag, "filename" [, "workingdir" [, show_flag [, opt_flag ]]] ) for more informations read the help of AutoIt "F1". bye, Asilus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now