PowerShell 技能连载 - 显示警告对话框(第 1 部分)

这是一个显示弹出警告对话框的快速代码示例:

1
2
3
4
5
Add-Type -AssemblyName  System.Windows.Forms
$message = 'Your system will shutdown soon!'
$title = 'Alert'

[System.Windows.Forms.MessageBox]::Show($message, $title, [System.Windows.Forms.MessageBoxButtons]::OKCancel, [System.Windows.Forms.MessageBoxIcon]::Warning)

这些是可用的按钮样式:

1
2
3
4
5
6
7
PS> [Enum]::GetNames([System.Windows.Forms.MessageBoxButtons])
OK
OKCancel
AbortRetryIgnore
YesNoCancel
YesNo
RetryCancel

这些是可用的图标样式:

1
2
3
4
5
6
7
8
9
10
PS> [Enum]::GetNames([System.Windows.Forms.MessageBoxIcon])
None
Hand
Error
Stop
Question
Exclamation
Warning
Asterisk
Information

PowerShell 技能连载 - 处理控制台命令的错误

有时,在 PowerShell 脚本中使用控制台应用程序很有用,甚至是必要的。例如,在上一个技能中,我们研究了删除映射网络驱动器的方法,尽管 Remove-PSDrive 声称能够执行此操作,但最可靠的方法仍然是使用旧的 net.exe 控制台命令。

让我们快速看看如何检查控制台命令是否成功完成。

让我们尝试通过映射一个新的网络驱动器,然后使用控制台应用程序将其删除。当然,您可以将相同的原则应用于您可能需要在 PowerShell 脚本中运行的任何控制台应用程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PS> net use z: \\127.0.0.1\c$
The command completed successfully.


PS> net use z: /delete
z: was deleted successfully.

PS> net use z: /delete
net : The network connection could not be found.
At line:1 char:1
+ net use z: /delete
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (The network con...d not be found.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

More help is available by typing NET HELPMSG 2250.

创建好映射驱动器,然后再删除。但是,状态消息是本地化的(因此很难将它们与多国环境中的预期值进行比较),并且错误会作为异常出现。

通过使用 $?,您可以将输出转换为仅 $true$false$true 表示命令成功完成,而 $false 表示(任何)错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
PS> $null = net use z: \\127.0.0.1\c$; $result = $?; $result
True

PS> $null = net use z: \\127.0.0.1\c$; $result = $?; $result
net : System error 85 has occurred.
At line:1 char:9
+ $null = net use z: \\127.0.0.1\c$; $result = $?; $result
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (System error 85 has occurred.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

The local device name is already in use.
False

这要好得多,因为您的脚本随后可以判断 $result 并在出现错误时采取适当的步骤或将消息写入日志文件。

但是,如果出现错误,详细的错误信息仍会发送到控制台,并且没有(明显的)方法可以将其删除。即使是成熟的 try...catch 错误处理程序也不会响应它们:

1
2
3
4
5
6
7
8
9
10
PS> $null = try { net use z: \\127.0.0.1\c$} catch {}; $result = $?; $result
net : System error 85 has occurred.
At line:1 char:15
+ $null = try { net use z: \\127.0.0.1\c$} catch {}; $result = $?; $res ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (System error 85 has occurred.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

The local device name is already in use.
False

原因是:控制台应用程序不会抛出 .NET 异常。发生错误时,控制台应用程序仅通过输出流 #2 发出信息。

而这恰好是包装控制台应用程序的解决方案:将所有流重定向到输出流。这段代码映射了一个网络驱动器:第一次调用成功所有后续调用都失败:

1
2
3
4
5
6
7
8
PS> $null = net use z: \\127.0.0.1\c$ *>&1; $?
True

PS> $null = net use z: \\127.0.0.1\c$ *>&1; $?
False

PS> $null = net use z: \\127.0.0.1\c$ *>&1; $?
False

同样,这会再次删除映射的驱动器,就像在第一次调用成功之前一样,所有剩余的调用都会失败:

1
2
3
4
5
6
7
8
PS> $null = net use z: /delete *>&1; $result = $?; $result
True

PS> $null = net use z: /delete *>&1; $result = $?; $result
False

PS> $null = net use z: /delete *>&1; $result = $?; $result
False

PowerShell 技能连载 - 移除网络驱动器

虽然 Remove-PSDrive 可以删除包括网络驱动器在内的所有类型的驱动器,但更改可能要等系统重新启动时才能生效。这当然是荒谬的。

这个任务是一个很好的例子,为什么 PowerShell 使控制台应用程序成为平等公民是有用的。事实上,即使在 2021 年,移除网络驱动器的最可靠方法也是使用旧的但经过验证的 net.exe。下面的示例删除网络驱动器号 Z:

1
2
PS> net use z: /delete
z: was deleted successfully.

PowerShell 技能连载 - 列出网络驱动器

有很多方法可以列出映射的网络驱动器。其中之一使用 PowerShell 的 Get-PSDrive 并检查目标根目录是否以 “\“ 开头,表示 UNC 网络路径:

1
2
3
4
5
PS> Get-PSDrive -PSProvider FileSystem | Where-Object DisplayRoot -like '\\*'

Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
Z 11076,55 0,00 FileSystem \\192.168.2.107\docs

一个不错的方面是 Get-PSDrive 返回有用的附加详细信息,例如驱动器的大小。

PowerShell 技能连载 - 读取打印机属性(第 3 部分)

在之前的技能中,我们研究了如何使用 Get-PrinterProperty 读取本地安装打印机的打印机属性。此 cmdlet 是所有 Windows 操作系统附带的 PrintManagement 模块的一部分。

重要提示:由于属性名称是特定于打印驱动程序的,如果您需要在整个企业中管理相同类型的打印机,此 cmdlet 会非常有用。如果您想为大量不同的打印机类型创建详细的打印机清单,这不是最佳选择,因为您必须为每个正在使用的打印机驱动程序确定确切的属性名称。同样,在下面的示例中,请确保将打印机属性名称替换为您的打印机支持的名称。

简而言之,要读取特定的打印机属性,您需要提供打印机的名称(运行 Get-Printer 以查找打印机名称)。然后该 cmdlet 会列出所有可用的打印机属性,这些属性可能会因打印机驱动程序和型号而异:

1
2
3
4
5
6
7
8
9
10
11
12
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP'

ComputerName PrinterName PropertyName Type Value
------------ ----------- ------------ ---- -----
S/W Laser HP Config:AccessoryO... String 500Stapler
S/W Laser HP Config:ActualCust... String 431800_914400
S/W Laser HP Config:AutoConfig... String NotInstalled
S/W Laser HP Config:Auto_install String INSTALLED
S/W Laser HP Config:BookletMak... String NOTINSTALLED
S/W Laser HP Config:CombineMed... String Installed
S/W Laser HP Config:DeviceIsMo... String Installed
S/W Laser HP Config:DuplexUnit String Installed

例如,您可以过滤属性名称并获取已安装和已卸载打印机附件的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP' | Where-Object Value -like *installed* | Select-Object -Property PropertyName, Value

PropertyName Value
------------ -----
Config:AutoConfiguration NotInstalled
Config:Auto_install INSTALLED
Config:BookletMakerUnit_PC NOTINSTALLED
Config:CombineMediaTypesAndInputBins Installed
Config:DeviceIsMopier Installed
Config:DuplexUnit Installed
Config:EmbeddedJobAccounting NotInstalled
Config:EnvFeed_install NOTINSTALLED
Config:HPJobSeparatorPage NotInstalled
Config:HPPinToPrintOnly NotInstalled
Config:HPPunchUnitType NotInstalled
Config:InsLwH1_install NOTINSTALLED
Config:InsUpH1_install NOTINSTALLED
Config:JobRetention Installed
Config:ManualFeed_install INSTALLED
Config:PCCFoldUnit NOTINSTALLED
Config:PCVFoldUnit NOTINSTALLED
Config:PrinterHardDisk Installed
Config:SecurePrinting Installed
Config:StaplingUnit_PC NOTINSTALLED
Config:Tray10_install NOTINSTALLED
Config:Tray1_install INSTALLED
Config:Tray2_install INSTALLED
Config:Tray3_install INSTALLED
Config:Tray4_install NOTINSTALLED
Config:Tray5_install NOTINSTALLED
Config:Tray6_install NOTINSTALLED
Config:Tray7_install NOTINSTALLED
Config:Tray8_install NOTINSTALLED
Config:Tray9_install NOTINSTALLED
Config:TrayExt1_install NOTINSTALLED
Config:TrayExt2_install NOTINSTALLED
Config:TrayExt3_install NOTINSTALLED
Config:TrayExt4_install NOTINSTALLED
Config:TrayExt5_install NOTINSTALLED
Config:TrayExt6_install NOTINSTALLED

知道打印机名称和特定属性名称后,您可以查询各个属性并检索值以在脚本中使用它。以下是检查是否安装了双面打印单元的示例(确保将打印机名称和属性名称调整为您的打印机型号):

1
2
3
4
5
6
7
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP' -PropertyName Config:DuplexUnit | Select-Object -ExpandProperty Value
Installed

PS> $hasDuplexUnit = (Get-PrinterProperty -PrinterName 'S/W Laser HP' -PropertyName Config:DuplexUnit).Value -eq 'installed'

PS> $hasDuplexUnit
True

要远程查询打印机,Get-PrinterProperty 具有 -ComputerName 参数。它接受单个字符串,因此您一次只能查询一台打印机,并且没有 -Credential 参数,因此您无法以其他人身份进行身份验证。你可以试试这个来查询你自己的机器,一旦成功,用真正的远程系统替换计算机名称:

1
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP' -ComputerName $env:COMPUTERNAME

由于 cmdlet 使用 Windows 远程管理服务进行远程访问,因此目标打印服务器应启用 WinRM 远程处理(这是 Windows 服务器的默认设置),并且您应该是目标端的管理员。

实际情况中,您还希望能够查询多个服务器并以其他人身份进行身份验证。对于远程访问,首先使用 New-CimSession 指定要查询的所有服务器,并根据需要提交凭据。

接下来,将此会话提交给 Get-PrinterProperty。如果您有适当的访问权限,现在可以并行查询会话中的所有服务器,从而节省大量时间。-ThrottleLimit 参数确定最多实际联系多少个会话。如果您指定的服务器数超过最大连接数,PowerShell 将自动将其余服务器排队:

1
2
3
4
5
$session = New-CimSession -ComputerName server1, server2, server3 -Credential mydomain\remotinguser

Get-PrinterProperty -PrinterName 'S/W Laser HP' -CimSession $session -ThrottleLimit 100

Remove-CimSession -CimSession $session

额外提示:您也可以使用 Get-Printer 查找远程打印机名称。Get-Printer 还接受 -CimSession 参数,因此您可以使用相同的网络会话从一台或多台远程服务器查询所有打印机名称。

PowerShell 技能连载 - 读取打印机属性(第 2 部分)

在上一个技能中,我们查看了 Get-PrinterProperty,它是 PrintManagement 模块的一部分,可在 Windows 操作系统上使用。

在这个技能中,让我们看看如何在自己的脚本中实际使用打印机值,以及与使用简单数组相比,如何将它们存储在哈希表中使访问打印机属性更容易。

重要提示:实际的打印机属性及其名称取决于您的打印机型号和打印机驱动程序。上面示例中使用的属性名称可能因打印机而异。

当您将 Get-PrinterProperty 返回的结果存储在一个变量中时,该变量包含一个简单的数组,您的工作是使用您所追求的属性来标识数组元素。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
PS> $info = Get-PrinterProperty -PrinterName 'S/W Laser HP'

# return result is an array
PS> $info -is [Array]
True

# array elements can only be accessed via numeric index
PS> $info.Count
64

# the number of returned properties depends on the printer model
# the index of given properties may change so accessing a property by
# index works but can be unreliable:
PS> $info[0]

ComputerName PrinterName PropertyName Type Value
------------ ----------- ------------ ---- -----
S/W Laser HP Config:AccessoryO... String 500Stapler


# the actual property value is stored in the property “Value”
PS> $info[0].Value
500Stapler

# using comparison operators, you can convert string content to Boolean
# for example to check whether a printer has a certain feature installed
PS> $info[2]

ComputerName PrinterName PropertyName Type Value
------------ ----------- ------------ ---- -----
S/W Laser HP Config:AutoConfig... String NotInstalled

PS> $info[2].Value
NotInstalled

PS> $info[2].Value -eq 'NotInstalled'
True

更安全的方法是将结果存储在哈希表中并使用原始属性名称作为键。众所周知,Group-Object 可以自动为您创建哈希表。只需告诉 Group-Object 要用于分组的属性的名称,并要求取回哈希表并将字符串用作哈希表键:

1
$info = Get-PrinterProperty -PrinterName 'S/W Laser HP' | Group-Object -Property PropertyName -AsHashTable -AsString

这一次,$info 包含一个哈希表,如果您使用带有 IntelliSense 的 PowerShell 编辑器(如 ISE 或 VSCode),一旦您在输入变量名时按下键盘上的点,就会获得丰富的 IntelliSense,显示可用的属性名称。在控制台中,您可以按 TAB 以使用自动完成功能。

由于 IntelliSense 菜单和 TAB 自动完成还包含一些与哈希表相关的属性和方法,因此您可能需要向下滚动一点或分别按 TAB 几次。

要查询打印机属性的值,选择属性名称后,您需要在属性名称周围添加引号,因为通常打印机属性名称包含特殊字符,如冒号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# hash table keys need to be quoted
PS> $info.Config:AccessoryOutputBins
At line:1 char:13
+ $info.Config:AccessoryOutputBins
+             ~~~~~~~~~~~~~~~~~~~~
Unexpected token ':AccessoryOutputBins' in expression or statement.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken


# once you add quotes, all is fine
PS> $info.'Config:AccessoryOutputBins'

ComputerName         PrinterName          PropertyName         Type       Value
------------         -----------          ------------         ----       -----
                     S/W Laser HP         Config:AccessoryO... String     500Stapler

PS> $info.'Config:AccessoryOutputBins'.Value
500Stapler

PowerShell 技能连载 - 读取打印机属性(第 1 部分)

您可能知道 Get-Printer,它返回系统上所有已安装打印机的名称。但是,您无法通过这种方式获得特定的打印机功能或设置。

Get-PrinterProperty 可以提供帮助。只需提交打印机名称(使用 Get-Printer 找出可用的打印机名称),然后运行以下命令(确保将打印机名称更改为存在的名称):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP'

ComputerName PrinterName PropertyName Type Value
------------ ----------- ------------ ---- -----
S/W Laser HP Config:AccessoryO... String 500Stapler
S/W Laser HP Config:ActualCust... String 431800_914400
S/W Laser HP Config:AutoConfig... String NotInstalled
S/W Laser HP Config:Auto_install String INSTALLED
S/W Laser HP Config:BookletMak... String NOTINSTALLED
S/W Laser HP Config:CombineMed... String Installed
S/W Laser HP Config:DeviceIsMo... String Installed
S/W Laser HP Config:DuplexUnit String Installed
S/W Laser HP Config:DynamicRender String AUTODEVICE
S/W Laser HP Config:EMFSpooling String Automatic
S/W Laser HP Config:EdgeToEdge... String Enabled
S/W Laser HP Config:EmbeddedJo... String NotInstalled
S/W Laser HP Config:EnvFeed_in... String NOTINSTALLED
S/W Laser HP Config:HPDisplayD... String True
S/W Laser HP Config:HPFontInst... String TRUE
S/W Laser HP Config:HPInstalla... String HP2HolePunch-Q3689
S/W Laser HP Config:HPInstalla... String 500Stapler-Q2443
S/W Laser HP Config:HPInstalla... String Auto_install
S/W Laser HP Config:HPJobSepar... String NotInstalled
S/W Laser HP Config:HPMOutputB... String 500Stapler-Q2443
S/W Laser HP Config:HPMOutputB... String None
S/W Laser HP Config:HPOutputBi... String 0-0
S/W Laser HP Config:HPPCL6Version String PDL_VERSION_2-1_OR_GREATER
S/W Laser HP Config:HPPinToPri... String NotInstalled
S/W Laser HP Config:HPPrnPropR... String hpchl230.cab
S/W Laser HP Config:HPPunchUni... String NotInstalled
S/W Laser HP Config:InsLwH1_in... String NOTINSTALLED
S/W Laser HP Config:InsUpH1_in... String NOTINSTALLED
S/W Laser HP Config:JobRetention String Installed
S/W Laser HP Config:LineWidthC... String Disabled
S/W Laser HP Config:ManualFeed... String INSTALLED
S/W Laser HP Config:Memory String 128MB
S/W Laser HP Config:PCCFoldUnit String NOTINSTALLED
S/W Laser HP Config:PCOptional... String None
S/W Laser HP Config:PCVFoldUnit String NOTINSTALLED
S/W Laser HP Config:PrinterHar... String Installed
S/W Laser HP Config:ProductClass String HP
S/W Laser HP Config:SHAccessor... String None
S/W Laser HP Config:SHByPassTray String None
S/W Laser HP Config:SHDocInser... String None
S/W Laser HP Config:SHInstalla... String MXFN19
S/W Laser HP Config:SHLargeCap... String None
S/W Laser HP Config:SHMOutputB... String None
S/W Laser HP Config:SHPaperFol... String None
S/W Laser HP Config:SHPuncherUnit String None
S/W Laser HP Config:SPSOptiona... String None
S/W Laser HP Config:SecurePrin... String Installed
S/W Laser HP Config:StaplingUn... String NOTINSTALLED
S/W Laser HP Config:Tray10_ins... String NOTINSTALLED
S/W Laser HP Config:Tray1_install String INSTALLED
S/W Laser HP Config:Tray2_install String INSTALLED
S/W Laser HP Config:Tray3_install String INSTALLED
S/W Laser HP Config:Tray4_install String NOTINSTALLED
S/W Laser HP Config:Tray5_install String NOTINSTALLED
S/W Laser HP Config:Tray6_install String NOTINSTALLED
S/W Laser HP Config:Tray7_install String NOTINSTALLED
S/W Laser HP Config:Tray8_install String NOTINSTALLED
S/W Laser HP Config:Tray9_install String NOTINSTALLED
S/W Laser HP Config:TrayExt1_i... String NOTINSTALLED
S/W Laser HP Config:TrayExt2_i... String NOTINSTALLED
S/W Laser HP Config:TrayExt3_i... String NOTINSTALLED
S/W Laser HP Config:TrayExt4_i... String NOTINSTALLED
S/W Laser HP Config:TrayExt5_i... String NOTINSTALLED
S/W Laser HP Config:TrayExt6_i... String NOTINSTALLED

注意:Get-PrinterProperty 是 Windows 操作系统(客户端和服务器)附带的 PrintManagement 模块的一部分。如果您使用非常旧的 Windows 操作系统或其他操作系统,则 cmdlet 可能不可用。

返回的属性列表取决于打印机型号。运行此命令以仅获取可用属性名的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP' | Select-Object -ExpandProperty PropertyName | Sort-Object -Unique
Config:AccessoryOutputBins
Config:ActualCustomRange
Config:Auto_install
Config:AutoConfiguration
Config:BookletMakerUnit_PC
Config:CombineMediaTypesAndInputBins
Config:DeviceIsMopier
Config:DuplexUnit
Config:DynamicRender
Config:EdgeToEdgeSupport_PC
Config:EmbeddedJobAccounting
Config:EMFSpooling
Config:EnvFeed_install
Config:HPDisplayDocUITab
Config:HPFontInstaller
Config:HPInstallableFinisher
Config:HPInstallableHCO
Config:HPInstallableTrayFeatureName
Config:HPJobSeparatorPage
Config:HPMOutputBinHCOMap
Config:HPMOutputBinHCOPMLMap
Config:HPOutputBinPMLRange
Config:HPPCL6Version
Config:HPPinToPrintOnly
Config:HPPrnPropResourceData
Config:HPPunchUnitType
Config:InsLwH1_install
Config:InsUpH1_install
Config:JobRetention
Config:LineWidthCorrection
Config:ManualFeed_install
Config:Memory
Config:PCCFoldUnit
Config:PCOptionalOutputBin
Config:PCVFoldUnit
Config:PrinterHardDisk
Config:ProductClass
Config:SecurePrinting
Config:SHAccessoryOutputBins
Config:SHByPassTray
Config:SHDocInsertionUnit
Config:SHInstallableHCO
Config:SHLargeCapacityTray
Config:SHMOutputBinHCOMap
Config:SHPaperFoldUnit
Config:SHPuncherUnit
Config:SPSOptionalOutputBin
Config:StaplingUnit_PC
Config:Tray1_install
Config:Tray10_install
Config:Tray2_install
Config:Tray3_install
Config:Tray4_install
Config:Tray5_install
Config:Tray6_install
Config:Tray7_install
Config:Tray8_install
Config:Tray9_install
Config:TrayExt1_install
Config:TrayExt2_install
Config:TrayExt3_install
Config:TrayExt4_install
Config:TrayExt5_install
Config:TrayExt6_install

一旦您知道您所希望了解的属性名,您就可以将结果限制为以下属性:

1
2
3
4
5
6
PS> Get-PrinterProperty -PrinterName 'S/W Laser HP' -PropertyName Config:AccessoryOutputBins, Config:BookletMakerUnit_PC

ComputerName PrinterName PropertyName Type Value
------------ ----------- ------------ ---- -----
S/W Laser HP Config:AccessoryO... String 500Stapler
S/W Laser HP Config:BookletMak... String NOTINSTALLED

PowerShell 技能连载 - 在 Windows 10 上启用 Telnet

每个 Windows 10 版本都附带一个 telnet 客户端,但它最初是隐藏的。要启用 telnet 客户端,请以完全管理员权限运行以下命令:

1
2
3
4
5
6
PS> Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient -All


Path :
Online : True
RestartNeeded : False

安装 telnet 客户端后,您可以使用它与另一台计算机的任何端口进行远程通信。由于新命令 “telnet“ 是一个控制台应用程序,因此请确保在真正的控制台窗口中运行它,例如 powershell.exepwsh.exe,而不是 ISE 编辑器。

PowerShell 技能连载 - 管理快捷方式文件(第 3 部分)

在上一个技巧中,我们创建了新的快捷方式文件,您已经看到 CreateShortcut() 方法如何提供方法来控制快捷方式的几乎所有细节。这是在桌面上创建 PowerShell 快捷方式的代码:

1
2
3
4
5
$path = [Environment]::GetFolderPath('Desktop') | Join-Path -ChildPath 'myLink.lnk'
$scut = (New-Object -ComObject WScript.Shell).CreateShortcut($path)
$scut.TargetPath = 'powershell.exe'
$scut.IconLocation = 'powershell.exe,0'
$scut.Save()

但是,代码不能做的一件事是启用快捷方式文件的管理员权限,因此双击快捷方式图标会自动提升 LNK 文件启动的 PowerShell。

要启用管理员权限,您必须右键单击新创建的快捷方式文件并手动选择“属性”,然后手动检查相应的对话框。

或者,您需要知道 URL 文件的二进制格式,并通过 PowerShell 翻转这些位。下面的代码将你刚刚在桌面上创建的快捷方式文件变成了一个自动提升的文件:

1
2
3
4
5
6
7
8
9
# launch LNK file as Administrator
# THIS PATH MUST EXIST (use previous script to create the LNK file or create one manually)
$path = [Environment]::GetFolderPath('Desktop') | Join-Path -ChildPath 'myLink.lnk'
# read LNK file as bytes...
$bytes = [System.IO.File]::ReadAllBytes($path)
# flip a bit in byte 21 (0x15)
$bytes[0x15] = $bytes[0x15] -bor 0x20
# update the bytes
[System.IO.File]::WriteAllBytes($path, $bytes)

当您现在双击 LNK 文件时,它会自动提升权限。将位翻转回原位以从任何 LNK 文件中删除管理员权限功能:

1
$bytes[0x15] = $bytes[0x15] -band -not 0x20

PowerShell 技能连载 - 管理快捷方式文件(第 2 部分)

在上一个技巧中,我们创建了新的快捷方式文件,您已经看到 CreateShortcut() 方法如何提供方法来控制快捷方式的几乎所有细节。这是在桌面上创建 PowerShell 快捷方式的代码:

1
2
3
4
5
$path = [Environment]::GetFolderPath('Desktop') | Join-Path -ChildPath 'myLink.lnk'
$scut = (New-Object -ComObject WScript.Shell).CreateShortcut($path)
$scut.TargetPath = 'powershell.exe'
$scut.IconLocation = 'powershell.exe,0'
$scut.Save()

这就是全部:在您的桌面上现在有一个新的 PowerShell 快捷方式。调整上面的代码以创建其他应用程序和路径的快捷方式。