PowerShell 技能连载 - Office365邮箱恢复删除(第 1 部分)

如果您已删除 Office365 用户帐户,但后来意识到仍需要其邮箱中的数据,则可能可以恢复该邮箱。

首先,请检查邮箱是否已“软删除”。下一个命令列出了所有可恢复的邮箱:

1
Get-Mailbox -SoftDeletedMailbox | Select UserPrincipalName, WhenSoftDeleted

每个邮箱都与用户主体名称相关联。要取消删除邮箱,您需要临时重新创建此帐户。接下来,您可以撤消邮件箱的删除操作。只需在以下命令中替换主体名称即可:

1
Undo-SoftDeletedMailbox -SoftDeletedObject username@company.onmicrosoft.com

PowerShell 技能连载 - 重命名属性(简单方法)

Select-Object 不仅可以选择属性,还可以重命名。假设您需要获取一个文件夹中的文件列表,并包含文件大小信息,这行代码就足够了:

1
2
PS> Get-ChildItem -Path c:\windows -File | Select-Object -Property Length, FullName
}

现在你只能看到两个选定的属性“Length”和“FullName”。但是如果您希望此信息以不同的名称显示,例如“Size”和“Path”,该怎么办?

只需通过提交每个属性的哈希表来重命名属性。在每个哈希表内,使用“Name”键来重命名属性,“Expression = '[OriginalPropertyName]' }”键保持原始属性内容不变:

1
Get-ChildItem -Path c:\windows -File | Select-Object -Property @{Name='Size';Expression='Length'}, @{Name='Path';Expression='FullName'}

这样,您可以轻松地重命名任何对象中的任何属性。

PowerShell 技能连载 - 常见陷阱和奇怪结果:比较运算符

你能发现下面代码中的错误吗?

1
2
3
4
5
6
7
8
9
10
$result = 'NO'

if ($result = 'YES')
{
'Result: YES'
}
else
{
'Result: NO'
}

无论 $result 包含“NO”还是“YES”,它总是返回“Result: YES”。

从其他脚本或编程语言转换到 PowerShell 的人经常遇到这个错误:在 PowerShell 中,“=”是一个独占赋值运算符,而对于比较,您需要使用“-eq”。因此,正确的代码(和简单的修复)应该是这样的:

1
2
3
4
5
6
7
8
9
10
$result = 'NO'

if ($result -eq 'YES')
{
'Result: YES'
}
else
{
'Result: NO'
}

让我们看一下为什么最初的代码总是返回“Result: YES”。

当您意外使用赋值运算符而不是比较运算符时,您将不会得到任何结果,因此这个 NULL 值应该真正评估为 $false,并且条件应该始终返回“Result: NO”。然而,情况恰恰相反。

这是由于另一个PowerShell鲜为人知的怪异之处:当您分配一个值并将分配放在大括号中时,分配也将被返回。最初错误的代码将使用实际响应于赋值值的条件。

每当您向$result(所有都被解释为FALSE)分配0、’’、$false 或 $null 时,代码都会返回“Result: NO”。任何其他赋值都会返回“Result: YES”。

所有这些令人困惑的行为只是因为用户肌肉记忆使用了操作符“=”而实际上需要“-eq”操作符。

PowerShell 技能连载 - PowerShell 废弃功能(第 2 部分:Exchange Online 中的远程 PowerShell (RPS))

Exchange Online 中的 PowerShell cmdlet 使用“远程 PowerShell”作为远程技术,这是一种在今天世界中存在安全风险的传统技术。这就是为什么 Exchange 团队最初考虑在2023年6月停用 Remote PowerShell。

由于相当多的用户似乎无法切换到新的、更安全的基于 REST 的 v3 PowerShell 模块来管理 Exchange,团队决定添加一种方法让客户重新启用 Remote PowerShell 以延长宽限期(至少适用于 Microsoft 云租户)。

简而言之:如果您仍在使用 Exchange Online 中的 Remote PowerShell,则需要开始计划过渡到基于 REST 的 v3 PowerShell 模块。

PowerShell 技能连载 - PowerShell 废弃功能 (第 1 部分:PowerShell 2.0)

Windows PowerShell 2.0 仍然是任何 Windows PowerShell 的一部分,用于向后兼容。当启用时,它是一个严重的安全风险 - PowerShell 2.0 简单地没有 PowerShell 5 及更高版本中发现的所有先进恶意软件检测工具。

如果您拥有管理员权限,则此行将告诉您系统上是否启用了 PowerShell 2.0:

1
PS> Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2

如果它已启用,请确保将其禁用。

PowerShell 技能连载 - 更丰富的打印机信息

Get-Printer 返回所有本地打印机的基本信息。当您添加开关参数 -Full 时,它会返回更详细的信息,例如打印机权限,但乍一看,无论是否指定了 -FullGet-Printer 似乎输出相同的信息。

要查看增强信息,必须要求 PowerShell 显示所有属性,因为默认情况下所有增强属性都是隐藏的。以下代码揭示了通过指定 -Full 所做出的差异:

1
2
Get-Printer | Select-Object -Property * | Out-GridView -Title 'Without -Full'
Get-Printer -Full | Select-Object -Property * | Out-GridView -Title 'With -Full'

最显著的区别在于 PermissionSDDL 属性。

PowerShell 技能连载 - 使用 PowerShell 解决问题(第 4 部分)

PowerShell 为您提供了丰富的方法来解决任务。它们总是归结为相同的策略。在这个小系列中,我们将逐一说明它们。

以下是要解决的问题:获取计算机的 MAC 地址。

在我们之前的提示中,我们看过命令和运算符。但如果你仍然无法获得所需信息怎么办?

即使如此,PowerShell 也有选项可供选择,因为您可以直接访问 .NET Framework 类型和方法。或者换句话说:如果没有程序员替您完成工作并提供特定命令,则可以自己编写功能。

显然,这可能很快成为最困难的方法,因为现在您需要具备程序员技能,并且需要更多地搜索谷歌。你需要找到一个内置的 .NET 类型来处理你所需的信息。

经过一番研究后,您可能会发现 [System.Net.NetworkInformation.NetworkInterface] .NET类型管理网络适配器,并且在 PowerShell 中,所有 .NET 类型后添加两个冒号,即可访问其方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PS C:\> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces()


Id : {DC7C0CE2-B070-4070-B5CB-1C400DA69AF8}
Name : vEthernet (Default Switch)
Description : Hyper-V Virtual Ethernet Adapter
NetworkInterfaceType : Ethernet
OperationalStatus : Up
Speed : 10000000000
IsReceiveOnly : False
SupportsMulticast : True

Id : {44FE83FC-7565-4B18-AAC8-AB3EC075E822}
Name : Ethernet 2
Description : USB Ethernet
NetworkInterfaceType : Ethernet
OperationalStatus : Up
Speed : 1000000000
IsReceiveOnly : False
SupportsMulticast : True

...

由于 .NET 返回结构化数据,因此 PowerShell cmdlet 返回的结果与原始 .NET 方法返回的结果之间没有区别。您可以以相同的方式消耗和处理数据:

1
2
3
4
5
6
7
8
9
10
11
PS C:\> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Select-Object -Property Name, NetworkInterfaceType, Description

Name NetworkInterfaceType Description
---- -------------------- -----------
vEthernet (Default Switch) Ethernet Hyper-V Virtual Ethernet Adapter
Ethernet 2 Ethernet USB Ethernet
Local Area Connection* 1 Wireless80211 Microsoft Wi-Fi Direct Virtual Adapter
Local Area Connection* 2 Wireless80211 Microsoft Wi-Fi Direct Virtual Adapter #2
WLAN Wireless80211 Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)
Bluetooth Network Connection Ethernet Bluetooth Device (Personal Area Network)
Loopback Pseudo-Interface 1 Loopback Software Loopback Interface 1

但是,您找到的.NET方法可能不直接包含所需信息。在我们的示例中,GetAllNetworkInterfaces() 返回所有网络适配器,但要获取它们的 MAC 地址,则需要深入了解 .NET 对象树。这就使得使用这种技术变得更加困难(但也令人兴奋和有益)。

这是获取有关您的网络适配器的所有所需信息的完整 .NET 代码,甚至包括特定适配器当前是否处于活动状态的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |
ForEach-Object {
$nic = $_

[PSCustomObject]@{
Name = $_.Name
Status = $_.OperationalStatus
Mac = [System.BitConverter]::ToString($nic.GetPhysicalAddress().GetAddressBytes())
Type = $_.NetworkInterfaceType
SpeedGb = $(if ($_.Speed -ge 0) { $_.Speed/1000000000 } )
Description = $_.Description
}
}

这就是整个工作闭环之处:通过将此原始 .NET 代码封装到 PowerShell 函数中,您可以向 PowerShell 词汇表添加一个新的简单命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Get-MacAddress
{
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |
ForEach-Object {
$nic = $_

[PSCustomObject]@{
Name = $_.Name
Status = $_.OperationalStatus
Mac = [System.BitConverter]::ToString($nic.GetPhysicalAddress().GetAddressBytes())
Type = $_.NetworkInterfaceType
SpeedGb = $(if ($_.Speed -ge 0) { $_.Speed/1000000000 } )
Description = $_.Description
}
}
}

一旦你运行了这个函数定义代码,就可以再次使用一个高度专业且易于使用的 PowerShell 命令,并附加你常用的一组 PowerShell cmdlet(Select-ObjectWhere-Object),将数据处理成所需的形式:

1
2
3
4
5
6
7
8
9
10
PS C:\> Get-MacAddress | Where-Object Mac | Select-Object -Property Name, Status, Mac, SpeedGb

Name Status Mac SpeedGb
---- ------ --- -------
vEthernet (Default Switch) Up 00-15-5D-58-46-A8 10
Ethernet 2 Up 80-3F-5D-05-58-91 1
Local Area Connection* 1 Down 24-EE-9A-54-1B-E6
Local Area Connection* 2 Down 26-EE-9A-54-1B-E5
WLAN Down 24-EE-9A-54-1B-E5 0,78
Bluetooth Network Connection Down 24-EE-9A-54-1B-E9 0,003

PowerShell 博客文章汇总 (2022-04 ~ 2023-03)

2022 年 03 月

2022 年 04 月

2022 年 05 月

2022 年 06 月

2022 年 07 月

2022 年 08 月

2022 年 09 月

2022 年 10 月

2022 年 11 月

2023 年

2023 年 01 月

2023 年 02 月

2023 年 03 月

PowerShell 技能连载 - 翻译数据

哈希表和字典是完美的查找表:每当您的原始数据包含难以理解的数字或命令返回仅为数值返回值时,哈希表可以将这些数字转换为友好的文本。

由于您可以自由地向哈希表添加任何键,因此要翻译的数字也不必是连续的数字范围。

以下是一个示例,从 WMI 查询操作系统信息,然后将您的 Windows SKU 从数字转换为描述性文本:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# get any info, i.e. some WMI information about your OS
$info = Get-CimInstance -ClassName Win32_OperatingSystem
# it may include information that is cryptically encoded as some number:
$rawData = $info.OperatingSystemSKU
# by using a hash table, you can easily translate the numbers to text:
$translation = @{
0 = 'UNDEFINED'
1 = 'ULTIMATE'
2 = 'HOME_BASIC'
3 = 'HOME_PREMIUM'
4 = 'ENTERPRISE'
5 = 'HOME_BASIC_N'
6 = 'BUSINESS'
7 = 'STANDARD_SERVER'
8 = 'DATACENTER_SERVER'
9 = 'SMALLBUSINESS_SERVER'
10 = 'ENTERPRISE_SERVER'
11 = 'STARTER'
12 = 'DATACENTER_SERVER_CORE'
13 = 'STANDARD_SERVER_CORE'
14 = 'ENTERPRISE_SERVER_CORE'
15 = 'ENTERPRISE_SERVER_IA64'
16 = 'BUSINESS_N'
17 = 'WEB_SERVER'
18 = 'CLUSTER_SERVER'
19 = 'HOME_SERVER'
20 = 'STORAGE_EXPRESS_SERVER'
21 = 'STORAGE_STANDARD_SERVER'
22 = 'STORAGE_WORKGROUP_SERVER'
23 = 'STORAGE_ENTERPRISE_SERVER'
24 = 'SERVER_FOR_SMALLBUSINESS'
25 = 'SMALLBUSINESS_SERVER_PREMIUM'
26 = 'HOME_PREMIUM_N'
27 = 'ENTERPRISE_N'
28 = 'ULTIMATE_N'
29 = 'WEB_SERVER_CORE'
30 = 'MEDIUMBUSINESS_SERVER_MANAGEMENT'
31 = 'MEDIUMBUSINESS_SERVER_SECURITY'
32 = 'MEDIUMBUSINESS_SERVER_MESSAGING'
33 = 'SERVER_FOUNDATION'
34 = 'HOME_PREMIUM_SERVER'
35 = 'SERVER_FOR_SMALLBUSINESS_V'
36 = 'STANDARD_SERVER_V'
37 = 'DATACENTER_SERVER_V'
38 = 'ENTERPRISE_SERVER_V'
39 = 'DATACENTER_SERVER_CORE_V'
40 = 'STANDARD_SERVER_CORE_V'
41 = 'ENTERPRISE_SERVER_CORE_V'
42 = 'HYPERV'
43 = 'STORAGE_EXPRESS_SERVER_CORE'
44 = 'STORAGE_STANDARD_SERVER_CORE'
45 = 'STORAGE_WORKGROUP_SERVER_CORE'
46 = 'STORAGE_ENTERPRISE_SERVER_CORE'
47 = 'STARTER_N'
48 = 'PROFESSIONAL'
49 = 'PROFESSIONAL_N'
50 = 'SB_SOLUTION_SERVER'
51 = 'SERVER_FOR_SB_SOLUTIONS'
52 = 'STANDARD_SERVER_SOLUTIONS'
53 = 'STANDARD_SERVER_SOLUTIONS_CORE'
54 = 'SB_SOLUTION_SERVER_EM'
55 = 'SERVER_FOR_SB_SOLUTIONS_EM'
56 = 'SOLUTION_EMBEDDEDSERVER'
57 = 'SOLUTION_EMBEDDEDSERVER_CORE'
58 = 'PROFESSIONAL_EMBEDDED'
59 = 'ESSENTIALBUSINESS_SERVER_MGMT'
60 = 'ESSENTIALBUSINESS_SERVER_ADDL'
61 = 'ESSENTIALBUSINESS_SERVER_MGMTSVC'
62 = 'ESSENTIALBUSINESS_SERVER_ADDLSVC'
63 = 'SMALLBUSINESS_SERVER_PREMIUM_CORE'
64 = 'CLUSTER_SERVER_V'
65 = 'EMBEDDED'
66 = 'STARTER_E'
67 = 'HOME_BASIC_E'
68 = 'HOME_PREMIUM_E'
69 = 'PROFESSIONAL_E'
70 = 'ENTERPRISE_E'
71 = 'ULTIMATE_E'
72 = 'ENTERPRISE_EVALUATION'
76 = 'MULTIPOINT_STANDARD_SERVER'
77 = 'MULTIPOINT_PREMIUM_SERVER'
79 = 'STANDARD_EVALUATION_SERVER'
80 = 'DATACENTER_EVALUATION_SERVER'
84 = 'ENTERPRISE_N_EVALUATION'
85 = 'EMBEDDED_AUTOMOTIVE'
86 = 'EMBEDDED_INDUSTRY_A'
87 = 'THINPC'
88 = 'EMBEDDED_A'
89 = 'EMBEDDED_INDUSTRY'
90 = 'EMBEDDED_E'
91 = 'EMBEDDED_INDUSTRY_E'
92 = 'EMBEDDED_INDUSTRY_A_E'
95 = 'STORAGE_WORKGROUP_EVALUATION_SERVE'
96 = 'STORAGE_STANDARD_EVALUATION_SERVER'
97 = 'CORE_ARM'
98 = 'CORE_N'
99 = 'CORE_COUNTRYSPECIFIC'
100 = 'CORE_SINGLELANGUAGE'
101 = 'CORE'
103 = 'PROFESSIONAL_WMC'
105 = 'EMBEDDED_INDUSTRY_EVAL'
106 = 'EMBEDDED_INDUSTRY_E_EVAL'
107 = 'EMBEDDED_EVAL'
108 = 'EMBEDDED_E_EVAL'
109 = 'NANO_SERVER'
110 = 'CLOUD_STORAGE_SERVER'
111 = 'CORE_CONNECTED'
112 = 'PROFESSIONAL_STUDENT'
113 = 'CORE_CONNECTED_N'
114 = 'PROFESSIONAL_STUDENT_N'
115 = 'CORE_CONNECTED_SINGLELANGUAGE'
116 = 'CORE_CONNECTED_COUNTRYSPECIFIC'
117 = 'CONNECTED_CAR'
118 = 'INDUSTRY_HANDHELD'
119 = 'PPI_PRO'
120 = 'ARM64_SERVER'
121 = 'EDUCATION'
122 = 'EDUCATION_N'
123 = 'IOTUAP'
124 = 'CLOUD_HOST_INFRASTRUCTURE_SERVER'
125 = 'ENTERPRISE_S'
126 = 'ENTERPRISE_S_N'
127 = 'PROFESSIONAL_S'
128 = 'PROFESSIONAL_S_N'
129 = 'ENTERPRISE_S_EVALUATION'
130 = 'ENTERPRISE_S_N_EVALUATION'
135 = 'HOLOGRAPHIC'
138 = 'PRO_SINGLE_LANGUAGE'
139 = 'PRO_CHINA'
140 = 'ENTERPRISE_SUBSCRIPTION'
141 = 'ENTERPRISE_SUBSCRIPTION_N'
143 = 'DATACENTER_NANO_SERVER'
144 = 'STANDARD_NANO_SERVER'
145 = 'DATACENTER_A_SERVER_CORE'
146 = 'STANDARD_A_SERVER_CORE'
147 = 'DATACENTER_WS_SERVER_CORE'
148 = 'STANDARD_WS_SERVER_CORE'
149 = 'UTILITY_VM'
159 = 'DATACENTER_EVALUATION_SERVER_CORE'
160 = 'STANDARD_EVALUATION_SERVER_CORE'
161 = 'PRO_WORKSTATION'
162 = 'PRO_WORKSTATION_N'
164 = 'PRO_FOR_EDUCATION'
165 = 'PRO_FOR_EDUCATION_N'
168 = 'AZURE_SERVER_CORE'
169 = 'AZURE_NANO_SERVER'
171 = 'ENTERPRISEG'
172 = 'ENTERPRISEGN'
175 = 'SERVERRDSH'
178 = 'CLOUD'
179 = 'CLOUDN'
180 = 'HUBOS'
182 = 'ONECOREUPDATEOS'
183 = 'CLOUDE'
184 = 'ANDROMEDA'
185 = 'IOTOS'
186 = 'CLOUDEN'
}
# use the raw data as key to the hash table
# AND MAKE SURE you convert numeric data to [int]!
# (WMI returns unusual data types like [byte] and [UInt16],
# and hash table keys are type-aware)
$translation[$rawData -as [int]]

这个基本的概念适用于所有类型的翻译。以下是一个示例,可以将 ping.exe 提供的返回值进行翻译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$translation = @{
0 = 'SUCCESS'
1 = 'FAILURE'
2 = 'ERROR'
}

1..255 | ForEach-Object {
# create the IP address to ping
# make sure you adjust this to your segment!
$ip = "192.168.2.$_"
# execute ping.exe and disregard the text output
ping -n 1 -w 500 $ip > $null
# instead return the translated return value found in $LASTEXITCODE
[PSCustomObject]@{
IpAddress = $ip
Status = $translation[$LASTEXITCODE]
}
}

以下是执行结果:

IpAddress   Status
---------   ------
192.168.2.1 SUCCESS
192.168.2.2 FAILURE
192.168.2.3 FAILURE
192.168.2.4 FAILURE
192.168.2.5 FAILURE
192.168.2.6 FAILURE
...

PowerShell 技能连载 - 自动化操作 Defender 杀毒软件(第 2 部分)

在 Windows 上,PowerShell 带有用于自动化内置防病毒引擎 “Defender” 的 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
PS C:\> Get-MpPreference


AllowDatagramProcessingOnWinServer : False
AllowNetworkProtectionDownLevel : False
AllowNetworkProtectionOnWinServer : False
AllowSwitchToAsyncInspection : False
AttackSurfaceReductionOnlyExclusions : {N/A: Must be and administrator to view exclusions}
AttackSurfaceReductionRules_Actions :
AttackSurfaceReductionRules_Ids :
CheckForSignaturesBeforeRunningScan : False
CloudBlockLevel : 1
CloudExtendedTimeout : 1
ComputerID : 7AB83555-0B97-47C7-A67C-8778E4757F65
ControlledFolderAccessAllowedApplications : {N/A: Must be and administrator to view exclusions}
ControlledFolderAccessProtectedFolders :
DefinitionUpdatesChannel : 0
DisableArchiveScanning : False
DisableAutoExclusions : False
DisableBehaviorMonitoring : False
DisableBlockAtFirstSeen : False
DisableCatchupFullScan : True
DisableCatchupQuickScan : True
DisableCpuThrottleOnIdleScans : True
DisableDatagramProcessing : False
DisableDnsOverTcpParsing : False
DisableDnsParsing : False
DisableEmailScanning : True
DisableFtpParsing : False
DisableGradualRelease : False
DisableHttpParsing : False
DisableInboundConnectionFiltering : False
DisableIOAVProtection : False
DisableNetworkProtectionPerfTelemetry : False
DisablePrivacyMode : False
DisableRdpParsing : False
DisableRealtimeMonitoring : False
DisableRemovableDriveScanning : True
DisableRestorePoint : True
DisableScanningMappedNetworkDrivesForFullScan : True
DisableScanningNetworkFiles : False
DisableScriptScanning : False
DisableSmtpParsing : False
DisableSshParsing : False
DisableTlsParsing : False
EnableControlledFolderAccess : 0
EnableDnsSinkhole : True
EnableFileHashComputation : False
EnableFullScanOnBatteryPower : False
EnableLowCpuPriority : False
EnableNetworkProtection : 0
EngineUpdatesChannel : 0
ExclusionExtension : {N/A: Must be and administrator to view exclusions}
ExclusionIpAddress : {N/A: Must be and administrator to view exclusions}
ExclusionPath : {N/A: Must be and administrator to view exclusions}
ExclusionProcess : {N/A: Must be and administrator to view exclusions}
ForceUseProxyOnly : False
HighThreatDefaultAction : 0
IntelTDTEnabled : True
LowThreatDefaultAction : 0
MAPSReporting : 2
MeteredConnectionUpdates : False
ModerateThreatDefaultAction : 0
PlatformUpdatesChannel : 0
ProxyBypass :
ProxyPacUrl :
ProxyServer :
PUAProtection : 1
QuarantinePurgeItemsAfterDelay : 90
RandomizeScheduleTaskTimes : True
RealTimeScanDirection : 0
RemediationScheduleDay : 0
RemediationScheduleTime : 02:00:00
ReportDynamicSignatureDroppedEvent : False
ReportingAdditionalActionTimeOut : 10080
ReportingCriticalFailureTimeOut : 10080
ReportingNonCriticalTimeOut : 1440
ScanAvgCPULoadFactor : 50
ScanOnlyIfIdleEnabled : True
ScanParameters : 1
ScanPurgeItemsAfterDelay : 10
ScanScheduleDay : 0
ScanScheduleOffset : 120
ScanScheduleQuickScanTime : 00:00:00
ScanScheduleTime : 02:00:00
SchedulerRandomizationTime : 4
ServiceHealthReportInterval : 60
SevereThreatDefaultAction : 0
SharedSignaturesPath :
SignatureAuGracePeriod : 0
SignatureBlobFileSharesSources :
SignatureBlobUpdateInterval : 60
SignatureDefinitionUpdateFileSharesSources :
SignatureDisableUpdateOnStartupWithoutEngine : False
SignatureFallbackOrder : MicrosoftUpdateServer|MMPC
SignatureFirstAuGracePeriod : 120
SignatureScheduleDay : 8
SignatureScheduleTime : 01:45:00
SignatureUpdateCatchupInterval : 1
SignatureUpdateInterval : 0
SubmitSamplesConsent : 1
ThreatIDDefaultAction_Actions : {6}
ThreatIDDefaultAction_Ids : {311978}
ThrottleForScheduledScanOnly : True
TrustLabelProtectionStatus : 0
UILockdown : False
UnknownThreatDefaultAction : 0
PSComputerName :

从结果中可以看到,一些设置是受保护的,需要管理员权限才能查询。

如果您想更改防病毒软件设置,只需使用 Set-MpPreference 命令。

当然,您可以使用 Select-Object 命令过滤返回的信息以回答特定问题,但如果您想根据值过滤信息怎么办?比如说,您需要一份当前关闭的所有功能的列表?

以下是一种聪明的方法,使用底层的 PSObject 列出所有属性的名称,然后根据它们的值进行过滤:

1
2
3
4
5
$preference = Get-MpPreference
[PSObject]$psObject = $preference.PSObject
$psObject.Properties | Where-Object {
$_.Value -is [bool] -and $_.Value -eq $true
} | Select-Object -ExpandProperty Name

同样,下面的代码列出了所有当前已禁用的属性(值为 $false):

1
2
3
4
5
$preference = Get-MpPreference
[PSObject]$psObject = $preference.PSObject
$psObject.Properties | Where-Object {
$_.Value -is [bool] -and $_.Value -eq $false
} | Select-Object -ExpandProperty Name

由于上述方法可以根据任何属性值进行过滤,因此您可以轻松地调整它,例如只转储包含小于 500 的 [byte] 属性:

1
2
3
4
5
$preference = Get-MpPreference
[PSObject]$psObject = $preference.PSObject
$psObject.Properties | Where-Object {
$_.Value -is [byte] -and $_.Value -lt 500
} | Select-Object -Property Name, Value

以下是执行结果:

Name                         Value
----                         -----
CloudBlockLevel                  1
DefinitionUpdatesChannel         0
EnableControlledFolderAccess     0
EnableNetworkProtection          0
EngineUpdatesChannel             0
HighThreatDefaultAction          0
LowThreatDefaultAction           0
MAPSReporting                    2
ModerateThreatDefaultAction      0
PlatformUpdatesChannel           0
PUAProtection                    1
RealTimeScanDirection            0
RemediationScheduleDay           0
ScanAvgCPULoadFactor            50
ScanParameters                   1
ScanScheduleDay                  0
SevereThreatDefaultAction        0
SignatureScheduleDay             8
SubmitSamplesConsent             1
UnknownThreatDefaultAction       0

现在,我们总结一下:通过将代码封装在函数中,您使代码可以重复使用,自动添加可扩展性(在上面的示例中,我们现在可以在同一个调用中转换一个或数千个字符串),并且您的生产脚本代码变得更短,可以集中精力完成真正想要实现的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS C:\> Get-Command -Module ConfigDefender

CommandType Name Version Source
----------- ---- ------- ------
Function Add-MpPreference 1.0 ConfigDefender
Function Get-MpComputerStatus 1.0 ConfigDefender
Function Get-MpPreference 1.0 ConfigDefender
Function Get-MpThreat 1.0 ConfigDefender
Function Get-MpThreatCatalog 1.0 ConfigDefender
Function Get-MpThreatDetection 1.0 ConfigDefender
Function Remove-MpPreference 1.0 ConfigDefender
Function Remove-MpThreat 1.0 ConfigDefender
Function Set-MpPreference 1.0 ConfigDefender
Function Start-MpRollback 1.0 ConfigDefender
Function Start-MpScan 1.0 ConfigDefender
Function Start-MpWDOScan 1.0 ConfigDefender
Function Update-MpSignature 1.0 ConfigDefender