O acesso ao caminho é negado (script Renomear-Item do PowerShell)

2

Eu fiquei chateado com a tecla F1 trazendo ajuda do Windows o tempo todo, porque eu acho que é muito inútil. Portanto, a solução é renomear o arquivo "HelpPane.exe" no diretório "C: \ Windows" para outra coisa, de modo que pressionar F1 nunca mais faça nada. No entanto, gostaria de automatizar isso com um script.

Usando o PowerShell, posso tentar o seguinte script:

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

No entanto, sempre que executo o script, seja como administrador ou não, recebo o seguinte erro:

Isso ocorre porque o Windows tem alguma permissão de segurança no arquivo. Eu sei que posso removê-los manualmente mexendo em Propriedades / Segurança / Avançado, mas preciso de uma maneira automatizada para fazer isso dentro do próprio script do PowerShell; Eu não quero fazer isso manualmente todas as vezes. Infelizmente, não sei como gerenciar esses tipos de permissão avançada diretamente do PowerShell.

O que preciso adicionar ao meu script do PowerShell para garantir que o arquivo seja renomeado com êxito? Obrigado.

Para referência, estou executando o Windows 10 Enterprise 1607 build 14393.

    
por jippyjoe4 02.07.2018 / 22:21

1 resposta

2

Você precisa adicionar uma entrada de controle de acesso que lhe conceda controle suficiente, mas para isso você precisa primeiro ser o proprietário do arquivo. Os administradores podem tornar-se proprietários de qualquer arquivo, mas o processo que faz o ajuste deve ter o SeTakeOwnershipPrivilege privilégio ativado. Permitir isso requer mexer com código não gerenciado, que Lee Holmes fez por nós . Eu reformatei e alterei levemente o script dele, que você precisará salvar em um arquivo (por exemplo, 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)

Se você ainda não o fez, precisará seguir as instruções na seção Habilitando Scripts do wiki de tags do PowerShell . Então podemos juntar tudo:

.\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

Isso ajusta a ACL, permitindo que você renomeie o arquivo:

Rename-Item C:\Windows\HelpPane.exe HelpPane_.exe
    
por 03.07.2018 / 00:04