PowerShell 技能连载 - 详细的电池报告

如果您的笔记本电脑电池电量过低,或者您想调查相关问题,可以通过一种简单的方法来生成大量的电池充电报告。它会准确显示电池的充电时间,电池容量以及电池耗尽的时间。

以下是创建 14 天报告的代码:

1
2
3
4
$path = "$env:temp/battery_report2.html"
powercfg /batteryreport /output $Path /duration 14
Start-Process -FilePath $Path -Wait
Remove-Item -Path $path

请注意,此调用不需要管理员特权(如常所述)。只要确保报告文件是在您具有写权限的位置生成的。

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

通过 PowerShell 库,可以轻松访问其他 PowerShell 命令。例如,您可以下载并安装 SharePoint 的命令扩展,并使用 PowerShell 来自动化 SharePoint 网站:

1
2
3
4
Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser -Force

# listing all new SharePoint commands
Get-Command -Module Microsoft.Online.SharePoint.PowerShell

在 PowerShell 库中,还有许多用于处理 SharePoint 的 PowerShell 模块。Find-Module 可帮助您确定更多有用的资源:

1
Find-Module -Name *sharepoint*

知道您感兴趣的模块名称后,请使用 Install-Module 下载并安装它,或使用 Save-Module 将其下载到您选择的隔离文件夹中。这样,您可以调查源代码并确定是否信任该代码。

要了解有关 SharePoint 的 PowerShell 命令的更多信息,请访问官方帮助页面:

1
Start-Process -FilePath https://docs.microsoft.com/en-us/powershell/sharepoint/sharepoint-online/connect-sharepoint-online?view=sharepoint-ps

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