2 votos

A la ruta de acceso es negado (Script de PowerShell Rename-Item)

Me molestaba que con la tecla F1 traer a la ayuda de Windows todo el tiempo porque creo que es bastante inútil. Así que la solución es cambiar el nombre de la "HelpPane.exe" en el archivo "C:\Windows" directorio para algo más para que presione F1 nunca hace nada más. Sin embargo, me gustaría automatizar este proceso con una secuencia de comandos.

El uso de PowerShell, puede intentar la siguiente secuencia de comandos:

Rename-Item -Force -Path "C:\Windows\HelpPane.exe" -NewName "C:\Windows\HelpPane1.exe"

Sin embargo, cada vez que ejecuto el script, ya sea como administrador o no, recibo el siguiente error: enter image description here

Esto es porque Windows tiene algunas permiso de seguridad en el archivo. Sé que me puede quitar de forma manual por el cachondeo en Propiedades/Seguridad/opciones Avanzadas, pero necesito una forma automatizada para ello, dentro de la secuencia de comandos de PowerShell sí mismo; no quiero hacerlo manualmente cada vez. Por desgracia, no estoy seguro de cómo manejar estos tipos de permisos avanzados directamente desde PowerShell.

¿Qué necesito para agregar a mi script de PowerShell para asegurarse de que el archivo que se cambió de nombre correctamente? Gracias.

Para referencia, estoy corriendo Windows 10 Enterprise 1607 construir 14393.

2voto

Ben N Puntos 1071

Usted necesita para agregar una entrada de control de acceso que le otorga un control suficiente, pero para hacerlo, primero debe ser el propietario del archivo. Los administradores pueden hacer ellos mismos el propietario de cualquier archivo, pero el proceso de hacer el ajuste debe tener el SeTakeOwnershipPrivilege privilegio habilitado. Lo que permite que requiere jugueteando con código no administrado, que Lee Holmes ha hecho por nosotros. He formateado y ligeramente ajustado el script, el cual deberá guardar en un archivo (por ejemplo privs.ps1):

param(    ## The privilege to adjust. This set is taken from
    ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
    [ValidateSet(
        "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
        "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
        "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
        "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
        "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
        "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
        "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
        "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
        "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
        "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
        "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
    $Privilege,
    $ProcessId = $pid,
    [Switch] $Disable
)

$definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv
{

[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}

internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;

public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = new IntPtr(processHandle);
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
if(disable)
{
tp.Attr = SE_PRIVILEGE_DISABLED;
}
else
{
tp.Attr = SE_PRIVILEGE_ENABLED;
}
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
}
'@

$processHandle = (Get-Process -id $ProcessId).Handle
try { Add-Type $definition } catch {}
[AdjPriv]::EnablePrivilege($processHandle, $Privilege, $Disable)

Si no lo has hecho, tendrás que seguir las instrucciones que aparecen en la Habilitación de secuencias de comandos de la sección de la PowerShell etiqueta de la wiki. Entonces podemos poner todo junto:

.\privs.ps1 -Privilege SeTakeOwnershipPrivilege
$acl = Get-Acl C:\Windows\HelpPane.exe
$acl.SetOwner([System.Security.Principal.NTAccount]::new('Administrators'))
$rule = [System.Security.AccessControl.FileSystemAccessRule]::new('Administrators', 'FullControl', 'None', 'None', 'Allow')
$acl.AddAccessRule($rule)
Set-Acl C:\Windows\HelpPane.exe $acl

Que se ajusta a la ACL, dándole permiso para cambiar el nombre el archivo:

Rename-Item C:\Windows\HelpPane.exe HelpPane_.exe

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: