PowerShell 技能连载 - 启用 Active Directory cmdlet

在服务器和客户端上,Windows 都附带了 “ActiveDirectory” PowerShell 模块。它添加了许多 cmdlet 来管理 Active Directory 中的用户和资源。

默认情况下,该模块是隐藏的。要在客户端上启用它,请以管理员权限运行:

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

在服务器上,再次使用管理员权限并运行:

1
2
Install-WindowsFeature RSAT-AD-PowerShell
Add-WindowsFeature RSAT-AD-PowerShell

PowerShell 技能连载 - 四个 PowerShell 关键先决条件

如果您要切换到新计算机,您可能需要快速检查一下 PowerShell 是否设置正确。以下是您绝对应该检查的四件事:

1 检查 PowerShell 版本

运行 $PSVersionTable 以检查您的 PowerShell 版本。

1
2
3
4
5
6
7
8
9
10
11
12
PS> $PSVersionTable

Name Value
---- -----
PSVersion 5.1.19041.1237
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1237
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

由于 $PSVersionTable 是一个哈希表,您还可以将其转换为对象以选择某些属性:

1
2
3
4
5
PS> [PSCustomObject]$PSVersionTable | Select-Object -Property PSVersion, PSEdition

PSVersion PSEdition
--------- ---------
5.1.19041.1237 Desktop

如果 “PSEdition“ 是 “Desktop“,则您使用的是内置的 Windows PowerShell。应该是 5.1 版。任何旧版本均已弃用,使用旧版本可能会引发安全风险。由于 Windows PowerShell 功能齐全,因此没有超过 5.1 的新版本。

如果 “PSEdition“ 是 “Core“,那么您使用的是新的跨平台 PowerShell。当前版本为 7.1.5,更新频繁。

2 检查运行策略

如果你不能运行脚本,PowerShell 就没有意义了。执行策略应设置为 “RemoteSigned“(仅允许本地脚本)或 “Bypass“(位于任何地方的脚本都可以运行,包括下载的脚本):

1
2
PS> Get-ExecutionPolicy
Bypass

如果需要,使用以下代码来更改执行策略:

1
PS> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force

3 检查 PowerShellGet

PowerShellGet 是一个重要的附加组件,因为它代表了 PowerShell 包管理。使用 PowerShellGet,您可以通过 Install-Module 安装其他模块。如果此模块已过时,您可能无法再下载和安装其他模块:

1
2
3
4
5
PS> Get-Module -Name PowerShellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1 -Property Version

Version
-------
2.2.5

如果报告的版本低于 2.2.0,则需要更新此模块。如果您看到版本 1.0.0 或 1.0.1(最初随 Windows 一起提供并且此后从未更新过的初始模块),则尤其如此。

要更新该模块,您需要重新安装它及其必备的 PackageManagement 模块:

1
2
Install-Module -Name PowerShellGet -Scope CurrentUser -Force -AllowClobber
Install-Module -Name Packagemanagement -Scope CurrentUser -Force -AllowClobber

TLS 1.2 支持

最后要检查的是 Windows 是否设置为支持传输层协议 1.2:

1
2
PS> ([System.Net.ServicePointManager]::SecurityProtocol -band 'Tls12') -eq 'Tls12'
True

If this is $false, then your Windows still uses outdated settings, and PowerShell may not be able to connect to HTTPS: webservices and sites. You should update Windows. Meanwhile, you can manually enable TLS 1.2 on a per-application setting:
如果返回 $false,那么您的 Windows 仍然使用过时的设置,并且 PowerShell 可能无法连接到 HTTPS:网络服务和网站。您应该更新 Windows。同时,您可以在每个应用程序独立的设置上手动启用 TLS 1.2:

1
2
3
[System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.ServicePointManager]::SecurityProtocol -bor
[System.Net.SecurityProtocolType]::Tls12

PowerShell 技能连载 - 改进 PowerShell ISE 的帮助

仍有许多专业的脚本编写者使用内置 PowerShell ISE 编辑器,它仍然是一个快速可靠的脚本开发环境。如果您使用 PowerShell ISE,可能希望将它内置的帮助系统切换为在线帮助。请运行这段代码(在 PowerShell ISE 中):

1
PS> $psise.Options.UseLocalHelp = $false

运行此代码后,只要您在脚本窗格或控制台部分中单击命令,然后按 F1,PowerShell ISE 将对命令运行 Get-Help 并添加 -Online 开关参数,因此浏览器打开并显示复杂的、排版好的最新在线帮助。

尽管如此,您可能希望记住上面的命令:如果命令没有在线帮助,则可能仍有本地帮助文件。将 PowerShell ISE 选项恢复为 $true 将打开本地帮助。

PowerShell 技能连载 - 打开 Windows 设置对话框(快速)(第 2 部分)

上一个技能中,我们介绍了 Start-Process 支持的命令 “ms-settings:“,可用于打开各种 Windows 设置对话框。例如,要打开个人注册信息页面,请执行以下操作:

1
PS> Start-Process ms-settings:yourinfo

每当您需要经常打开特定对话框时,例如检查更新,那么现在可以直接做到:

1
PS> Start-Process ms-settings:windowsupdate-action

但是,您需要记住相当隐蔽的命令。您无法定义新的命令别名,因为这些代码不是命令,而是命令加参数。

但是,您可以为此做些什么,也就是创建简单的函数。当您需要方便地记忆命令参数时,这一直是一种好方法:

1
function update { Start-Process ms-settings:windowsupdate-action }

运行此代码后,您现在可以使用新的 “update“ 命令快速检查 Windows 更新。如果要保留这些功能,请将它们导出为一个 module,或将功能代码放入其中一个配置文件(自动启动)脚本中。 可以在 $profile 中找到默认配置文件脚本的路径。如果尚不存在,您可能必须创建文件。如果还没有允许脚本执行,请先启用它。

PowerShell 技能连载 - 打开 Windows 设置对话框(快速)(第 1 部分)

大多数对话框和 Windows 中的设置可以通过内部命令直接打开。Windows 10 的设置对话框可以用如下命令打开:

1
PS> Start-Process ms-settings:

要打开特定的设置页面,请添加其名称。例如,要快速打开“镜像显示”设置页面,请尝试如下代码:

1
PS> Start-Process ms-settings:quietmomentspresentation

以下是 Paolo Maffezzoli 整理的支持命令列表(谢谢):

Page Command (URI)
**Settings home page**
Settings home page ms-settings:
**System**
Display ms-settings:display
Night light settings ms-settings:nightlight
Advanced scaling settings ms-settings:display-advanced
Connect to a wireless display ms-settings-connectabledevices:devicediscovery
Graphics settings ms-settings:display-advancedgraphics
Display orientation ms-settings:screenrotation
Sound (build 17063+) ms-settings:sound
Manage sound devices ms-settings:sound-devices
App volume and device preferences ms-settings:apps-volume
Notifications & actions ms-settings:notifications
Focus assist (build 17074+) ms-settings:quiethours, OR ms-settings:quietmomentshome
During these hours ms-settings:quietmomentsscheduled
Duplicating my display (When I'm duplicating my display) ms-settings:quietmomentspresentation
Playing a game full screen (When I'm playing a game) ms-settings:quietmomentsgame
Power & sleep ms-settings:powersleep
Battery ms-settings:batterysaver
See which apps are affecting your battery life ms-settings:batterysaver-usagedetails
Battery Saver settings ms-settings:batterysaver-settings
Storage ms-settings:storagesense
Configure Storage Sense or run it now ms-settings:storagepolicies
Change where new content is saved ms-settings:savelocations
Tablet mode ms-settings:tabletmode
Multitasking ms-settings:multitasking
Projecting to this PC ms-settings:project
Shared experiences ms-settings:crossdevice
Clipboard ms-settings:clipboard
Remote Desktop ms-settings:remotedesktop
Device Encryption (where available) ms-settings:deviceencryption
About ms-settings:about
**Devices**
Bluetooth & other devices ms-settings:bluetooth, OR ms-settings:connecteddevices
Printers & scanners ms-settings:printers
Mouse ms-settings:mousetouchpad
Touchpad ms-settings:devices-touchpad
Typing ms-settings:typing
Hardware keyboard - Text suggestions ms-settings:devicestyping-hwkbtextsuggestions
Wheel (where available) ms-settings:wheel
Pen & Windows Ink ms-settings:pen
AutoPlay ms-settings:autoplay
USB ms-settings:usb
**Phone**
Phone ms-settings:mobile-devices
Add a phone ms-settings:mobile-devices-addphone
Your Phone (opens app) ms-settings:mobile-devices-addphone-direct
**Network & Internet**
Network & Internet ms-settings:network
Status ms-settings:network-status
Show available networks ms-availablenetworks:
Cellular & SIM ms-settings:network-cellular
Wi-Fi ms-settings:network-wifi
Show available networks ms-availablenetworks:
Manage known networks ms-settings:network-wifisettings
Wi-Fi Calling ms-settings:network-wificalling
Ethernet ms-settings:network-ethernet
Dial-up ms-settings:network-dialup
DirectAccess (where available) ms-settings:network-directaccess
VPN ms-settings:network-vpn
Airplane mode ms-settings:network-airplanemode, OR ms-settings:proximity
Mobile hotspot ms-settings:network-mobilehotspot
NFC ms-settings:nfctransactions
Data usage ms-settings:datausage
Proxy ms-settings:network-proxy
**Personalization**
Personalization ms-settings:personalization
Background ms-settings:personalization-background
Colors ms-settings:personalization-colors, OR ms-settings:colors
Lock screen ms-settings:lockscreen
Themes ms-settings:themes
Fonts (build 17083+) ms-settings:fonts
Start ms-settings:personalization-start
Choose which folders appear on Start ms-settings:personalization-start-places
Taskbar ms-settings:taskbar
**Apps**
Apps & features ms-settings:appsfeatures OR ms-settings:appsfeatures-app
Manage optional features ms-settings:optionalfeatures
Default apps ms-settings:defaultapps
Offline maps ms-settings:maps
Download maps ms-settings:maps-downloadmaps
Apps for websites ms-settings:appsforwebsites
Video playback (build 16215+) ms-settings:videoplayback
Startup (build 17017+) ms-settings:startupapps
**Accounts**
Your info ms-settings:yourinfo
Email & accounts ms-settings:emailandaccounts
Sign-in options ms-settings:signinoptions
Windows Hello face setup ms-settings:signinoptions-launchfaceenrollment
Windows Hello fingerprint setup ms-settings:signinoptions-launchfingerprintenrollment
Security Key setup ms-settings:signinoptions-launchsecuritykeyenrollment
Dynamic Lock ms-settings:signinoptions-dynamiclock
Access work or school ms-settings:workplace
Family & other people ms-settings:otherusers OR ms-settings:family-group
Set up a kiosk ms-settings:assignedaccess
Sync your settings ms-settings:sync
**Time & language**
Date & time ms-settings:dateandtime
Region ms-settings:regionformatting
Japan IME settings (where available) ms-settings:regionlanguage-jpnime
Pinyin IME settings (where available) ms-settings:regionlanguage-chsime-pinyin
Wubi IME settings (where available) ms-settings:regionlanguage-chsime-wubi
Korea IME settings (where available) ms-settings:regionlanguage-korime
Language ms-settings:regionlanguage OR ms-settings:regionlanguage-languageoptions
Windows Display language ms-settings:regionlanguage-setdisplaylanguage
Add Display language ms-settings:regionlanguage-adddisplaylanguage
Keyboard (removed in build 17083+) ms-settings:keyboard
Speech ms-settings:speech
**Gaming**
Game bar ms-settings:gaming-gamebar
Captures ms-settings:gaming-gamedvr
Broadcasting ms-settings:gaming-broadcasting
Game Mode ms-settings:gaming-gamemode
TruePlay (removed in version 1809+) ms-settings:gaming-trueplay
Xbox Networking (build 16226+) ms-settings:gaming-xboxnetworking
**Extras**
Extras (available when Settings app extensions installed) ms-settings:extras
**Ease of Access**
Display (build 17025+) ms-settings:easeofaccess-display
Mouse Pointer (Cursor & pointer, build 17040+) ms-settings:easeofaccess-cursorandpointersize OR ms-settings:easeofaccess-MousePointer
Text Cursor ms-settings:easeofaccess-cursor
Magnifier ms-settings:easeofaccess-magnifier
Color Filters (build 17025+) ms-settings:easeofaccess-colorfilter
Adaptive Color Filters Link ms-settings:easeofaccess-colorfilter-adaptivecolorlink
Night Light Link ms-settings:easeofaccess-colorfilter-bluelightlink
High Contrast ms-settings:easeofaccess-highcontrast
Narrator ms-settings:easeofaccess-narrator
Start Narratorafter sign-in for me ms-settings:easeofaccess-narrator-isautostartenabled
Audio (build 17035+) ms-settings:easeofaccess-audio
Closed captions ms-settings:easeofaccess-closedcaptioning
Speech (build 17035+) ms-settings:easeofaccess-speechrecognition
Keyboard ms-settings:easeofaccess-keyboard
Mouse ms-settings:easeofaccess-mouse
Eye Control (build 17035+) ms-settings:easeofaccess-eyecontrol
Other options (removed in version 1809+) ms-settings:easeofaccess-otheroptions
**Search (version 1903+)**
Permissions & history ms-settings:search-permissions
Searching Windows ms-settings:cortana-windowssearch
More details ms-settings:search-moredetails
**Cortana (build 16188+)**
Cortana ms-settings:cortana
Talk to Cortana ms-settings:cortana-talktocortana
Permissions ms-settings:cortana-permissions
More details ms-settings:cortana-moredetails
**Privacy**
General ms-settings:privacy
Speech ms-settings:privacy-speech
Inking & typing personalization ms-settings:privacy-speechtyping
Diagnostics & feedback ms-settings:privacy-feedback
View Diagnostic Data ms-settings:privacy-feedback-telemetryviewergroup
Activity history (build 17040+) ms-settings:privacy-activityhistory
Location ms-settings:privacy-location
Camera ms-settings:privacy-webcam
Microphone ms-settings:privacy-microphone
Voice activation ms-settings:privacy-voiceactivation
Notifications ms-settings:privacy-notifications
Account info ms-settings:privacy-accountinfo
Contacts ms-settings:privacy-contacts
Calendar ms-settings:privacy-calendar
Phone calls (removed in version 1809+) ms-settings:privacy-phonecalls
Call history ms-settings:privacy-callhistory
Email ms-settings:privacy-email
Eye tracker (requires eyetracker hardware) ms-settings:privacy-eyetracker
Tasks ms-settings:privacy-tasks
Messaging ms-settings:privacy-messaging
Radios ms-settings:privacy-radios
Other devices ms-settings:privacy-customdevices
Background apps ms-settings:privacy-backgroundapps
App diagnostics ms-settings:privacy-appdiagnostics
Automatic file downloads ms-settings:privacy-automaticfiledownloads
Documents ms-settings:privacy-documents
Pictures ms-settings:privacy-pictures
Videos ms-settings:privacy-documents
File system ms-settings:privacy-broadfilesystemaccess
**Update & security**
Windows Update ms-settings:windowsupdate
Check for updates ms-settings:windowsupdate-action
View update history ms-settings:windowsupdate-history
Restart options ms-settings:windowsupdate-restartoptions
Advanced options ms-settings:windowsupdate-options
Change active hours ms-settings:windowsupdate-activehours
Optional updates ms-settings:windowsupdate-optionalupdates OR ms-settings:windowsupdate-seekerondemand
Delivery Optimization ms-settings:delivery-optimization
Windows Security / Windows Defender ms-settings:windowsdefender
Open Windows Security windowsdefender:
Backup ms-settings:backup
Troubleshoot ms-settings:troubleshoot
Recovery ms-settings:recovery
Activation ms-settings:activation
Find My Device ms-settings:findmydevice
For developers ms-settings:developers
Windows Insider Program ms-settings:windowsinsider, OR ms-settings:windowsinsider-optin
**Mixed reality**
Mixed reality ms-settings:holographic
Audio and speech ms-settings:holographic-audio
Environment ms-settings:privacy-holographic-environment
Headset display ms-settings:holographic-headset
Uninstall ms-settings:holographic-management
**Surface Hub**
Accounts ms-settings:surfacehub-accounts
Team Conferencing ms-settings:surfacehub-calling
Team device management ms-settings:surfacehub-devicemanagenent
Session cleanup ms-settings:surfacehub-sessioncleanup
Welcome screen ms-settings:surfacehub-welcome

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

在上一个部分中,我们说明了如何使用脚本块对排序进行更多的控制。例如,您可以使用 “-as“ 运算符来转换数据以控制排序算法。

这样,您可以“修正”传入数据的数据类型。例如将某些或所有数字数据转为字符串类型,再传给 Sort-Object。看看第一个例子的结果,以及下方的修正结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS> 1,2,"13",4,11,3,"2" | Sort-Object
1
13
2
3
4
11
2

PS> 1,2,"13",4,11,3,"2" | Sort-Object -Property { $_ -as [double] }
1
2
2
3
4
11
13

同样,您可以完全随机化列表,快速地创建简单的随机密码:

1
2
3
4
5
PS> -join ('abcdefghkmnrstuvwxyz23456789*+#'.ToCharArray() | Get-Random -count 5 | Sort-Object -Property { Get-Random } )
m2v6u

PS> -join ('abcdefghkmnrstuvwxyz23456789*+#'.ToCharArray() | Get-Random -count 5 | Sort-Object -Property { Get-Random } )
b+g7t

或者,您可以根据计算值进行排序。下面的示例按文件年龄排序,通过从创建时间中减去上次写入时间计算得出:

1
2
3
Get-ChildItem -Path c:\windows -Filter *.log -Depth 1 -ErrorAction Ignore |
Sort-Object -Property { $_.LastWriteTime - $_.CreationTime } |
Select-Object -Property Name, LastWriteTime, CreationTime, @{Name='Age (Days)';Expression={ [int]($_.LastWriteTime - $_.CreationTime).TotalDays }}

结果看起来类似这样:

Name                                 LastWriteTime       CreationTime        Age (Days)
----                                 -------------       ------------        ----------
setupapi.upgrade.log                 28.09.2020 15:04:56 28.09.2020 15:40:12          0
setuperr.log                         11.07.2021 14:37:51 11.07.2021 14:37:51          0
setupact.log                         16.10.2021 12:59:17 16.10.2021 12:59:17          0
setupapi.setup.log                   28.09.2020 17:48:22 28.09.2020 17:47:36          0
setupapi.offline.20191207_091437.log 07.12.2019 10:14:37 07.12.2019 10:13:02          0
setupapi.offline.log                 28.09.2020 15:40:12 28.09.2020 15:09:47          0
setupapi.dev.20201120_180252.log     20.11.2020 18:02:52 28.09.2020 17:51:43         53
setupapi.dev.20210514_095516.log     14.05.2021 09:55:16 27.02.2021 04:17:58         76
setupapi.dev.20210226_041725.log     26.02.2021 04:17:25 22.11.2020 04:18:58         96
lvcoinst.log                         23.10.2021 15:30:45 19.07.2021 08:46:48         96
PFRO.log                             25.10.2021 13:54:27 11.07.2021 14:41:28        106
WindowsUpdate.log                    26.10.2021 10:47:38 10.07.2021 15:05:05        108
setupapi.dev.20210710_201855.log     10.07.2021 20:18:55 27.02.2021 04:17:58        134
setupapi.dev.20210915_082529.log     15.09.2021 08:25:29 27.02.2021 04:17:58        200
NetSetup.LOG                         17.04.2020 15:19:26 26.08.2019 17:23:11        235
setupapi.dev.log                     26.10.2021 06:27:25 27.02.2021 04:17:58        241
mrt.log                              13.10.2021 08:30:39 12.11.2020 07:16:17        335
PASSWD.LOG                           25.10.2021 13:54:28 28.09.2020 17:47:22        392
ReportingEvents.log                  26.10.2021 09:37:23 03.09.2019 10:42:58        784
Gms.log                              25.10.2021 13:54:32 26.08.2019 17:27:50        791

请注意如何以非常相似的方式将哈希表与 Select-Object 一起使用。在示例中,通过将哈希表提交给 Select-Object,将“Age (Days)”属性添加到输出中。在内部,哈希表定义了新属性的名称并提供了一个脚本块来计算属性值。此脚本块的工作原理与此处讨论的脚本块基本相同:$_ 表示整个对象,您可以使用任何 PowerShell 表达式来转换或计算该值。

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

在上一个提示中,您已经看到 Sort-Object 如何接受哈希表作为参数,对排序进行高级控制。 例如,此行代码按状态排序,然后显示名称,并为每个属性使用单独的排序方向:

1
2
3
Get-Service |
Sort-Object -Property @{Expression='Status'; Descending=$true}, @{Expression='DisplayName'; Descending=$false } |
Select-Object -Property DisplayName, Status

但是,当您查看结果时,”Status” 属性的排序方向似乎是错的。我们已经澄清了这一点,因为 “Status” 实质上是一个数字常量,而 Sort-Object 排序的底层逻辑是对原始数据进行排序。所以它是根据内部的数值型常量对 “Status” 进行排序,而不是根据可见的友好名称。

要确保 Sort-Object 是按照用户“看见”对象的内容对它们排序,请使用哈希表的另一个功能:”Expression” 键不仅能接受属性的名称,而且用支持脚本块(代码)转换为任何数据,再对该数据排序。在脚本块内,$_ 表示完整的传入对象。

要确保 “Status” 根据文本来排序而不是根据背后的数值来排序,请将其转换为字符串,如下所示:

1
2
3
Get-Service |
Sort-Object -Property @{Expression={[string]$_.Status}; Descending=$true}, @{Expression='DisplayName'; Descending=$false } |
Select-Object -Property DisplayName, Status

事实上,在排序之前改变数据的能力,能改变所有排序的游戏规则。

假设您有一个 HTTPS 连接列表,用于保存浏览器连接到的远程 IP 地址,并且您正在尝试通过 Sort-Object 来对这些 IP 地址进行排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS C:\> Get-NetTCPConnection -RemotePort 443 | Select-Object -Property RemoteAddress, RemotePort, State, OwningProcess | Sort-Object -Property RemoteAddress

RemoteAddress RemotePort State OwningProcess
------------- ---------- ----- -------------
142.250.185.74 443 TimeWait 0
142.250.186.46 443 TimeWait 0
20.199.120.182 443 Established 3552
20.199.120.182 443 Established 5564
20.42.65.89 443 Established 9836
20.42.65.89 443 TimeWait 0
20.42.73.24 443 TimeWait 0
35.186.224.25 443 TimeWait 0
45.60.13.212 443 Established 7644
51.104.30.131 443 Established 10220

如果您将仔细查看结果,您将看到 “RemoteAddress” 未正确排序:例如 “20.199.120.182” 列在了 “20.42.65.89” 的前面。

这是因为这些 IPv4 地址被视为字符串,因此 Sort-Object 使用默认的字母数字排序算法。

您现在知道如何以更合适的数据类型转换数据。例如,IPv4 地址可以被视为软件版本(数据类型[版本])正确排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
PS> Get-NetTCPConnection -RemotePort 443 | Select-Object -Property RemoteAddress, RemotePort, State, OwningProcess | Sort-Object -Property @{Expression={ $_.RemoteAddress -as [version] }}

RemoteAddress RemotePort State OwningProcess
------------- ---------- ----- -------------
20.42.65.89 443 Established 9836
20.42.65.89 443 TimeWait 0
20.199.120.182 443 Established 3552
20.199.120.182 443 Established 5564
35.186.224.25 443 TimeWait 0
45.60.13.212 443 Established 7644
51.104.30.131 443 Established 10220
142.250.185.74 443 TimeWait 0
142.250.186.46 443 TimeWait 0

现在 IP 地址已可以正确排序。

注意:当将数据转换为其他数据类型(如此处所示)时,始终优先使用 -as 运算符进行直接类型转换。如果数据不能转换为所需的数据类型,则 -as 运算符只会返回 $null,而直接类型转换将会产生异常。

在前面的例子中,如果 “RemoteAddress” 会显示一个 IPv6 地址(不能转换为 [version]),幸亏 -as 操作符,这些项目不会被排序,而会放在排序数据的开头.

要缩短代码,您可以简写哈希表的键(只要它们保持唯一):

1
2
3
Get-NetTCPConnection -RemotePort 443 |
Select-Object -Property RemoteAddress, RemotePort, State, OwningProcess |
Sort-Object -Property @{E={ $_.RemoteAddress -as [version] }}

如果您需要的只是数据转换,则可以完全跳过哈希表并将脚本块直接传给 -Property 参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
PS> Get-NetTCPConnection -RemotePort 443 | Select-Object -Property RemoteAddress, RemotePort, State, OwningProcess | Sort-Object -Property { $_.RemoteAddress -as [version] }

RemoteAddress RemotePort State OwningProcess
------------- ---------- ----- -------------
20.42.65.89 443 Established 9836
20.42.65.89 443 TimeWait 0
20.199.120.182 443 Established 3552
20.199.120.182 443 Established 5564
35.186.224.25 443 TimeWait 0
45.60.13.212 443 Established 7644
51.104.30.131 443 Established 10220
142.250.185.74 443 TimeWait 0
142.250.186.46 443 TimeWait 0

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

Sort-Object 支持高级排序,并在您传入哈希表时提供更多控制。例如,哈希表可以单独控制多个属性的排序方向。

例如,此行代码按状态对服务进行排序,然后按名称排序。排序方向可以通过 -Descending 开关参数控制,但始终适用于所有选定的属性:

1
2
3
Get-Service | Sort-Object -Property Status, DisplayName | Select-Object -Property DisplayName, Status

Get-Service | Sort-Object -Property Status, DisplayName -Descending | Select-Object -Property DisplayName, Status

要单独控制排序方向,请传入哈希表并使用 ExpressionDescending 键。这首先按状态(降序)对服务进行排序,然后按显示名称(升序):

1
2
3
Get-Service |
Sort-Object -Property @{Expression='Status'; Descending=$true}, @{Expression='DisplayName'; Descending=$false } |
Select-Object -Property DisplayName, Status

注意:当您查看结果时,您可能会对“状态”属性的内容排序方式感到恼火。尽管代码要求降序排序,但您首先会看到正在运行的服务,然后是停止的服务。

这个问题的简单答案是:您现在知道如何单独控制排序,因此如果排序顺序错误,只需尝试颠倒排序顺序,看看是否适合您。

深入的答案是:”Status“ 属性实际上是一个数字常量,而 Sort-Object 始终对底层数据进行排序。因此,当您使数字常量可见时,会发现排序顺序是正确的:

1
2
3
Get-Service |
Sort-Object -Property @{Expression='Status'; Descending=$true}, @{Expression='DisplayName'; Descending=$false } |
Select-Object -Property DisplayName, { [int]$_.Status }

正如您现在所看到的,”Running“ 实际上是常量 “4”,而 “Stopped” 由常量 1 表示。

不要错过我们的下一个技能,以获得更多控制(以及对由底层数字常量引起的问题的优雅修复)。

PowerShell 技能连载 - 高级排序(第 1 部分)

Sort-Object easily sorts results for you. For primitive data such as numbers or strings, simply add Sort-Object to your pipeline. This gets you a sorted list of lottery numbers:
Sort-Object 能轻松对结果排序。对于数字或字符串等原始数据,只需将 Sort-Object 添加到您的管道中。这将为您提供一个排序的彩票号码列表:

1
2
3
4
$lottery = 1..49 | Get-Random -Count 7 | Sort-Object
# set the string you want to use to separate numbers in your output
$ofs = ','
"Your numbers are $lottery"

具有多个属性的对象数据要求您定义要排序的属性。此行代码按状态对服务进行排序:

1
Get-Service | Sort-Object -Property Status

Sort-Object 甚至支持多种排序。此行代码按状态对服务进行排序,然后按服务名称排序:

1
Get-Service | Sort-Object -Property Status, DisplayName | Select-Object -Property DisplayName, Status

要反转排序顺序,请添加 -Descending 开关参数。

有关排序的更多控制,例如,对一个属性升序排序和另一个属性降序排序,请参阅我们的下一个提示。

PowerShell 技能连载 - 速度很重要

PowerShell 是一种通用自动化语言,因此它的目标是多功能且易于使用。速度不是首要任务。

如果您确实关心最大速度,那么有一些 cmdlet 几乎可以完全满足 .NET 调用的功能。在这些实例中使用直接 .NET 调用会更快,尤其是在经常调用这些 cmdlet 时(例如在循环中)。但另一方面是它使您的代码更难阅读。

这里有一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# cmdlet
PS> Join-Path -Path $env:temp -ChildPath test.txt
C:\Users\tobia\AppData\Local\Temp\test.txt

# direct .NET
PS> [System.IO.Path]::Combine($env:temp, 'test.txt')
C:\Users\tobia\AppData\Local\Temp\test.txt


# cmdlet
PS> Get-Date

Monday, October 4, 2021 12:34:46

# direct .NET
PS> [DateTime]::Now

Monday, October 4, 2021 12:34:52