4 votes

L'accès au chemin est refusé (PowerShell Rename-Item script)

J'ai été ennuyé par la touche F1 qui fait apparaître l'aide de Windows tout le temps parce que je pense que c'est plutôt inutile. La solution consiste donc à renommer le fichier "HelpPane.exe" dans le dossier " C:\Windows " vers quelque chose d'autre afin que l'appui sur F1 ne fasse plus rien. Cependant, je voudrais automatiser cela avec un script.

En utilisant PowerShell, je peux essayer le script suivant :

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

Cependant, chaque fois que j'exécute le script, que ce soit en tant qu'administrateur ou non, je reçois l'erreur suivante : enter image description here

C'est parce que Windows a une certaine autorisation de sécurité sur le fichier. Je sais que je peux les supprimer manuellement en jouant dans Propriétés/Sécurité/Avancées, mais j'ai besoin d'un moyen automatisé de le faire dans le script PowerShell lui-même ; je ne veux pas le faire manuellement à chaque fois. Malheureusement, je ne sais pas comment gérer ces types de permission avancée directement dans PowerShell.

Que dois-je ajouter à mon script PowerShell pour m'assurer que le fichier est renommé avec succès ? Merci.

Pour référence, j'exécute Windows 10 Enterprise 1607 build 14393.

3voto

Ben N Points 38070

Vous devez ajouter une entrée de contrôle d'accès qui vous accorde un contrôle suffisant, mais pour ce faire, vous devez d'abord être le propriétaire du fichier. Les administrateurs peuvent se rendre propriétaires de n'importe quel fichier, mais le processus qui effectue l'ajustement doit avoir l'autorisation de l'administrateur. SeTakeOwnershipPrivilege privilège activé. Pour l'activer, il faut manipuler du code non géré, qui Lee Holmes a fait pour nous . J'ai reformaté et légèrement modifié son script, que vous devrez enregistrer dans un fichier (par ex. 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 vous ne l'avez pas encore fait, vous devrez suivre les instructions de la section Activer les scripts du document le wiki des balises PowerShell . Ensuite, nous pourrons tout mettre ensemble :

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

Cela ajuste l'ACL, vous donnant la permission de renommer le fichier :

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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X