gpt4 book ai didi

windows - 如何使用 Powershell 更改我的电脑桌面图标?

转载 作者:行者123 更新时间:2023-12-05 04:52:53 28 4
gpt4 key购买 nike

我正在尝试学习一些 Shell 脚本,因为最近自动化测试似乎越来越流行。

我对 Powershell 的掌握非常笼统。我当前的目标是更改“我的电脑”桌面图标。

Microsoft Windows 10 操作系统的一些东西我还没有使用 Powershell 接触过。我希望也许有一些比我多产的作家能够帮助我实现这个目标。

我刚刚测试了两个片段,它们在第一次尝试时出人意料地成功运行。

第一个可以称为 Create_Shortcut.PS1 并为可以运行批处理文件的命令行预处理系统创建桌面图标。

# Creates the command-line desktop icon.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

$TargetFile = "C:\Windows\System32\Cmd.Exe"

$ShortcutFile = "\\ISXPFV01.hd00.example.com\us_qv2_dem_user_data_pool_nra$\EE65037.HD00\Desktop\Command-Line.Lnk"

$WScriptShell = New-Object -COMObject WScript.Shell

$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)

$Shortcut.TargetPath = $TargetFile

$Shortcut.Save()

第二个可能称为 Rename_My_Computer.PS1,它会重命名“我的电脑”桌面图标。

# Changes the My Computer desktop icon name from "This PC" to "VSDC0365".

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

$My_Computer = 17

$Shell = New-Object -COMObject Shell.Application

$NSComputer = $Shell.Namespace($My_Computer)

$NSComputer.Self.Name = $Env:COMPUTERNAME

对于 Powershell 比我更有经验的人来说,我感兴趣的东西可能会被证明是极其简单的。我需要通过指定路径来更改“我的电脑”桌面图标。

由于我还没有达到这个目标,我们非常感谢您就此主题提供任何形式的帮助。

感谢阅读。

@Theo 的精彩评论后更新:

一个新的令人惊讶的工作代码段,它设法生成“我的电脑”桌面图标:

# HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel\
# {20D04FE0-3AEA-1069-A2D8-08002B30309D}
# 0 = show
# 1 = hide

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel"

$Name = "{20D04FE0-3AEA-1069-A2D8-08002B30309D}"

$Exist = "Get-ItemProperty -Path $Path -Name $Name"

if ($Exist)
{
Set-ItemProperty -Path $Path -Name $Name -Value 0
}
Else
{
New-ItemProperty -Path $Path -Name $Name -Value 0
}

现在,我所要做的就是以某种方式以编程方式按 F5 以刷新桌面 View ,以某种方式设置他在评论中提到的设置。

与刷新相关的另一个更新:

另一个令人惊讶的工作片段,它刷新了桌面 View :

# Refresh Desktop Ability

$Definition = @'

[System.Runtime.InteropServices.DllImport("Shell32.dll")]

private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

public static void Refresh() {
SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
}
'@

Add-Type -MemberDefinition $Definition -Namespace WinAPI -Name Explorer

# Refresh desktop icons
[WinAPI.Explorer]::Refresh()

现在剩下的就是在刷新之前以某种方式更改“我的电脑”桌面图标。

与获取该注册表项的所有权相关的更新:

棘手的事情。我不知道它会变得如此复杂。

目前,它失败并显示以下错误消息:

PS Y:\> Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.PS1
True
Exception calling "OpenSubKey" with "3" argument(s): "Requested registry access is not allowed."
At Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.PS1:139 char:1
+ $RegKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey( ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SecurityException

这是 Change_Registry_Key.PS1 文件的内容:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Function Enable-Privilege {
Param(
## The privilege to adjust.
[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
## The process on which to adjust the privilege. Defaults to the current process.
, $ProcessId = $Pid
## Switch to disable the privilege, rather than enable it.
, [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
$Type = Add-Type $Definition -PassThru
$Type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
}

Enable-Privilege SeTakeOwnershipPrivilege

# Change Owner to the local Administrators group.
$RegKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey( `
"CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}" `
, [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree `
, [System.Security.AccessControl.RegistryRights]::TakeOwnership)
$RegACL = $RegKey.GetAccessControl()
$RegACL.SetOwner([System.Security.Principal.NTAccount]"Administrators")
$RegKey.SetAccessControl($RegACL)

# Change Permissions for the local Administrators group.
$RegKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey( `
"CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}" `
, [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree `
, [System.Security.AccessControl.RegistryRights]::ChangePermissions)
$RegACL = $RegKey.GetAccessControl()
$RegRule = New-Object System.Security.AccessControl.RegistryAccessRule( `
"Administrators" `
, "FullControl" `
, "ContainerInherit" `
, "None" `
, "Allow")
$RegACL.SetAccessRule($RegRule)
$RegKey.SetAccessControl($RegACL)

与获取该注册表项所有权的另一次尝试相关的更新:

这是另一个片段的内容,称为 Change_Registry_Key.2.PS1:

#Define HKCR
New-PSDrive -Name HKCR7 `
-PSProvider Registry `
-Root HKEY_CLASSES_ROOT

#Set $Path HKCR Key Path
$Path = "HKCR:\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"

#Set $Path Permissions
$ACL = Get-ACL $Path

$Rule = New-Object System.Security.AccessControl.RegistryAccessRule ( `
"<domain>\<username>" `
, "FullControl" `
, "Allow")

$ACL.SetAccessRule($Rule)

$ACL | Set-ACL -Path $path

#Set HKCR 'Attributes' Key Value
Set-ItemProperty -Path $Path `
-Name Attributes `
-Value b0940064

这些是出现在控制台区域的错误:

PS Y:\> Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.2.PS1

Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
HKCR7 Registry HKEY_CLASSES_ROOT
Exception calling "SetAccessRule" with "1" argument(s): "Some or all identity refere
nces could not be translated."
At Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.2.PS1
:17 char:1
+ $ACL.SetAccessRule($Rule)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException

Set-ACL : Requested registry access is not allowed.
At Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.2.PS1
:19 char:8
+ $ACL | Set-ACL -Path $path
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (HKEY_CLASSES_RO...8-08002B30309D}:
String) [Set-Acl], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShel
l.Commands.SetAclCommand

Set-ItemProperty : Requested registry access is not allowed.
At Y:\Digitization\Powershell\The_My_Computer_Desktop_Icon\Change_Registry_Key.2.PS1
:22 char:1
+ Set-ItemProperty -Path $Path `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (HKEY_CLASSES_RO...8-08002B30309D}:
String) [Set-ItemProperty], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShel
l.Commands.SetItemPropertyCommand

关于@Theo 重命名我的电脑桌面图标的第二个版本的更新:

这个版本还不适用于我。

它的测试非常简单:

  • 我正在手动将“我的电脑”桌面图标重命名为 Fifi
  • 然后我运行这段代码;
  • 然后我手动刷新桌面 View 。

虽然我希望“我的电脑”桌面图标重命名回Work-Laptop,但它的名称仍然固定为Fifi

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

#Requires -RunAsAdministrator

Function Enable-Privilege {
[CmdletBinding( ConfirmImpact = 'low'
, SupportsShouldProcess = $false)]
[OutputType('System.Boolean')]
Param(
[Parameter( Mandatory = $true
, Position = 0)]
[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")]
[String]$Privilege

, [Parameter(Position = 1)]
$ProcessId = $PID

, [switch]$Disable
)


Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

public class Privilege {
[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;
}
}
'@

try {
$proc = Get-Process -Id $ProcessId -ErrorAction Stop
$name = $proc.ProcessName
$handle = $proc.Handle
$action = if ($Disable) { 'Disabling' } else { 'Enabling' }
Write-Verbose ( "{0} privilege '{1}' for process {2}" -f $action `
, $Privilege `
, $name)
[Privilege]::EnablePrivilege( $handle `
, $Privilege `
, [bool]$Disable)
}
catch {
throw
}
}

################################################################
# Step 1: Give the current process the SeTakeOwnershipPrivilege.
################################################################

$null = Enable-Privilege -Privilege SeTakeOwnershipPrivilege -Verbose

##############################################################
# Step 2: change Owner to the local Administrators group
##############################################################

# Better not use the string "Administrators", because this
# might have a different name in other cultures.
#
# $RegACL.SetOwner([System.Security.Principal.NTAccount]"Administrators")
#
# Use the Well-Known SID instead.
# Local Administrators Group.
$Administrators = `
[System.Security.Principal.SecurityIdentifier]::new('S-1-5-32-544')

$RegKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey( `
"CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}" `
, [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree `
, [System.Security.AccessControl.RegistryRights]::TakeOwnership)

$RegACL = $RegKey.GetAccessControl()
$RegACL.SetOwner($Administrators)
$RegKey.SetAccessControl($RegACL)

##############################################################
# Step 3: Give the Local Administrators Group Full Control.
##############################################################

# Refresh the A.C.L.
$RegACL = $RegKey.GetAccessControl()

# Test if there is a Deny rule in the ACL
# for Administrators and, if so, remove that rule.
$RegACL.GetAccessRules( `
$true `
, $true `
, [System.Security.Principal.SecurityIdentifier]) | `
Where-Object { `
$_.AccessControlType -eq 'Deny' `
-and $_.IdentityReference -eq $Administrators.Value `
} | `
ForEach-Object { $null = $RegAcl.RemoveAccessRule($_) }

# Create a new rule allowing the Administrators Full Control.
$RegRule = [System.Security.AccessControl.RegistryAccessRule]::new( `
$Administrators `
, 'FullControl' `
, 'ContainerInherit' `
, 'None' `
, 'Allow')
$RegACL.SetAccessRule($RegRule)
$RegKey.SetAccessControl($RegACL)

# Close the Registry Key.
$RegKey.Close()


##############################################################
# Step 4: Change the 'LocalizedString' property
# in the registry to suit your needs.
##############################################################
#
# With PowerShell 5, you need to use
# `Registry::HKEY_CLASSES_ROOT\..` syntax in order to be able
# to set the registry Type for the value
# with parameter '-Type'.
# As of PowerShell 7, the '-Type' parameter is included.

$RegPath = `
'Registry::HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}'
Set-ItemProperty -Path $RegPath `
-Name 'LocalizedString' `
-Value "%ComputerName%" `
-Type ExpandString `
-Force

我在控制台中得到的是以下文本:

PS C:\WINDOWS\system32> C:\Users\MihaiDobrescu\OneDrive\Documents\2_Facturi\12_-_Bank_Services\Digitization\Powershell\Change_Registry_Key.3.PS1 -RunAsAdministrator
VERBOSE: Enabling privilege 'SeTakeOwnershipPrivilege' for process powershell_ise

PS C:\WINDOWS\system32>

更新:最终版本,里面有美丽汤的所有成分。

再次感谢@Theo,他实际上调试了整个困惑。

注意:该片段甚至在虚拟机内部也能正常工作,因为它不需要以管理员身份运行,因为在为了解决这个问题。

# How to test:
#
# 1. Rename the My Computer Desktop Icon to "Fifi".
# 2. Remove the My Computer Desktop Icon from the Desktop View.
# 3. Run this snippet.
# 4. Observe how the My Computer Desktop Icon is produced on the Desktop View,
# with the name "Tele-Ordinator" and with a very emotional Desktop Icon.

# Allow the execution of snippets.

Set-ExecutionPolicy `
-ExecutionPolicy RemoteSigned `
-Scope CurrentUser

# Produce the My Computer Desktop Icon on the Desktop View.

# HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel\
# {20D04FE0-3AEA-1069-A2D8-08002B30309D}
# 0 = show
# 1 = hide

$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel"

$Name = "{20D04FE0-3AEA-1069-A2D8-08002B30309D}"

$Exist = "Get-ItemProperty -Path $Path -Name $Name"

if ($Exist)
{
Set-ItemProperty `
-Path $Path `
-Name $Name `
-Value 0
}
Else
{
New-ItemProperty `
-Path $Path `
-Name $Name `
-Value 0
}

# Rename the My Computer Desktop Icon from "This PC" to "Tele-Ordinator".

$My_Computer = 17

$Shell = New-Object -COMObject Shell.Application

$NSComputer = $Shell.Namespace($My_Computer)

$NSComputer.Self.Name = "Tele-Ordinator"

# Change the My Computer Desktop Icon.

$RegPath = `
'Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon'

if (!(Test-Path -Path $RegPath))
{
$null = New-Item `
-Path $RegPath `
-Force
}

Set-ItemProperty `
-Path $RegPath `
-Name '(Default)' `
-Value 'Y:\Digitization\Icons\Robsonbillponte-Happy-Holidays-Pictures.ICO' `
-Type ExpandString `
-Force

# Refresh the Desktop View.

$Definition = @'

[System.Runtime.InteropServices.DllImport("Shell32.dll")]

private static extern int SHChangeNotify(
int eventId
, int flags
, IntPtr item1
, IntPtr item2);

public static void Refresh()
{
SHChangeNotify(
0x8000000
, 0x1000
, IntPtr.Zero
, IntPtr.Zero);
}
'@

Add-Type `
-MemberDefinition $Definition `
-Namespace WinAPI `
-Name Explorer

[WinAPI.Explorer]::Refresh()

另一个最终更新,用于设置和运行使用 Microsoft Windows 批处理文件预处理系统自动执行上述自动化操作的批处理文件:

这只是一个名为 Change_Desktop_Icons.BAT 的简短片段。

ChDir %SystemRoot%\System32\WindowsPowerShell\v1.0\

%SystemRoot%\System32\WindowsPowerShell\v1.0\PowerShell.Exe Y:\Digitization\PowerShell\The_My_Computer_Desktop_Icon\Change_Desktop_Icon.PS1

Pause

这是事物的输出,双击它自己的桌面图标。

'\\ISXPFV01.hd00.example.com\us_qv2_dem_user_data_pool_nra$\EE65037.HD00\Desktop'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.

C:\Windows>ChDir C:\WINDOWS\System32\WindowsPowerShell\v1.0\

C:\Windows\System32\WindowsPowerShell\v1.0>C:\WINDOWS\System32\WindowsPowerShell\v1.0\PowerShell.Exe Y:\Digitization\PowerShell\The_My_Computer_Desktop_Icon\Change_Desktop_Icon.PS1

C:\Windows\System32\WindowsPowerShell\v1.0>Pause
Press any key to continue . . .

最佳答案

如评论所述,更改“计算机”图标标题非常麻烦..

以下代码适用于使用 PowerShell 5.1 的 Windows 10 Pro

您需要以管理员身份运行它

#Requires -RunAsAdministrator

function Enable-Privilege {
[CmdletBinding(ConfirmImpact = 'low', SupportsShouldProcess = $false)]
[OutputType('System.Boolean')]
Param(
[Parameter(Mandatory = $true, Position = 0)]
[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")]
[String]$Privilege,

[Parameter(Position = 1)]
$ProcessId = $PID,

[switch]$Disable
)


Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

public class Privilege {
[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;
}
}
'@

try {
$proc = Get-Process -Id $ProcessId -ErrorAction Stop
$name = $proc.ProcessName
$handle = $proc.Handle
$action = if ($Disable) { 'Disabling' } else { 'Enabling' }
Write-Verbose ("{0} privilege '{1}' for process {2}" -f $action, $Privilege, $name)
[Privilege]::EnablePrivilege($handle, $Privilege, [bool]$Disable)
}
catch {
throw
}
}

function Grant-FullControl ([string]$SubKey, [switch]$BreakInheritance) {
# helper function to grant registry FullControl for Administrators on a certain subkey

# better not use the string "Administrators", because this might have a different name in other cultures
# $RegACL.SetOwner([System.Security.Principal.NTAccount]"Administrators")
# use the Well-Known SID instead
$Administrators = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-32-544') # local Administrators group

$RegKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey($SubKey,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::TakeOwnership)

$RegACL = $RegKey.GetAccessControl()
if ($BreakInheritance) {
# break inheritance, but keep permissions
$RegACL.SetAccessRuleProtection($true, $true)
}

$RegACL.SetOwner($Administrators)
$RegKey.SetAccessControl($RegACL)

# refresh the ACL
$RegACL = $RegKey.GetAccessControl()

# test if there is a Deny rule in the ACL for Administrators and if so remove that rule
$RegACL.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]) |
Where-Object { $_.AccessControlType -eq 'Deny' -and $_.IdentityReference -eq $Administrators.Value } |
ForEach-Object { $null = $RegAcl.RemoveAccessRule($_) }

# ceate a new rule allowing the Administrators FullControl
$RegRule =[System.Security.AccessControl.RegistryAccessRule]::new($Administrators,
'FullControl',
'ContainerInherit', # ContainerInherit, ObjectInherit
'None', # InheritOnly
'Allow')
$RegACL.SetAccessRule($RegRule)
$RegKey.SetAccessControl($RegACL)

# close the registry key
$RegKey.Close()
}

##################################################################################
# Step 1: give the current process the SeTakeOwnershipPrivilege
##################################################################################

$null = Enable-Privilege -Privilege SeTakeOwnershipPrivilege -Verbose

##################################################################################
# Step 2: change Key Owner to the local Administrators group and grant FullControl
##################################################################################

# first give Administrators full control on key "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
Grant-FullControl -SubKey "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -BreakInheritance

##################################################################################
# Step 3: change the 'LocalizedString' property in the registry to suit your needs
##################################################################################

# with PowerShell 5 you need to use `Registry::HKEY_CLASSES_ROOT\..` syntax in order to be able
# to set the registry Type for the value with parameter '-Type'.
# As of PowerShell 7 the '-Type' parameter is included

$regPath = 'Registry::HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}'
Set-ItemProperty -Path $regPath -Name 'LocalizedString' -Value "%ComputerName%" -Type ExpandString -Force

##################################################################################
# Step 4: OPTIONAL. Change the Computer icon for NEW user logins
##################################################################################

# give Administrators full control on subkey "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon"
# now, we do not need to break the inheritance as we needed for the root key
Grant-FullControl -SubKey "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon"

$regPath = 'Registry::HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon'
Set-ItemProperty -Path $regPath -Name '(Default)' -Value '%SystemRoot%\System32\imageres.dll,-149' -Type ExpandString -Force

##################################################################################
# Step 5: Change the Computer icon for the CURRENT user
##################################################################################

$regPath = 'Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon'
Set-ItemProperty -Path $regPath -Name '(Default)' -Value '%SystemRoot%\System32\imageres.dll,-149' -Type ExpandString -Force

所有这一切之后,桌面还没有显示计算机名。您需要在桌面上按 F5,或使用找到的代码刷新桌面。


要更改图标本身,您需要更改注册表路径中的默认值

HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon 

用于将来的新登录,或注册表路径

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon

对于当前用户。

默认指向%SystemRoot%\System32\imageres.dll,-109,即提取图标号。 109 来自 imageres.dll。在那个dll中。有大约 343 个图标,因此您可以选择使用同一资源中的另一个图标,或者从另一个现有的 dll 中获取一个。 (例如,您可以使用 nirsoft 的 IconsExtract)。

我还没有对此进行测试,但也应该可以让它指向您自己的图标的完整路径和文件名,例如 %SystemDrive%\MyComputerIcon.ico

例如,这将更新图标以使用 imageres.dll 图标号。 149

$regPath = 'Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\DefaultIcon'
Set-ItemProperty -Path $regPath -Name '(Default)' -Value '%SystemRoot%\System32\imageres.dll,-149' -Type ExpandString -Force

看起来像这样

enter image description here

关于windows - 如何使用 Powershell 更改我的电脑桌面图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66352179/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com