UAC References
References
This section includes a virtualization reference and a security settings reference.
Virtualization Reference
File Virtualization
Virtualize (%SYSTEMROOT%, %PROGRAMDATA%,%PROGRAMFILES%\(Subdirectories)
Redirect to: %LOCALAPPDATA%\VirtualStore
Excluded binary executables: .exe, .dll, .sys
Registry Virtualization
Virtualize (HKEY_LOCAL_MACHINE\SOFTWARE)
Redirect to: HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\<Application Registry Keys>
Keys excluded from virtualization
HKEY_LOCAL_MACHINE\Software\Classes
HKEY_LOCAL_MACHINE \Software\Microsoft\Windows
HKEY_LOCAL_MACHINE \Software\Microsoft\Windows NT
Applicability
Virtual stores do not roam
Corresponding global objects would not roam
Enabled only for interactive standard users
Disabled for non-interactive processes
Disabled for 64-bit executables
Disabled for executables that request an execution level (requestedExecutionLevel) in their application manifest, the model for separation
Disabled for kernel mode and impersonated callers
·Only administrator writeable registry keys and files are virtualized
UAC Security Settings Reference
This reference details the security settings available to administer UAC with Group Policy or the computer's local security policy.
Note
The procedures presented in this section are intended for administering unmanaged computers. To use Group Policy to administer the settings centrally in a managed environment, use Active Directory Users and Computers (dsa.msc) instead of local Security Policy Manager snap-in (secpol.msc).
Configuring UAC Security Settings
The following procedure details how to configure the UAC security settings with the Security Policy Manager. The procedure details the default user experience for an administrator in Admin Approval Mode.
To view or set the UAC security settings with Security Policy Manager
Click the Start button, type secpol.msc into the search box, and then press Enter.
At the User Account Control consent prompt, click Continue.
In Local Security Settings, expand Local Policies, and then click Security Options.
Right-click the security setting that you would like to change and select Properties.
The following procedure details how to configure the UAC security settings with the Group Policy. The procedure details the default user experience for an administrator in Admin Approval Mode.
To view or set the UAC security settings with the Group Policy Object Editor
Click the Start button, type gpedit.msc into the search box, and then press Enter.
At the User Account Control consent prompt, click Continue.
In Group Policy, expand User Configuration, and then expand Security Options.
Right-click the security setting that you would like to change and select Properties.
UAC Security Settings
The following table lists the configurable UAC security settings. These settings can be configured with the Security Policy Manager (secpol.msc) or managed centrally with Group Policy (gpedit.msc).
Setting |
Description |
Default value |
---|---|---|
User Account Control: Admin Approval Mode for the Built-in Administrator account |
There are two possible settings:
|
|
User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode |
There are three possible values:
|
Prompt for consent |
User Account Control: Behavior of the elevation prompt for standard users |
There are two possible values:
|
|
User Account Control: Detect application installations and prompt for elevation |
There are two possible values:
|
Enabled |
User Account Control: Only elevate executables that are signed and validated |
There are two possible values:
|
Disabled |
User Account Control: Only elevate UIAccess applications that are installed in secure locations |
There are two possible values:
|
Enabled |
User Account Control: Run all administrators in Admin Approval Mode |
There are two possible values:
Note: Changing this setting will require a system reboot. |
Enabled |
User Account Control: Switch to the secure desktop when prompting for elevation |
There are two possible values:
|
Enabled |
User Account Control: Virtualize file and registry write failures to per-user locations |
There are two possible values:
|
Enabled |
Note
Modifying the User Account control: Run all administrators in Admin Approval Mode setting will require a computer restart before the setting becomes effective. All other UAC Group Policy settings are dynamic and do not require a reboot.
Task Scheduler Code Sample
The following C++ code sample illustrates how to use Task Scheduler to run an un-elevated application as the currently logged on desktop user from an elevated process. This method works for both the consent prompt and the credential prompt.
//---------------------------------------------------------------------
// This file is part of the Microsoft .NET Framework SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation. See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------
/**********************************************************************
* Main.cpp - Sample application for Task Scheduler V2 COMAPI * Component: Task Scheduler
* Copyright (c) 2002 - 2003, Microsoft Corporation
* This sample creates a task to that launches as the currently logged
* on deskup user. The task launches as soon as it is registered.
**********************************************************************/
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <comdef.h>
#include <comutil.h>
//Include Task header files - Included in Windows Vista Beta-2 SDK from //MSDN
#include <taskschd.h>
#include <conio.h>
#include <iostream>
#include <time.h>
using namespace std;
#define CLEANUP \
pRootFolder->Release();\
pTask->Release();\
CoUninitialize();
HRESULT CreateMyTask(LPCWSTR, wstring);
void __cdecl wmain(int argc, wchar_t** argv)
{
wstring wstrExecutablePath;
WCHAR taskName[20];
HRESULT result;
if( argc < 2 )
{
printf("\nUsage: LaunchApp yourapp.exe" );
return;
}
// Pick random number for task name
srand((unsigned int) time(NULL));
wsprintf((LPWSTR)taskName, L"Launch %d", rand());
wstrExecutablePath = argv[1];
result = CreateMyTask(taskName, wstrExecutablePath);
printf("\nReturn status:%d\n", result);
}
HRESULT CreateMyTask(LPCWSTR wszTaskName, wstring wstrExecutablePath)
{
// ------------------------------------------------------
// Initialize COM.
TASK_STATE taskState;
int i;
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if( FAILED(hr) )
{
printf("\nCoInitializeEx failed: %x", hr );
return 1;
}
// Set general COM security levels.
hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
0,
NULL);
if( FAILED(hr) )
{
printf("\nCoInitializeSecurity failed: %x", hr );
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Create an instance of the Task Service.
ITaskService *pService = NULL;
hr = CoCreateInstance( CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
(void**)&pService );
if (FAILED(hr))
{
printf("Failed to CoCreate an instance of the TaskService
class: %x", hr);
CoUninitialize();
return 1;
}
// Connect to the task service.
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(),
_variant_t());
if( FAILED(hr) )
{
printf("ITaskService::Connect failed: %x", hr );
pService->Release();
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Get the pointer to the root task folder. This folder will hold
// the new task that is registered.
ITaskFolder *pRootFolder = NULL;
hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
if( FAILED(hr) )
{
printf("Cannot get Root Folder pointer: %x", hr );
pService->Release();
CoUninitialize();
return 1;
}
// Check if the same task already exists. If the same task exists,
// remove it.
hr = pRootFolder->DeleteTask( _bstr_t( wszTaskName), 0 );
// Create the task builder object to create the task.
ITaskDefinition *pTask = NULL;
hr = pService->NewTask( 0, &pTask );
pService->Release(); // COM clean up. Pointer is no longer used.
if (FAILED(hr))
{
printf("Failed to CoCreate an instance of the TaskService
class: %x", hr);
pRootFolder->Release();
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Get the trigger collection to insert the registration trigger.
ITriggerCollection *pTriggerCollection = NULL;
hr = pTask->get_Triggers( &pTriggerCollection );
if( FAILED(hr) )
{
printf("\nCannot get trigger collection: %x", hr );
CLEANUP
return 1;
}
// Add the registration trigger to the task.
ITrigger *pTrigger = NULL;
hr = pTriggerCollection->Create( TASK_TRIGGER_REGISTRATION,
&pTrigger );
pTriggerCollection->Release();
// COM clean up. Pointer is no longer used.
if( FAILED(hr) )
{
printf("\nCannot add registration trigger to the Task %x", hr );
CLEANUP
return 1;
}
pTrigger->Release();
// ------------------------------------------------------
// Add an Action to the task.
IExecAction *pExecAction = NULL;
IActionCollection *pActionCollection = NULL;
// Get the task action collection pointer.
hr = pTask->get_Actions( &pActionCollection );
if( FAILED(hr) )
{
printf("\nCannot get Task collection pointer: %x", hr );
CLEANUP
return 1;
}
// Create the action, specifying that it is an executable action.
IAction *pAction = NULL;
hr = pActionCollection->Create( TASK_ACTION_EXEC, &pAction );
pActionCollection->Release();
// COM clean up. Pointer is no longer used.
if( FAILED(hr) )
{
printf("\npActionCollection->Create failed: %x", hr );
CLEANUP
return 1;
}
hr = pAction->QueryInterface( IID_IExecAction, (void**)
&pExecAction );
pAction->Release();
if( FAILED(hr) )
{
printf("\npAction->QueryInterface failed: %x", hr );
CLEANUP
return 1;
}
// Set the path of the executable to the user supplied executable.
hr = pExecAction->put_Path( _bstr_t( wstrExecutablePath.c_str() ) );
if( FAILED(hr) )
{
printf("\nCannot set path of executable: %x", hr );
pExecAction->Release();
CLEANUP
return 1;
}
hr = pExecAction->put_Arguments( _bstr_t( L"" ) );
if( FAILED(hr) )
{
printf("\nCannot set arguments of executable: %x", hr );
pExecAction->Release();
CLEANUP
return 1;
}
// ------------------------------------------------------
// Save the task in the root folder.
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t( wszTaskName ),
pTask,
TASK_CREATE,
_variant_t(_bstr_t( L"S-1-5-32-545")),//Well Known SID for \\Builtin\Users group
_variant_t(),
TASK_LOGON_GROUP,
_variant_t(L""),
&pRegisteredTask);
if( FAILED(hr) )
{
printf("\nError saving the Task : %x", hr );
CLEANUP
return 1;
}
printf("\n Success! Task successfully registered. " );
for (i=0; i<100; i++)//give 10 seconds for the task to start
{
pRegisteredTask->get_State(&taskState);
if (taskState == TASK_STATE_RUNNING)
{
printf("\nTask is running\n");
break;
}
Sleep(100);
}
if (i>= 100) printf("Task didn't start\n");
//Delete the task when done
hr = pRootFolder->DeleteTask(
_bstr_t( wszTaskName ),
NULL);
if( FAILED(hr) )
{
printf("\nError deleting the Task : %x", hr );
CLEANUP
return 1;
}
printf("\n Success! Task successfully deleted. " );
// Clean up.
CLEANUP
CoUninitialize();
return 0;
}