Ejecute el script de PowerShell como un usuario diferente y elevado

Ejecute el script de PowerShell como un usuario diferente y elevado

Sé que esto parece una pregunta duplicada, pero probé las soluciones y no me funcionaron.

Necesitamos ejecutar un script con nuestras cuentas de dominio pero también ejecutarlo elevado. Esto no es un problema en la mayoría de los dispositivos, ya que el acceso directo se ejecuta como administrador y nos solicita una credencial. Sin embargo, si el usuario es un administrador local, no se nos solicita una credencial (solo un mensaje UAC de sí/no).

Estoy confundido por qué esto no funciona:

# Get identity of script user
$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

# Elevate the script if not already
if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -F Green 'ELEVATED'
} else {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Exit
}

# Ensure the script has domain privileges
if ($identity.IsInRole('[domain]\[admin group]')) {
    Write-Host -F Green 'DOMAIN ADMIN'
} else {
    Start-Process PowerShell -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Pause # required, otherwise the Exit below closes the UAC prompt
    Exit
}
Pause

Cuando el script autoelevado se ejecuta cuando se ingresan las credenciales de usuario y dominio, pierde elevación... es decir, cuando Start-Process -Verb RunAsUser powershellse ejecuta desde un PowerShell elevado, no está elevado en sí mismo.

También probé lo siguiente:

Start-Process powershell -verb RunAs -argumentlist "Start-Process powershell.exe -Verb RunAsUser `"& path\to\script.ps1`""

Lo cual falla porque el administrador del dominio no tiene acceso al directorio del script... a menos que esté elevado.

Respuesta1

¿Estás automatizando algo o simplemente ejecutas un script de vez en cuando? ¿El directorio del script es local o está en la red?

Como habrás notado, iniciar una nueva instancia de PowerShell runasno cambiará al usuario y runasuserno mejorará el proceso. Tendrás que hacerlos ambos en el orden opuesto. Si ha iniciado sesión como administrador local, inicie Powershell con RunAsUser o mediante:

  • Mayús+clic derecho > Ejecutar como usuario diferente > Administrador de dominio

Luego haz tus runas para elevar desde allí (como administrador del dominio):

Start-Process PowerShell -Verb RunAs

Puedes comprobar con qué usuario estás ejecutando actualmente whoami. el resultado debería ser su cuenta de dominio, incluso cuando esté elevado.

O

Si está administrando una PC de forma remota y ya usa PowerShell, conéctese usando PowerShell, ya que la sesión siempre será elevada:

Enter-PSSession MyPCName -credential (get-credential -username domain\MyAdmin)
# remote session:
[MyPCName]: PS C:\WINDOWS\system32>

También debo recomendar nunca usar la cuenta de administrador local si es posible.

Respuesta2

Una herramienta alternativa es la herramienta gratuita sysinternals. PsExec.

El comando se vería así:

psexec -u domain\user -h -i command [arguments]

Los parámetros son:

  • -i: Ejecute el programa para que interactúe con el escritorio de la sesión especificada en el sistema remoto. Si no se especifica ninguna sesión, el proceso se ejecuta en la sesión de la consola.
  • -h: Si el sistema de destino es Vista o superior, el proceso se ejecuta con el token elevado de la cuenta, si está disponible.

Una práctica insegura también es especificar la contraseña:

-p: Especifica una contraseña opcional para el nombre de usuario. Si omite esto, se le pedirá que ingrese una contraseña oculta.

Respuesta3

Una solución simple es copiar primero el script desde la ubicación que requiere la credencial del dominio.que ya has iniciado sesión comoal sistema de archivos local de la máquina que necesita para ejecutarlo desde elevado. Luego, ejecute el script elevado desde esa copia local.

Ejecute el Start-Process Powershellde manera un poco diferente a como lo estaba ejecutando para que tome la acción de la lógica del script mientras se ejecuta elevado también. Agregue los ExecutionPolicy Bypass -NoProfile -Fileparámetros y ejecute el script luego para que funcione.

Nota:Los dos ejemplos de soluciones de PowerShell que se muestran a continuación utilizan la raíz de la unidad "C" C:\del sistema de archivos local, pero puede ajustarla en consecuencia para adaptarla.

PowerShell (Solución 1)

Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

Si necesita autenticarse con una credencial de dominio para acceder a la ubicación de la ruta del scriptinicialmente puede usar invoke-commandcon el -credentialparámetro para realizar la operación de copia. Luego puede ejecutar el script copiado del sistema de archivos local elevado de esa manera.

PowerShell (Solución 2)

$cred = Get-Credential "domain\username";
Invoke-Command -ScriptBlock {
    Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
    } -Credential $cred;

Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

Recursos de apoyo

Respuesta4

Según tengo entendido, en general, el usuario ejecutante y el privilegio del proceso actual no se pueden modificar durante la ejecución del proceso, pero el kernel del sistema operativo los establece en el momento de inicio del proceso.
Por lo tanto, debes separar el bloque de código que deseas ejecutar como elevado y ejecutarlo con RunAs (o sus variaciones).
Si es posible alterar los privilegios dentro de un proceso, se convertirá en un agujero de seguridad muy peligroso del sistema operativo.

Además, el privilegio local ( local administrator) y el privilegio de dominio ( [domain]\[admin group]) se definen por separado.
Si desea permitir DomainA\User01ambos local administratorAND DomainA\AdminGroup, debe hacer ambas cosas:

  • conceder DomainA\User01al grupo de seguridad informática local local administrator, Y
  • conceder DomainA\User01al grupo de seguridad del dominioDomainA\AdminGroup

y luego ejecute el script con RunAs.

información relacionada