2

Меня раздражало, что клавиша F1 постоянно вызывает справку Windows, потому что я думаю, что она довольно бесполезна. Поэтому решение состоит в том, чтобы переименовать файл «HelpPane.exe» в каталоге «C:\Windows» во что-то другое, чтобы нажатие клавиши F1 больше ничего не делало. Тем не менее, я хотел бы автоматизировать это с помощью сценария.

Используя PowerShell, я могу попробовать следующий скрипт:

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

Однако всякий раз, когда я запускаю скрипт, будь то администратор или нет, я получаю следующую ошибку:

Это связано с тем, что Windows имеет некоторые права доступа к файлу. Я знаю, что могу удалить их вручную, возиться в Свойствах / Безопасности / Расширенные, но мне нужен автоматический способ сделать это в самом скрипте PowerShell; Я не хочу делать это каждый раз вручную. К сожалению, я не уверен, как управлять этими расширенными разрешениями напрямую из PowerShell.

Что мне нужно добавить в мой скрипт PowerShell, чтобы убедиться, что файл успешно переименован? Благодарю.

Для справки я использую Windows 10 Enterprise 1607 build 14393.

1 ответ1

2

Вам нужно добавить запись контроля доступа, которая дает вам достаточный контроль, но для этого вам сначала нужно быть владельцем файла. Администраторы могут сделать себя владельцем любого файла, но процесс, выполняющий настройку, должен иметь привилегию SeTakeOwnershipPrivilege . Включение этого требует возиться с неуправляемым кодом, что Ли Холмс сделал для нас . Я переформатировал и немного подправил его скрипт, который вам нужно сохранить в файл (например, 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)

Если вы этого еще не сделали, вам нужно будет следовать инструкциям в разделе «Включение сценариев» вики-тега PowerShell. Тогда мы можем собрать все вместе:

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

Это настраивает ACL, давая вам разрешение на переименование файла:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .