web-dev-qa-db-ja.com

パスへのアクセスが拒否されました(PowerShellの名前変更-アイテムスクリプト)

F1キーがWindowsのヘルプを表示するのはかなり役に立たないと思うので、いつもイライラしていました。したがって、解決策は、「C:\ Windows」ディレクトリの「HelpPane.exe」ファイルの名前を別の名前に変更して、F1キーを押しても何も起こらないようにすることです。ただし、これをスクリプトで自動化したいと思います。

PowerShellを使用して、次のスクリプトを試すことができます。

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

ただし、管理者であるかどうかに関係なく、スクリプトを実行すると、次のエラーが発生します。 enter image description here

これは、Windowsがファイルに対するセキュリティ権限を持っているためです。プロパティ/セキュリティ/詳細をいじって手動で削除できることは知っていますが、PowerShellスクリプト自体でこれを行う自動化された方法が必要です。毎回手動でこれを行いたくありません。残念ながら、PowerShell内から直接これらの種類の高度なアクセス許可を管理する方法がわかりません。

ファイルの名前が正常に変更されるようにするには、PowerShellスクリプトに何を追加する必要がありますか?ありがとうございます。

参考までに、私はWindows 10 Enterprise1607ビルド14393を実行しています。

2
jippyjoe4

十分な制御を許可するアクセス制御エントリを追加する必要がありますが、そのためには、最初にファイルの所有者である必要があります。管理者は自分自身を任意のファイルの所有者にすることができますが、調整を行うプロセスではSeTakeOwnershipPrivilegeprivilege を有効にする必要があります。これを有効にするには、アンマネージコードをいじる必要があります。これは Lee Holmesが行ってくれました 。私は彼のスクリプトを再フォーマットして少し調整しました。ファイルに保存する必要があります(例: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タグwiki の[スクリプトの有効化]セクションの手順に従う必要があります。次に、すべてをまとめることができます。

.\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
3
Ben N