Search code examples
powershellvbscriptuacadministrator

Run Executable File Without UAC Popup as Administrator


I am running a large study where we have staff in various countries collecting information on tablet computers running Windows 10 Enterprise. Each staff member is assigned to a tablet and they log into the tablet with their standard username and password. These users do not have local admin rights on the machines, but all tablets have a single Administrator Username and Password which I know and these are uniform across the tablets.

Each night, users invoke a program on their tablets that uploads data to our servers and then we pass information back to the tablet during this synchronization process. Otherwise, they are disconnected from the internet. At the end of the synchronization process a program is executed that allows me to run any script I like, but the script executes under the standard user account (i.e. without elevated privileges).

I need to update all the tablets with a bug fix for software that they use on the tablets and I'd like to do this during the synchronization process. The bug fix is contained in a simple executable file that can be easily pushed to the staff memebers' tablets along with any code I like during the sync. If users were running the synchronization program as administrators, this wouldn't a problem as I could simply run the executable via a script at the end of the synchronization. But they aren't, so I'm trying to find a way that I could run a script (I don't really care what it is. It could be a windows batch file, a vbs script, VB.NET, powershell, etc.) and have that script execute with administrative privileges and run the installation without the UAC prompt interfering.

I don't even mind supplying the admin password in plaintext to be honest, since these users are all our employees and they can't really do anything really concerning to us with it (and I could always deploy a subsequent file through the synchronization process to delete the program that has the password in it). I realize this sounds somewhat complicated, but in a nutshell, I'd like to carry out these steps:

  1. Send the bug update executable to the tablet computer (I can do this now)
  2. Develop custom code, that will pass admin credentials to the tablet and install the executable in 1 without having the UAC appear (I can send the script to the tablet during sync but do not know how to execute it as the Admin without getting the UAC prompt).

Any ideas how I can do this? I've explored this all day with minimal success using PowerShell scripts like the ones described here and here. This was the closest I got after storing the credentials in $cred, but it continued to give me the UAC prompt:

Start-Process PowerShell.exe -Cred $cred -ArgumentList '-command &{Start-Process -FilePath C:\MySyncPath\BugFix32.exe -Verb runas}]

UPDATE

After some additional work, I think I'd be able to get this to run if I could somehow disable to UAC control with a script that can run under the regular user's account and pass the admin credentials to it. Any idea how I might be able to accomplish this? If I could get this to work, even with a reboot, I'd be able to accomplish what I need.


Solution

  • The actual issue you're having is that you want to update your application, but the application is in the Program Files folder (or some other location that standard users are not allowed to modify).

    In order to allow any user the ability to update your program, you must grant all users Full Control to your folder. Ideally your application's installer would have done this adjustment to the DACL during installation (when the installer was running as an administrator).

    For now you will have to settle for a final one-time requirement that the users elevate to administrator. Then you can disable all security on your application - allowing any user (malicious or not) to modify your application at will.

    GrantEveryoneFullControlToFileOrFolder("C:\Program Files\Contoso");
    

    with a pseudocode implementation of:

    void  GrantAllUsersFullControlToFileOrFolder(String path)
    {
        PACL oldDACL;
        PACL newDACL;    
        PSECURITY_DESCRIPTOR sd;
    
        //Get the current DALC (Discretionary Access Control List) and Security Descriptor
        GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
              nil, nil, ref oldDACL, nil, ref sd);
    
        //Create an SID for the "Users" group
        PSID usersSid = StringToSid("S-1-5-32-545");
    
        // Initialize an EXPLICIT_ACCESS structure for the new Access Control Entry (ACE)
        EXPLICIT_ACCESS ea;
        ZeroMemory(@ea, SizeOf(EXPLICIT_ACCESS));
        ea.grfAccessPermissions  = GENERIC_ALL;
        ea.grfAccessMode         = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
        ea.grfInheritance        = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea.Trustee.TrusteeForm   = TRUSTEE_IS_SID;
        ea.Trustee.TrusteeType   = TRUSTEE_IS_GROUP;
        ea.Trustee.ptstrName     = PChar(usersSID);
    
        // Create a new ACL that merges the new ACE into the existing ACL.
        // SetEntriesInAcl takes care of adding the ACE in the correct order in the list
        SetEntriesInAcl(1, @ea, oldDACL, ref newDACL); //use LocalFree to free returned newDACL
    
        //Attach the new ACL as the object's new DACL
        SetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
              nil, nil, newDACL, nil);
    
        LocalFree(HLOCAL(sd));
        LocalFree(HLOCAL(newDACL));
        FreeSid(usersSID);
    }
    

    It's not completely unheard of for applications to be modifiable by any user: Most MMOs install updates while you play. MMOs usually have a shim applied by Microsoft that gives all users control of the application folder.