PowerShell 技能连载 - 添加 Azure 的 PowerShell 命令

要在 Azure 云中管理和自动化操作您的资产,可以轻松安装免费的 PowerShell 模块,该模块带有大量新的 PowerShell 命令:

1
2
3
4
5
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
Write-Warning 'AzureRM and Az modules installed at the same time is not supported.')
} else {
Install-Module -Name Az -AllowClobber -Scope CurrentUser
}

在 Windows PowerShell 上,如果您已经安装了较旧的 “AzureRM” 模块,不建议再安装 “Az” 模块,因此上面的代码检查 “AzureRM” 模块是否存在,仅当 Windows PowerShell 中不存在该模块时下载并安装新的 “Az” 模块。

“Az” 模块由许多嵌套模块组成,并且都已安装。此过程可能需要几分钟。安装模块后,您可以查看所有新模块以及它们带来的命令:

1
2
3
4
5
# listing all new commands
Get-Command -Module Az.*

# listing all new modules
Get-Module -Name Az.* -ListAvailable

第一步是连接到您的Azure帐户:

1
PS> Connect-AzAccount

如果您有多个 Azure 订阅,则可以像这样选择一个订阅:

1
Get-AzSubscription | Out-GridView -Title 'Subscription?' -OutputMode Single | Select-AzSubscription

连接后,您就可以开始使用新命令了。作为初学者,您应该专注于动词为 “Get” 的命令,这样您就不会弄乱任何东西:

1
2
3
4
5
# listing all Azure VMs
Get-AzVM

# listing all safe Get-* cmdlets
Get-Command -Verb Get -Module Az.*

若要了解您可以使用新的 Azure 命令做什么,请在浏览器中访问扩展的联机帮助:

1
Start-Process -FilePath https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az

PowerShell 技能连载 - 显示 Wi-Fi 的 SSID

在上一个技巧中,我们说明了如何使用 netsh.exe 转储所有 Wi-Fi 配置名称。通常,配置名称和 SSID 是相同的。但是,如果您对真正的 Wi-Fi SSID 名称感兴趣,则可以通过转储单个配置文件并使用通配符作为配置文件名称来直接查询这些名称:

1
2
3
PS> netsh wlan show profile name="*" key=clear |
 Where-Object { $_ -match "SSID name\s*:\s(.*)$"} |
 ForEach-Object { $matches[1].Replace('"','') }

PowerShell 技能连载 - 导出 Wi-Fi 密码

在上一个技巧中,我们使用 netsh.exe 转储 Wi-Fi 配置。让我们更进一步,提取缓存的密码:

1
2
3
4
5
6
7
8
9
# get cleartext password for each profile
Foreach ($profile in $profiles)
{
$password = (@(netsh wlan show profile name="$profile" key=clear) -like '*Key Content*' -split ': ')[-1]
[PSCustomObject]@{
Profile = $profile
Password = $password
}
}

这只是一个示例,演示了 PowerShell 如何处理由控制台应用程序(例如 netsh.exe)返回的字符串信息。您也有可能遇到挑战:当 Wi-Fi 配置名称使用特殊字符(例如撇号)时,可能无法通过 netsh.exe 进行检索。

PowerShell 技能连载 - 显示 Wi-Fi 配置

PowerShell 不仅限于执行 cmdlet,还可以运行可执行文件。例如,没有内置的 cmdlet 可以列出现有的 Wi-Fi 配置文件,但是 netsh.exe 可以提供以下信息:

1
PS> netsh wlan show profiles

使用 Select-String 仅识别与模式匹配的输出行(冒号后面跟着文本),然后使用 -split 运算符在以 “: “ 分隔字符串,并返回最后一个数组元素 (index -1) 得到配置文件名称:

1
2
3
PS> netsh wlan show profiles |
Select-String ":(.{1,})$" |
ForEach-Object { ($_.Line -split ': ')[-1] }

PowerShell 技能连载 - 重定向流

PowerShell 将输出信息写入六个不同的流,并且仅将输出流分配给变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
function Invoke-Test
{
"Regular Output"
Write-Host "You always see me!"
Write-Information "Info"
Write-Warning "Warning"
Write-Error "Error"
Write-Debug "Debug"
Write-Verbose "Verbose"
Write-Output "Output"
}

$result = Invoke-Test

其余所有流要么显示在控制台中,要么隐藏在控制台中,具体取决于其适当的首选项变量的设置:

1
2
3
4
5
6
7
8
9
PS> Get-Variable -Name *preference -Exclude *confirm*,*whatif*,*progress*

Name Value
---- -----
DebugPreference SilentlyContinue
ErrorActionPreference Continue
InformationPreference SilentlyContinue
VerbosePreference SilentlyContinue
WarningPreference Continue

有时,可能还需要捕获其他流的输出并对其进行处理,而不是将其输出到控制台。为此,您可以将所有流重定向到输出流,并将总结果捕获到变量中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Invoke-Test
{
"Regular Output"
Write-Host "You always see me!"
Write-Information "Info"
Write-Warning "Warning"
Write-Error "Error"
Write-Debug "Debug"
Write-Verbose "Verbose"
Write-Output "Output"
}


$all = Invoke-Test *>&1

现在,此变量包含所有流的组合输出。为了单独处理流,您可能需要按类型对内容进行分组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS> $groups = $all | Group-Object -Property { $_.GetType().Name } -AsHashTable -AsString

PS> $groups

Name Value
---- -----
WarningRecord {Warning}
InformationRecord {You always see me!, Info}
ErrorRecord {Error}
String {Regular Output, Output}


PS> $groups.WarningRecord
WARNING: Warning

PS> $groups.InformationRecord
You always see me!
Info

PowerShell 技能连载 - 禁止 Write-Host 语句输出

Write-Host 是将信息输出给用户的非常有用的 cmdlet,因为此输出不能被丢弃:

1
2
3
4
5
6
7
8
9
10
11
function Invoke-Test
{
"Regular Output"
Write-Host "You always see me!"
}

# both show
Invoke-Test

# Write-Host still shows
$result = Invoke-Test

不过从 PowerShell 5开始,引擎发生了悄然的变化。Write-Host 产生的输出现在也由流系统控制,并且 Write-HostWrite-Information 共享新的信息流。

如果要隐藏 Write-Host 发出的消息,只需将 #6 流重定向到 $null

1
PS> $result = Invoke-Test 6>$null

有关流和重定向的更多信息,请访问 https://powershell.one/code/9.html

PowerShell 技能连载 - 丢弃数据流

PowerShell 通过不同的流输出信息。警告写入到与输出不同的流中,而错误也写入不同的流。每个流都有一个唯一的数字标识符:

IDStream
1Output
2Error
3Warning
4Verbose
5Debug
6Information

如果要丢弃某个流,可以使用重定向运算符(“>”)并将流重定向到 $null。此行代码将丢弃任何错误或警告消息:

1
Get-Process -FileVersionInfo 2>$null 3>$null

PowerShell 技能连载 - 忽略(任何)输出

无论您做什么,PowerShell中都有(少量)命令可将信息输出到控制台。无论流重定向或赋值给 $null 都不能禁止这类命令输出,例如:

1
PS> $null = Get-WindowsUpdateLog *>&1

即使所有输出流都被丢弃,Get-WindowsUpdateLog cmdlet 仍会将大量信息写入控制台。

如果遇到这种情况,最后的方法是暂时禁用内部命令 Out-Default,如下所示:

1
2
3
4
5
6
7
8
9
10
11
# temporarily overwrite Out-Default
function Out-Default {}

# run your code (guaranteed no output)
Get-WindowsUpdateLog

# test any other direct console write
[Console]::WriteLine("Hello")

# restore Out-Default
Remove-Item -Path function:Out-Default

PowerShell 技能连载 - 识别操作系统详细信息

当您查询操作系统详细信息时,WMI 会返回一个数字:

1
2
3
PS> Get-CimInstance -ClassName Win32_OperatingSystem |
Select-Object -ExpandProperty SuiteMask
272

SuiteMask 实际上是一个位掩码,其中每个位代表一个特定的细节。要将其转换为可读的文本,请使用标志枚举:

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
$SuiteMask = @{
Name = 'SuiteMaskText'
Expression = {
[Flags()] Enum EnumSuiteMask
{
SmallBusinessServer = 1
Server2008Enterprise = 2
BackOfficeComponents = 4
CommunicationsServer = 8
TerminalServices = 16
SmallBusinessServerRestricted = 32
WindowsEmbedded = 64
DatacenterEdition = 128
TerminalServicesSingleSession = 256
HomeEdition = 512
WebServerEdition = 1024
StorageServerEdition = 8192
ComputeClusterEdition = 16384
}

[EnumSuiteMask][int]$_.SuiteMask
}
}

Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property Caption, SuiteMask, $SuiteMask

这将添加一个计算得出的 SuiteMaskText 属性,该属性列出了已安装的操作系统扩展:

Caption                  SuiteMask                                   SuiteMaskText
-------                  ---------                                   -------------
Microsoft Windows 10 Pro       272 TerminalServices, TerminalServicesSingleSession

PowerShell 技能连载 - 识别 Windows 类型

WMI 返回每个不同的 Windows SKU 的密码编号:

1
2
PS> Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty OperatingSystemSKU
48

要将此数字转换为有意义的文本(例如出于报告目的),请尝试以下操作:

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
164
165
$OperatingSystemSKU = @{
Name = 'OperatingSystemSKUText'
Expression = {
$value = $_.OperatingSystemSKU

switch([int]$value)
{
0 {'PRODUCT_UNDEFINED'}
1 {'PRODUCT_ULTIMATE'}
2 {'PRODUCT_HOME_BASIC'}
3 {'PRODUCT_HOME_PREMIUM'}
4 {'PRODUCT_ENTERPRISE'}
5 {'PRODUCT_HOME_BASIC_N'}
6 {'PRODUCT_BUSINESS'}
7 {'PRODUCT_STANDARD_SERVER'}
8 {'PRODUCT_DATACENTER_SERVER'}
9 {'PRODUCT_SMALLBUSINESS_SERVER'}
10 {'PRODUCT_ENTERPRISE_SERVER'}
11 {'PRODUCT_STARTER'}
12 {'PRODUCT_DATACENTER_SERVER_CORE'}
13 {'PRODUCT_STANDARD_SERVER_CORE'}
14 {'PRODUCT_ENTERPRISE_SERVER_CORE'}
15 {'PRODUCT_ENTERPRISE_SERVER_IA64'}
16 {'PRODUCT_BUSINESS_N'}
17 {'PRODUCT_WEB_SERVER'}
18 {'PRODUCT_CLUSTER_SERVER'}
19 {'PRODUCT_HOME_SERVER'}
20 {'PRODUCT_STORAGE_EXPRESS_SERVER'}
21 {'PRODUCT_STORAGE_STANDARD_SERVER'}
22 {'PRODUCT_STORAGE_WORKGROUP_SERVER'}
23 {'PRODUCT_STORAGE_ENTERPRISE_SERVER'}
24 {'PRODUCT_SERVER_FOR_SMALLBUSINESS'}
25 {'PRODUCT_SMALLBUSINESS_SERVER_PREMIUM'}
26 {'PRODUCT_HOME_PREMIUM_N'}
27 {'PRODUCT_ENTERPRISE_N'}
28 {'PRODUCT_ULTIMATE_N'}
29 {'PRODUCT_WEB_SERVER_CORE'}
30 {'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT'}
31 {'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY'}
32 {'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING'}
33 {'PRODUCT_SERVER_FOUNDATION'}
34 {'PRODUCT_HOME_PREMIUM_SERVER'}
35 {'PRODUCT_SERVER_FOR_SMALLBUSINESS_V'}
36 {'PRODUCT_STANDARD_SERVER_V'}
37 {'PRODUCT_DATACENTER_SERVER_V'}
38 {'PRODUCT_ENTERPRISE_SERVER_V'}
39 {'PRODUCT_DATACENTER_SERVER_CORE_V'}
40 {'PRODUCT_STANDARD_SERVER_CORE_V'}
41 {'PRODUCT_ENTERPRISE_SERVER_CORE_V'}
42 {'PRODUCT_HYPERV'}
43 {'PRODUCT_STORAGE_EXPRESS_SERVER_CORE'}
44 {'PRODUCT_STORAGE_STANDARD_SERVER_CORE'}
45 {'PRODUCT_STORAGE_WORKGROUP_SERVER_CORE'}
46 {'PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE'}
47 {'PRODUCT_STARTER_N'}
48 {'PRODUCT_PROFESSIONAL'}
49 {'PRODUCT_PROFESSIONAL_N'}
50 {'PRODUCT_SB_SOLUTION_SERVER'}
51 {'PRODUCT_SERVER_FOR_SB_SOLUTIONS'}
52 {'PRODUCT_STANDARD_SERVER_SOLUTIONS'}
53 {'PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE'}
54 {'PRODUCT_SB_SOLUTION_SERVER_EM'}
55 {'PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM'}
56 {'PRODUCT_SOLUTION_EMBEDDEDSERVER'}
57 {'PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE'}
58 {'PRODUCT_PROFESSIONAL_EMBEDDED'}
59 {'PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT'}
60 {'PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL'}
61 {'PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC'}
62 {'PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC'}
63 {'PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE'}
64 {'PRODUCT_CLUSTER_SERVER_V'}
65 {'PRODUCT_EMBEDDED'}
66 {'PRODUCT_STARTER_E'}
67 {'PRODUCT_HOME_BASIC_E'}
68 {'PRODUCT_HOME_PREMIUM_E'}
69 {'PRODUCT_PROFESSIONAL_E'}
70 {'PRODUCT_ENTERPRISE_E'}
71 {'PRODUCT_ULTIMATE_E'}
72 {'PRODUCT_ENTERPRISE_EVALUATION'}
76 {'PRODUCT_MULTIPOINT_STANDARD_SERVER'}
77 {'PRODUCT_MULTIPOINT_PREMIUM_SERVER'}
79 {'PRODUCT_STANDARD_EVALUATION_SERVER'}
80 {'PRODUCT_DATACENTER_EVALUATION_SERVER'}
84 {'PRODUCT_ENTERPRISE_N_EVALUATION'}
85 {'PRODUCT_EMBEDDED_AUTOMOTIVE'}
86 {'PRODUCT_EMBEDDED_INDUSTRY_A'}
87 {'PRODUCT_THINPC'}
88 {'PRODUCT_EMBEDDED_A'}
89 {'PRODUCT_EMBEDDED_INDUSTRY'}
90 {'PRODUCT_EMBEDDED_E'}
91 {'PRODUCT_EMBEDDED_INDUSTRY_E'}
92 {'PRODUCT_EMBEDDED_INDUSTRY_A_E'}
95 {'PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVE'}
96 {'PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER'}
97 {'PRODUCT_CORE_ARM'}
98 {'PRODUCT_CORE_N'}
99 {'PRODUCT_CORE_COUNTRYSPECIFIC'}
100 {'PRODUCT_CORE_SINGLELANGUAGE'}
101 {'PRODUCT_CORE'}
103 {'PRODUCT_PROFESSIONAL_WMC'}
105 {'PRODUCT_EMBEDDED_INDUSTRY_EVAL'}
106 {'PRODUCT_EMBEDDED_INDUSTRY_E_EVAL'}
107 {'PRODUCT_EMBEDDED_EVAL'}
108 {'PRODUCT_EMBEDDED_E_EVAL'}
109 {'PRODUCT_NANO_SERVER'}
110 {'PRODUCT_CLOUD_STORAGE_SERVER'}
111 {'PRODUCT_CORE_CONNECTED'}
112 {'PRODUCT_PROFESSIONAL_STUDENT'}
113 {'PRODUCT_CORE_CONNECTED_N'}
114 {'PRODUCT_PROFESSIONAL_STUDENT_N'}
115 {'PRODUCT_CORE_CONNECTED_SINGLELANGUAGE'}
116 {'PRODUCT_CORE_CONNECTED_COUNTRYSPECIFIC'}
117 {'PRODUCT_CONNECTED_CAR'}
118 {'PRODUCT_INDUSTRY_HANDHELD'}
119 {'PRODUCT_PPI_PRO'}
120 {'PRODUCT_ARM64_SERVER'}
121 {'PRODUCT_EDUCATION'}
122 {'PRODUCT_EDUCATION_N'}
123 {'PRODUCT_IOTUAP'}
124 {'PRODUCT_CLOUD_HOST_INFRASTRUCTURE_SERVER'}
125 {'PRODUCT_ENTERPRISE_S'}
126 {'PRODUCT_ENTERPRISE_S_N'}
127 {'PRODUCT_PROFESSIONAL_S'}
128 {'PRODUCT_PROFESSIONAL_S_N'}
129 {'PRODUCT_ENTERPRISE_S_EVALUATION'}
130 {'PRODUCT_ENTERPRISE_S_N_EVALUATION'}
135 {'PRODUCT_HOLOGRAPHIC'}
138 {'PRODUCT_PRO_SINGLE_LANGUAGE'}
139 {'PRODUCT_PRO_CHINA'}
140 {'PRODUCT_ENTERPRISE_SUBSCRIPTION'}
141 {'PRODUCT_ENTERPRISE_SUBSCRIPTION_N'}
143 {'PRODUCT_DATACENTER_NANO_SERVER'}
144 {'PRODUCT_STANDARD_NANO_SERVER'}
145 {'PRODUCT_DATACENTER_A_SERVER_CORE'}
146 {'PRODUCT_STANDARD_A_SERVER_CORE'}
147 {'PRODUCT_DATACENTER_WS_SERVER_CORE'}
148 {'PRODUCT_STANDARD_WS_SERVER_CORE'}
149 {'PRODUCT_UTILITY_VM'}
159 {'PRODUCT_DATACENTER_EVALUATION_SERVER_CORE'}
160 {'PRODUCT_STANDARD_EVALUATION_SERVER_CORE'}
161 {'PRODUCT_PRO_WORKSTATION'}
162 {'PRODUCT_PRO_WORKSTATION_N'}
164 {'PRODUCT_PRO_FOR_EDUCATION'}
165 {'PRODUCT_PRO_FOR_EDUCATION_N'}
168 {'PRODUCT_AZURE_SERVER_CORE'}
169 {'PRODUCT_AZURE_NANO_SERVER'}
171 {'PRODUCT_ENTERPRISEG'}
172 {'PRODUCT_ENTERPRISEGN'}
175 {'PRODUCT_SERVERRDSH'}
178 {'PRODUCT_CLOUD'}
179 {'PRODUCT_CLOUDN'}
180 {'PRODUCT_HUBOS'}
182 {'PRODUCT_ONECOREUPDATEOS'}
183 {'PRODUCT_CLOUDE'}
184 {'PRODUCT_ANDROMEDA'}
185 {'PRODUCT_IOTOS'}
186 {'PRODUCT_CLOUDEN'}
default {"$value"}
}

}
}

Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property Caption, OperatingSystemSKU, $OperatingSystemSKU

输出将添加一个具有友好名称的新 OperatingSystemSKUText 属性:

Caption                  OperatingSystemSKU OperatingSystemSKUText
-------                  ------------------ ----------------------
Microsoft Windows 10 Pro                 48 PRODUCT_PROFESSIONAL
PowerShell 技术 QQ 群