Estoy usando un servicio externo de Windows que maneja algunas tareas de automatización ejecutando scripts y ejecutables usando CreateProcessAsUser(). Estoy teniendo problemas en Windows Server 2008 debido a UAC y la forma en que la elevación de LUA se maneja a través de las API.iniciando un proceso elevado de UAC desde un servicio no interactivo (win32/.net/powershell)
El servicio se ejecuta como LocalSystem y no tiene habilitado "Interactuar con el escritorio". Los procesos se ejecutan como usuarios en el grupo Administradores, pero no en la cuenta de administrador (que está exenta de muchas restricciones de UAC). Todos los ajustes predeterminados de UAC en su lugar.
Puedo pasar comandos arbitrarios o código de PowerShell al servicio, pero parece que no puedo 'salir' del proceso no elevado y no interactivo que inicia el servicio.
El quid de la cuestión parece ser que la única opción de API (pública) para iniciar un proceso elevado es ShellExecute() con el verbo 'runas', pero hasta donde puedo decir que no se puede invocar desde un servicio no interactivo o recibe errores como "Esta operación requiere una estación de ventana interactiva".
La única solución que he encontrado es mencionado aquí: http://www.eggheadcafe.com/software/aspnet/29620442/how-to-proper-use-sendinp.aspx
En Vista, el funcionario documentado manera para elevar un proceso sólo se utiliza el API cáscara ShellExecute (Ex) (no CreateProcess o CreateProcessAsUser). Entonces su aplicación debe llamar al ShellExecute (Ex) para iniciar un helper elevado para llamar a SendInput. Además, debido a la sesión 0 aislamiento, un servicio sólo puede utilizar CreateProcessAsUser o CreateProcessWithLogonW (no se puede utilizar ShellExecute (Ex)) para especificar el escritorio interactivo.
.. Creo que no hay una forma directa de engendrar un proceso elevado a partir de un servicio de Windows . Solo podemos usar primero CreateProcessAsUser o CreateProcessWithLogonW para generar un proceso no elevado de en la sesión de usuario (escritorio interactivo). Luego, en el proceso no elevado, puede usar ShellExecute (Ex) para engendrar un proceso elevado para la tarea real.
Para hacer esto desde el código .net/PowerShell, parece que tendría que hacer algo elaborado P/Invoke cosas para llamar CreateProcessAsUser o CreateProcessWithLogonW ya que el .Net System.Diagnostics.ProcessStartInfo no tiene una equivalente de lpDesktop que pude configurar como "winsta0 \ default". Y no tengo claro si LocalSystem incluso tiene los derechos para llamar a CreateProcessAsUser o CreateProcessWithLogonW.
I, también vieron http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx y Process.Start with different credentials with UAC on
Sobre la base de todo esto, estoy llegando a la conclusión de que no hay manera fácil de hacer esto. ¿Me estoy perdiendo de algo? Esto realmente no parece que debería ser tan difícil. Parece que el UAC nunca fue diseñado para manejar casos de uso no interactivos.
Y si alguna persona de Microsoft termina leyendo esto, noté que la forma en que ShellExecute maneja internamente la elevación es llamando al Servicio de Información de Aplicación (AIS). ¿Por qué no está disponible esa misma llamada a AIS a través de alguna API Win32 o .NET? http://msdn.microsoft.com/en-us/library/bb756945.aspx
Disculpe que funcionó un poco largo. Gracias por cualquier idea
Más bien diciendo que Server Core no es compatible con UAC. Parece confirmar mi evaluación. http://blogs.technet.com/server_core/archive/2009/01/19/user-account-control-uac-and-server-core.aspx –
Ver mi publicación aquí que explica cómo, en particular, mira el LinkedToken sección: http://brianbondy.com/blog/id/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops –