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

PowerShell 可以创建新的 LNK 文件并在旧 COM 对象的帮助下编辑现有文件。

让我们首先在开始菜单中的任何位置找到所有 LNK 文件:

1
[Environment]::GetFolderPath('StartMenu') | Get-ChildItem -Filter *.lnk -Recurse

这样可以获取到在开始菜单中任何位置找到的所有 LNK 文件。

接下来,让我们读取它们并找出它们的目标和隐藏的键盘快捷键(如果有):

1
2
3
4
5
[Environment]::GetFolderPath('StartMenu') |
Get-ChildItem -Filter *.lnk -Recurse |
ForEach-Object { $scut = New-Object -ComObject WScript.Shell } {
$scut.CreateShortcut($_.FullName)
}

COM 对象 WScript.Shell 提供了一个名为 CreateShortcut() 的方法,当您传入现有 LNK 文件的路径时,您将返回其内部属性。

在我的环境下,这些 LNK 文件看起来类似于:

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Visual Studio Code\Visual Studio Code.lnk
Arguments        :
Description      :
Hotkey           :
IconLocation     : ,0
RelativePath     :
TargetPath       : C:\Users\tobia\AppData\Local\Programs\Microsoft VS Code\Code.exe
WindowStyle      : 1
WorkingDirectory : C:\Users\tobia\AppData\Local\Programs\Microsoft VS Code

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell (x86).lnk
Arguments        :
Description      : Performs object-based (command-line) functions
Hotkey           :
IconLocation     : %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe,0
RelativePath     :
TargetPath       : C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
WindowStyle      : 1
WorkingDirectory : %HOMEDRIVE%%HOMEPATH%

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell ISE (x86).lnk
Arguments        :
Description      : Windows PowerShell Integrated Scripting Environment. Performs object-based (command-line) functions
Hotkey           :
IconLocation     : %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell_ise.exe,0
RelativePath     :
TargetPath       : C:\WINDOWS\syswow64\WindowsPowerShell\v1.0\PowerShell_ISE.exe
WindowStyle      : 1
WorkingDirectory : %HOMEDRIVE%%HOMEPATH%

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell ISE.lnk
Arguments        :
Description      : Windows PowerShell Integrated Scripting Environment. Performs object-based (command-line) functions
Hotkey           :
IconLocation     : %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell_ise.exe,0
RelativePath     :
TargetPath       : C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe
WindowStyle      : 1
WorkingDirectory : %HOMEDRIVE%%HOMEPATH%

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk
Arguments        :
Description      : Performs object-based (command-line) functions
Hotkey           :
IconLocation     : %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe,0
RelativePath     :
TargetPath       : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
WindowStyle      : 1
WorkingDirectory : %HOMEDRIVE%%HOMEPATH%

FullName         : C:\Users\tobia\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Zoom\Uninstall Zoom.lnk
Arguments        : /uninstall
Description      : Uninstall Zoom
Hotkey           :
IconLocation     : C:\Users\tobia\AppData\Roaming\Zoom\bin\Zoom.exe,0
RelativePath     :
TargetPath       : C:\Users\tobia\AppData\Roaming\Zoom\uninstall\Installer.exe
WindowStyle      : 1
WorkingDirectory :

PowerShell 技能连载 - 在 Windows 10 中解锁额外的 PowerShell 模块

Windows 10 附带了许多可用于控制服务器功能的 PowerShell 模块 - 例如 WSUS 更新管理,这只是众多模块中的一个。

在早期的 Windows 10 版本中,这些 PowerShell 模块是所谓的 RSAT 工具(远程服务器管理工​​具)的一部分,需要单独下载。在最近的版本中,您已经拥有 RSAT 工具(本技巧中的所有命令都需要提升权限):

1
2
\#requires -RunAsAdmin
Get-WindowsCapability -Online -Name "Rsat.*" | Format-Table -AutoSize -Wrap -GroupBy Name -Property DisplayName, Description

结果类似于:

Name: Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Active Directory Domain Services and Lightweight Directory Services Tools	Description
-----------
Active Directory Domain Services (AD DS) and Active Directory Lightweight Directory Services (AD LDS) Tools include snap-ins and command-line tools for remotely managing AD DS and AD LDS on Windows Server.

    Name: Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: BitLocker Drive Encryption Administration Utilities	Description
-----------
BitLocker Drive Encryption Administration Utilities include tools for managing BitLocker Drive Encryption features.
BitLocker Active Directory Recovery Password Viewer helps to locate BitLocker drive encryption recovery passwords in Active Directory Domain Services (AD DS).

    Name: Rsat.CertificateServices.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Active Directory Certificate Services Tools	Description
-----------
Active Directory Certificate Services Tools include the Certification Authority, Certificate Templates, Enterprise PKI, and Online Responder Management snap-ins for remotely managing AD CS on Windows Server

    Name: Rsat.DHCP.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: DHCP Server Tools	Description
-----------
DHCP Server Tools include the DHCP MMC snap-in, DHCP server netsh context and Windows PowerShell module for DHCP Server.

    Name: Rsat.Dns.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: DNS Server Tools	Description
-----------
DNS Server Tools include the DNS Manager snap-in, dnscmd.exe command-line tool and Windows PowerShell module for DNS Server.

    Name: Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Failover Clustering Tools	Description
-----------
Failover Clustering Tools include the Failover Cluster Manager snap-in, the Cluster-Aware Updating interface, and the Failover Cluster module for Windows PowerShell

    Name: Rsat.FileServices.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: File Services Tools	Description
-----------
File Services Tools include snap-ins and command-line tools for remotely managing the File Services role on Windows Server.

    Name: Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Group Policy Management Tools	Description
-----------
Group Policy Management Tools include Group Policy Management Console, Group Policy Management Editor, and Group Policy Starter GPO Editor.

    Name: Rsat.IPAM.Client.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: IP Address Management (IPAM) Client	Description
-----------
IP Address Management (IPAM) Client is used to connect to and manage a remote IPAM server. IPAM provides a central framework for managing IP address space and corresponding infrastructure servers such as DHCP and DNS in an Active Directory forest.

    Name: Rsat.LLDP.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Data Center Bridging LLDP Tools	Description
-----------
Data Center Bridging LLDP Tools include PowerShell tools for remotely managing LLDP agents on Windows Server.

    Name: Rsat.NetworkController.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Network Controller Management Tools	Description
-----------
Network Controller Management Tools include PowerShell tools for managing the Network Controller role on Windows Server.

    Name: Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Network Load Balancing Tools	Description
-----------
Network Load Balancing Tools include the Network Load Balancing Manager snap-in, the Network Load Balancing module for Windows PowerShell, and the nlb.exe and wlbs.exe command-line tools.

    Name: Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Remote Access Management Tools	Description
-----------
Remote Access Management Tools include graphical and PowerShell tools for managing the Remote Access role on Windows Server.

    Name: Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Remote Desktop Services Tools	Description
-----------
Remote Desktop Services Tools include snap-ins for Remote Desktop Licensing Manager, Remote Desktop Licensing Diagnostics and Remote Desktop Gateway Manager. Use Server Manager to administer all other RDS role services.

    Name: Rsat.ServerManager.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Server Manager	Description
-----------
Server Manager includes the Server Manager console and PowerShell tools for remotely managing Windows Server, and includes tools to remotely configure NIC teaming on Windows Server and Best Practices Analyzer.

    Name: Rsat.Shielded.VM.Tools~~~~0.0.1.0


DisplayName
-----------
SAT: Shielded VM Tools	Description
-----------
Shielded VM Tools include the Provisioning Data File Wizard and the Template Disk Wizard.

    Name: Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Storage Migration Service Management Tools	Description
-----------
Provides management tools for storage migration jobs.

    Name: Rsat.StorageReplica.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Storage Replica Module for Windows PowerShell	Description
-----------
Includes PowerShell module to remotely manage the Storage Replica feature on Windows Server 2016.

    Name: Rsat.SystemInsights.Management.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: System Insights Module for Windows PowerShell	Description
-----------
System Insights module for Windows PowerShell provides the ability to manage System Insights feature.

    Name: Rsat.VolumeActivation.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Volume Activation Tools	Description
-----------
Volume activation Tools can be used to manage volume activation license keys on a Key Management Service (KMS) host or in Microsoft Active Directory Domain Services. These tools can be used to install, activate, and manage one or more volume activation license keys, and to configure KMS settings on Windows Server.

Name: Rsat.WSUS.Tools~~~~0.0.1.0


DisplayName
-----------
RSAT: Windows Server Update Services Tools	Description
-----------
Windows Server Update Services Tools include graphical and PowerShell tools for managing WSUS.

要访问所有 RSAT PowerShell 模块和工具,您可以像这样启用它们:

1
2
3
#requires -RunAsAdmin
Get-WindowsCapability -Online -Name "Rsat.*" |
Add-WindowsCapability -Online -Verbose

PowerShell 技能连载 - 启用 ActiveDirectory 模块

Windows 10 附带 ActiveDirectory PowerShell 模块 - 它可能尚未启用。如果您想使用 PowerShell cmdlet 进行 AD 管理 - 即 Get-ADUser - 只需以完全管理员权限运行以下代码:

1
2
3
4
#requires -RunAsAdmin

$element = Get-WindowsCapability -Online -Name "Rsat.ActiveDirectory.DS*"
Add-WindowsCapability -Name $element.Name -Online

完成后,您现在可以访问 ActiveDirectory 模块及其 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
PS C:\> Get-Command -Module ActiveDirectory | Format-Wide -Column 4


Add-ADCentralAccessPolicyMember Add-ADComputerServiceAccount Add-ADDomainControllerPasswordRep... Add-ADFineGrainedPasswordPolicyS...
Add-ADGroupMember Add-ADPrincipalGroupMembership Add-ADResourcePropertyListMember Clear-ADAccountExpiration
Clear-ADClaimTransformLink Disable-ADAccount Disable-ADOptionalFeature Enable-ADAccount
Enable-ADOptionalFeature Get-ADAccountAuthorizationGroup Get-ADAccountResultantPasswordRep... Get-ADAuthenticationPolicy
Get-ADAuthenticationPolicySilo Get-ADCentralAccessPolicy Get-ADCentralAccessRule Get-ADClaimTransformPolicy
Get-ADClaimType Get-ADComputer Get-ADComputerServiceAccount Get-ADDCCloningExcludedApplicati...
Get-ADDefaultDomainPasswordPolicy Get-ADDomain Get-ADDomainController Get-ADDomainControllerPasswordRe...
Get-ADDomainControllerPasswordRep... Get-ADFineGrainedPasswordPolicy Get-ADFineGrainedPasswordPolicySu... Get-ADForest
Get-ADGroup Get-ADGroupMember Get-ADObject Get-ADOptionalFeature
Get-ADOrganizationalUnit Get-ADPrincipalGroupMembership Get-ADReplicationAttributeMetadata Get-ADReplicationConnection
Get-ADReplicationFailure Get-ADReplicationPartnerMetadata Get-ADReplicationQueueOperation Get-ADReplicationSite
Get-ADReplicationSiteLink Get-ADReplicationSiteLinkBridge Get-ADReplicationSubnet Get-ADReplicationUpToDatenessVec...
Get-ADResourceProperty Get-ADResourcePropertyList Get-ADResourcePropertyValueType Get-ADRootDSE
Get-ADServiceAccount Get-ADTrust Get-ADUser Get-ADUserResultantPasswordPolicy
Grant-ADAuthenticationPolicySiloA... Install-ADServiceAccount Move-ADDirectoryServer Move-ADDirectoryServerOperationM...
Move-ADObject New-ADAuthenticationPolicy New-ADAuthenticationPolicySilo New-ADCentralAccessPolicy
New-ADCentralAccessRule New-ADClaimTransformPolicy New-ADClaimType New-ADComputer
New-ADDCCloneConfigFile New-ADFineGrainedPasswordPolicy New-ADGroup New-ADObject
New-ADOrganizationalUnit New-ADReplicationSite New-ADReplicationSiteLink New-ADReplicationSiteLinkBridge
New-ADReplicationSubnet New-ADResourceProperty New-ADResourcePropertyList New-ADServiceAccount
New-ADUser Remove-ADAuthenticationPolicy Remove-ADAuthenticationPolicySilo Remove-ADCentralAccessPolicy
Remove-ADCentralAccessPolicyMember Remove-ADCentralAccessRule Remove-ADClaimTransformPolicy Remove-ADClaimType
Remove-ADComputer Remove-ADComputerServiceAccount Remove-ADDomainControllerPassword... Remove-ADFineGrainedPasswordPolicy
Remove-ADFineGrainedPasswordPolic... Remove-ADGroup Remove-ADGroupMember Remove-ADObject
Remove-ADOrganizationalUnit Remove-ADPrincipalGroupMembership Remove-ADReplicationSite Remove-ADReplicationSiteLink
Remove-ADReplicationSiteLinkBridge Remove-ADReplicationSubnet Remove-ADResourceProperty Remove-ADResourcePropertyList
Remove-ADResourcePropertyListMember Remove-ADServiceAccount Remove-ADUser Rename-ADObject
Reset-ADServiceAccountPassword Restore-ADObject Revoke-ADAuthenticationPolicySilo... Search-ADAccount
Set-ADAccountAuthenticationPolicy... Set-ADAccountControl Set-ADAccountExpiration Set-ADAccountPassword
Set-ADAuthenticationPolicy Set-ADAuthenticationPolicySilo Set-ADCentralAccessPolicy Set-ADCentralAccessRule
Set-ADClaimTransformLink Set-ADClaimTransformPolicy Set-ADClaimType Set-ADComputer
Set-ADDefaultDomainPasswordPolicy Set-ADDomain Set-ADDomainMode Set-ADFineGrainedPasswordPolicy
Set-ADForest Set-ADForestMode Set-ADGroup Set-ADObject
Set-ADOrganizationalUnit Set-ADReplicationConnection Set-ADReplicationSite Set-ADReplicationSiteLink
Set-ADReplicationSiteLinkBridge Set-ADReplicationSubnet Set-ADResourceProperty Set-ADResourcePropertyList
Set-ADServiceAccount Set-ADUser Show-ADAuthenticationPolicyExpres... Sync-ADObject
Test-ADServiceAccount Uninstall-ADServiceAccount Unlock-ADAccount

PowerShell 技能连载 - 取证事件日志分析(第 2 部分)

在上一个技能中,我们查看了 Get-EventLog 以进行取证分析并在应用程序日志中查找与搜索相关的错误。Get-EventLog 使用简单,但速度慢且已弃用。虽然在 Windows PowerShell 上使用 Get-EventLog 是完全可以的,但您可能希望改用 Get-WinEvent。它速度更快,也可以在 PowerShell 7 上运行。

让我们快速将 Get-EventLog 转换为 Get-WinEvent,以进行上一技巧中介绍的取证分析。下面的代码在应用程序事件日志中查找与“搜索”源相关的所有错误(您的系统上可能没有):

1
2
3
4
5
6
7
8
9
# old
Get-EventLog -LogName Application -Source *search* -EntryType error -Newest 10 | Select-Object TimeGenerated, Message

# new
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
ProviderName = '*search*'
Level = 1,2
} -ErrorAction Ignore | Select-Object TimeCreated, Message

要将每天的事件分组,请使用 Group-Object 和日期作为分组标准:

1
2
3
4
5
6
7
8
9
10
# old
Get-EventLog -LogName Application -Source *search* -EntryType error | Group-Object { Get-Date $_.timegenerated -format yyyy-MM-dd } -NoElement


# new
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
ProviderName = '*search*'
Level = 1,2
} -ErrorAction Ignore | Group-Object { Get-Date $_.TimeCreated -format yyyy-MM-dd } -NoElement

同样,您的日志中可能没有任何与搜索相关的错误条目,但是当您调整条件并搜索不同的事件日志条目时,您会很快意识到 Get-WinEvent 的速度有多快。在上面的示例中,Get-WinEventGet-EventLog 快大约 10 倍。

PowerShell 技能连载 - 取证事件日志分析(第 1 部分)

事件日志记录 Windows 几乎所有方面的信息,因此如果出现问题或停止按预期工作,最好将事件日志取证策略包含在故障排除中。

例如,一些用户报告说他们的 Windows“即时搜索”停止查找更新的电子邮件项目。为什么索引服务不再随 Outlook 更新?

那时阅读事件日志会变得非常重要(并且很有帮助)。下面这行代码能快速找出您是否有系统索引问题。它在“应用程序”日志中搜索与“搜索”相关的任何错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PS> Get-EventLog -LogName Application -Source *search* -EntryType error -Newest 10 |
Select-Object TimeGenerated, Message

TimeGenerated Message
------------- -------
21.05.2021 09:55:48 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 09:48:03 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 08:55:14 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 08:47:53 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 08:32:15 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 08:28:41 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
21.05.2021 08:26:18 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
20.05.2021 18:14:48 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
20.05.2021 12:55:06 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...
20.05.2021 11:41:06 The protocol handler Mapi16 cannot be loaded. Error description: (HRES...

最明显的是,在这个例子中,Mapi16 协议处理程序似乎存在重复的系统问题,阻止索引服务读取 Outlook 电子邮件。

要了解问题何时发生以及它是否仍然令人担忧,您可以将事件日志条目分组并显示它们的频率:

1
2
PS> Get-EventLog -LogName Application -Source *search* -EntryType error |
Group-Object { Get-Date $_.timegenerated -format yyyy-MM-dd } -NoElement

本示例中的 Group-Object 使用脚本块来计算分组标准:在 同一天 发生的任何错误事件都被放入同一组中,该组返回一个时间顺序协议。这是示例输出:

Count Name
----- ----
    7 2021-05-21
    6 2021-05-20
   29 2021-05-19
   29 2021-05-18
   16 2021-05-17
    5 2021-05-16
    2 2021-05-15
    8 2021-05-14
    2 2021-05-13
    3 2021-05-12
    9 2021-05-11
   13 2021-05-10
    1 2021-05-09
    3 2021-05-08
    7 2021-05-07
   10 2021-05-06
   15 2021-05-05
    8 2021-05-04
   24 2021-05-03
   22 2021-05-02
   10 2021-05-01
    2 2021-04-30

输出清楚地表明该问题始于 4 月 30 日,一直持续到 5 月 21 日,当时它显然已得到修复。

显然,这些示例不会在您的机器上产生相同的结果(除非您遇到相同的问题)。它们确实展示了事件日志信息的价值以及 PowerShell 可以多么轻松地帮助对数据进行取证检查。

PowerShell 技能连载 - 生日派对的琐事

假设您受邀参加一位朋友的 37 岁生日。你可以在生日贺卡上放什么?试试这个:

1
2
PS> Invoke-RestMethod -Uri http://numbersapi.com/37 -UseBasicParsing
37 is the number of plays William Shakespeare is thought to have written (counting Henry IV as three parts).

只需将 URL 中的数字替换为您需要的任何实际数字。这是一个很好的例子,说明使用 PowerShell 使用 REST Web 服务是多么容易。

Invoke-RestMethod 始终是更聪明的选择。有时示例使用 Invoke-WebRequest 代替。对于后者,您需要从接收到的值中手动提取信息并将其转换为正确的格式。这就是 Invoke-RestMethod 自动做的:

1
2
PS> (Invoke-WebRequest -Uri http://numbersapi.com/37 -UseBasicParsing).Content
37 is the cost in cents of the Whopper Sandwich when Burger King first introduced it in 1957.

PowerShell 技能连载 - 拆分而不丢失字符

拆分文本时,通常会丢失拆分字符。这就是为什么这个例子中的反斜杠丢失的原因:

1
2
3
4
PS> 'c:\test\file.txt' -split '\\'
c:
test
file.txt

重要提示:请注意 -split 运算符需要一个正则表达式。如果你想在反斜杠处拆分,因为反斜杠是正则表达式中的一个特殊字符,你需要对它进行转义。以下调用告诉您需要转义的内容:提交要使用的文字文本。结果是转义的正则表达式文本:

1
2
PS> [regex]::Escape('\')
\\

如果你想拆分而不丢失任何字符,你可以使用所谓的先行断言和后行断言。以下代码在一个反斜杠分割(不删除它):

1
2
3
4
PS> 'c:\test\file.txt' -split '(?<=\\)'
c:\
test\
file.txt

以下代码在每个反斜杠之前拆分:

1
2
3
4
PS> 'c:\test\file.txt' -split '(?=\\)'
c:
\test
\file.txt

PowerShell 技能连载 - 排序技巧(第 4 部分)

在上一个技能中,我们展示了 Sort-Object 通过属性名称、哈希表或普通脚本块来排序,并且我们使用脚本块来控制排序算法,并按日期和时间而不是字母数字对字符串信息进行排序。

在这最后一个示例中,让我们使用它来对 IPv4 地址进行排序。默认情况下,Sort-Object 将它们视为纯文本并使用字母排序:

1
2
3
4
PS> '10.12.11.1', '298.12.11.112', '8.8.8.8' | Sort-Object
10.12.11.1
298.12.11.112
8.8.8.8

要正确排序 IPv4 地址,您可以将它们转换为 [version] 类型,该类型也包含四个数字:

1
2
3
4
5
PS> '10.12.11.1', '298.12.11.112', '8.8.8.8' | Sort-Object -Property { $_ -as [version] }

8.8.8.8
10.12.11.1
298.12.11.112

PowerShell 技能连载 - 排序技巧(第 3 部分)

在上一个技能中,我们展示了 Sort-Object 接受属性名称、哈希表或普通脚本块来对事物进行排序。让我们看看为什么将脚本块提交给 Sort-Object 是个好主意。

假设您有一堆表示日期的字符串数据,并且您想对它们进行排序:

1
2
3
4
5
PS> 'May 12, 2020', 'Feb 1, 1999', 'June 12, 2021' | Sort-Object

Feb 1, 1999
June 12, 2021
May 12, 2020

结果已排序,但不按日期排序。由于输入是字符串,Sort-Object 使用字母数字排序算法。您现在可以将原始数据转换为另一种格式并对其进行排序。

但是,您也可以要求 Sort-Object 进行转换。不同之处在于原始数据格式保持不变:一系列字符串将按日期排序,但仍然是字符串:

1
2
3
4
5
6
PS> 'May 12, 2020', 'Feb 1, 1999', 'June 12, 2021' |
Sort-Object -Property { [DateTime]$_ }

Feb 1, 1999
May 12, 2020
June 12, 2021

当然,您的工作是想出一个脚本块,将 $_ 中传入的原始数据正确转换为您想要用于排序的所需类型。对于日期,您可能还想查看使用本地日期和时间格式的 -as 运算符,而直接转换始终使用美国格式:

1
2
3
4
5
PS> 'May 12, 2020', 'Feb 1, 1999', 'June 12, 2021' | Sort-Object -Property { $_ -as [DateTime] }

Feb 1, 1999
May 12, 2020
June 12, 2021

PowerShell 技能连载 - 排序技巧(第 2 部分)

在上一个技能中,我们展示了 Sort-Object 如何对多个属性进行排序,以及如何使用哈希表分别控制每个属性的排序方向。不过,哈希表还可以做更多的事情。

例如,哈希表键 “Expression“ 可以是一个脚本块,然后针对您要排序的每个项目执行该脚本块。脚本块的结果决定了排序顺序。

这就是为什么这行代码每次都会以不同的方式重新排列数字列表:

1
1..10 | Sort-Object -Property @{Expression={ Get-Random }}

本质上,本示例使用 Get-Random 的随机结果对数字列表进行随机排序。这可能很有用,即当您使用密码生成器并希望随机分配脚本计算的字符时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# compose password out of these
$Capitals = 2
$Numbers = 1
$lowerCase = 3
$Special = 1

# collect random chars from different lists in $chars
$chars = & {
'ABCDEFGHKLMNPRSTUVWXYZ'.ToCharArray() | Get-Random -Count $Capitals
'23456789'.ToCharArray() | Get-Random -Count $Numbers
'abcdefghkmnprstuvwxyz'.ToCharArray() | Get-Random -Count $lowerCase
'!§$%&?=#*+-'.ToCharArray() | Get-Random -Count $Special
} | # <- don't forget pipeline symbol!
# sort them randomly
Sort-Object -Property { Get-Random }

# convert chars to one string
$password = -join $chars
$password

正如您在实际示例中看到的,Sort-Object 还接受一个简单的脚本块,它表示哈希表的 “Expression“ 键。两行的工作方式相同(但当然会产生不同的随机结果):

1
1..10 | Sort-Object -Property @{Expression={ Get-Random }}1..10 | Sort-Object -Property { Get-Random }