Akses ke Path ditolak (PowerShell Rename-Item Script)

2

Saya merasa kesal dengan kunci F1 yang memunculkan bantuan Windows setiap saat karena saya pikir itu tidak berguna. Jadi solusinya adalah mengubah nama file "HelpPane.exe" di direktori "C: \ Windows" menjadi sesuatu yang lain sehingga menekan F1 tidak akan melakukan apa-apa lagi. Namun, saya ingin mengotomatiskan ini dengan skrip.

Menggunakan PowerShell, saya dapat mencoba skrip berikut:

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

Namun, setiap kali saya menjalankan skrip, apakah sebagai administrator atau tidak, saya menerima kesalahan berikut: enter image description here

Ini karena Windows memiliki beberapa izin keamanan pada file tersebut. Saya tahu bahwa saya dapat menghapusnya secara manual dengan bermain-main di Properties / Security / Advanced, tapi saya perlu cara otomatis untuk melakukan ini dalam skrip PowerShell itu sendiri; Saya tidak ingin melakukan ini secara manual setiap waktu. Sayangnya, saya tidak yakin bagaimana mengelola jenis izin lanjutan ini langsung dari dalam PowerShell.

Apa yang harus saya tambahkan ke skrip PowerShell saya untuk memastikan bahwa file tersebut berhasil diganti namanya? Terima kasih.

Sebagai referensi, saya menjalankan Windows 10 Enterprise 1607 build 14393.

jippyjoe4
sumber
Izin apa sebenarnya yang mencegah Anda mengubah nama file? Edit pertanyaan Anda untuk memasukkan informasi penting ini.
Ramhound

Jawaban:

2

Anda perlu menambahkan entri kontrol akses yang memberi Anda kontrol yang cukup, tetapi untuk melakukan itu Anda harus terlebih dahulu menjadi pemilik file. Administrator dapat menjadikan diri mereka sendiri pemilik file apa pun, tetapi proses yang melakukan penyesuaian harus memiliki SeTakeOwnershipPrivilege hak istimewa diaktifkan. Mengaktifkan itu membutuhkan mengutak-atik kode yang tidak dikelola, yang Lee Holmes telah melakukannya untuk kita . Saya telah memformat ulang dan sedikit mengubah skripnya, yang harus Anda simpan ke file (mis. 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)

Jika Anda belum melakukannya, Anda harus mengikuti instruksi di bagian Skrip Pengaktifan di wiki tag PowerShell . Lalu kita bisa menyatukan semuanya:

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

Itu menyesuaikan ACL, memberi Anda izin untuk mengganti nama file:

Rename-Item C:\Windows\HelpPane.exe HelpPane_.exe
Ben N
sumber
Ini bekerja dengan sempurna, terima kasih banyak. Saya terkejut ini sulit.
jippyjoe4