PowerShell 技能连载 - 用 BitsTransfer 在后台下载数据

下载大型的文件是一个挑战,因为下载的过程可能比机器的开机时间还长。通过 BitsTransfer,您可以在后台下载文件,甚至当机器关机或重启后,仍然能够续传直到完成。

以下代码可以下载一段 NASA 的视频。然而,下载过程是在后台,而且你可以继续做别的事。实际上。当您关闭 PowerShell 甚至电脑之后,下次启动时下载仍会继续。

1
2
3
4
$url = 'https://mars.nasa.gov/system/downloadable_items/41764_20180703_marsreport-1920.mp4'
$targetfolder = "$Home\Desktop"

Start-BitsTransfer -Source $url -Destination $targetfolder -Asynchronous -Priority Low

您需要做的只是偶尔查看一下 BitsTransfer,检查下载任务是否完成。当一个下载过程完成后,需要您负责完成下载。只有这样,所有下载的文件才会从后台缓冲区中复制到最终的目的地:

1
2
3
Get-BitsTransfer |
Where-Object Jobstate -eq Transferred |
Complete-BitsTransfer

完成。

要获取挂起的 BitsTransfer 任务的更多信息,请试试这段代码:

1
PS> Get-BitsTransfer | Select-Object -Property *

And if you have Admin privileges, you can even dump the jobs from other users, including internal accounts. This way you’ll see updates and other things that are on their way to you:
如果您有管理员特权,您甚至可以从其它用户那儿转储所有任务,包括内部账号。通过这种方式您可以查看进度等其它信息:

1
PS> Get-BitsTransfer -AllUsers

PowerShell 技能连载 - 通过 SSL 和 BitsTransfer

有一个很实用的内置方法可以下载文件,甚至支持 SSL 连接。该方法是 Start-BitsTransfer。它也会显示一个进度条,指示实际的下载状态。以下是一个可用的例子:

1
2
3
4
5
$url = 'https://mars.nasa.gov/system/downloadable_items/41764_20180703_marsreport-1920.mp4'
$OutFile = "$home\desktop\videoNasa2.mp4"


Start-BitsTransfer -Source $url -Destination $OutFile -Priority Normal -Description 'NASA Movie'

PowerShell 技能连载 - 通过 SSL 和 Invoke-WebRequest 下载数据

Invoke-WebRequest 可以下载文件,但是对 HTTPS URL 可能会遇到麻烦。要使用 SSL 连接,您可能需要改变缺省的设置。以下是一个可用的示例:

1
2
3
4
5
6
$url = 'https://mars.nasa.gov/system/downloadable_items/41764_20180703_marsreport-1920.mp4'
$OutFile = "$home\desktop\video.mp4"

$AllProtocols = [Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[Net.ServicePointManager]::SecurityProtocol = $AllProtocols
Invoke-WebRequest -OutFile $OutFile -UseBasicParsing -Uri $url

PowerShell 技能连载 - 查找禁用的 GPO

以下是一行可以转储所有禁用了所有设置的组策略对象的代码:

1
Get-Gpo -All | Where-Object GpoStatus -eq AllSettingsDisabled

这个示例需要 Microsoft 免费的 RSAT 工具。

PowerShell 技能连载 - 浏览所有的事件日志

Get-EventLog 总是需要您通过 LogName 明确地指定一个事件日志。您无法使用通配符,并且无法一次性浏览所有事件日志。

然而,可以使用这个技巧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS> Get-EventLog -LogName *

Max(K) Retain OverflowAction Entries Log
------ ------ -------------- ------- ---
20.480 0 OverwriteAsNeeded 13.283 Application
512 7 OverwriteOlder 98 Dell
20.480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 0 Internet Explorer
512 7 OverwriteOlder 46 isaAgentLog
20.480 0 OverwriteAsNeeded 0 Key Management Service
128 0 OverwriteAsNeeded 97 OAlerts
10.240 0 OverwriteAsNeeded 0 PowerShellPrivateLog
512 7 OverwriteOlder 0 PreEmptive
Security
20.480 0 OverwriteAsNeeded 5.237 System
16.384 0 OverwriteAsNeeded 20 TechSmith
15.360 0 OverwriteAsNeeded 10.279 Windows PowerShell

所以显然,-LogName 终究不支持通配符。然而,您现在看到的不再是事件日志项,而是一个摘要视图。不过您仍然可以访问以下的事件日志条目:

1
PS> Get-EventLog -LogName * | Select-Object -ExpandProperty Entries -ErrorAction SilentlyContinue

这将从所有的日志中转储所有事件日志条目。在这儿,您可以添加自定义过滤器。要查看近 48 小时所有事件日志错误,请试试这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# take events not older than 48 hours
$deadline = (Get-Date).AddHours(-48)

Get-EventLog -LogName * |
ForEach-Object {
# get the entries, and quiet errors
try { $_.Entries } catch {}
} |
Where-Object {
# take only errors
$_.EntryType -eq 'Error'
} |
Where-Object {
# take only entries younger than the deadline
$_.TimeGenerated -gt $deadline
}

PowerShell 技能连载 - 创建事件日志报告

您可能经常使用 Get-EventLog 来转储事件日志信息,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS> Get-EventLog -LogName System -EntryType Error -Newest 6

Index Time EntryType Source InstanceID Message
----- ---- --------- ------ ---------- -------
5237 Jul 31 12:39 Error DCOM 10016 The des...
5234 Jul 31 09:54 Error DCOM 10016 The des...
5228 Jul 31 09:46 Error DCOM 10016 The des...
5227 Jul 31 09:40 Error DCOM 10016 The des...
5218 Jul 31 09:38 Error DCOM 10016 The des...
5217 Jul 31 09:38 Error DCOM 10016 The des...



PS>

但是,如果您想创建有用的报告,请确保将输出表格格式化,并启用换行:

1
PS> Get-EventLog -LogName System -EntryType Error -Newest 6 | Format-Table -AutoSize -Wrap

您现在可以方便地将结果输送到 Out-File 并创建有意义的文本报告。同时,设置其 Width 参数,以调整报告文件的宽度。

如果您不知道某个日志的确切名字,只需要将 "*" 赋给 -LogName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS> Get-EventLog -LogName *

Max(K) Retain OverflowAction Entries Log
------ ------ -------------- ------- ---
20.480 0 OverwriteAsNeeded 13.283 Application
512 7 OverwriteOlder 98 Dell
20.480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 0 Internet Explorer
512 7 OverwriteOlder 46 isaAgentLog
20.480 0 OverwriteAsNeeded 0 Key Management Service
128 0 OverwriteAsNeeded 97 OAlerts
Security
20.480 0 OverwriteAsNeeded 5.237 System
15.360 0 OverwriteAsNeeded 10.279 Windows PowerShell

PowerShell 技能连载 - PowerShell 控制台的键盘快捷方式

PowerShell 控制台从 5.0 版开始发布了一个名为 PSReadLine 的模块,它不仅可以对命令做语法着色,还有更多的功能。它包含持久化的命令历史,并且可以将自定义命令绑定到键盘快捷方式上。

请看这个示例:

1
2
3
4
5
Set-PSReadlineKeyHandler -Chord Ctrl+H -ScriptBlock {
Get-History |
Out-GridView -Title 'Select Command' -PassThru |
Invoke-History
}

当您在 PowerShell 控制台中运行这段代码(它不能在 PowerShell ISE 中运行!),按下 CTRL + H 打开一个网格视图窗口,这个窗口中列出了所有命令行历史。您可以轻松地选择一个命令并执行它。

显然,这不仅是一个示例。您可以将任何脚本块绑定到未使用的键盘快捷方式,例如提交变更到 Git,或是打开喜爱的滚动新闻条。

PowerShell 技能连载 - 在 PowerShell 中使用 SSH

PowerShell 6 (PowerShell Core) 终于支持 SSH 了:您可以使用 SSH 来连接非 Windows 机器来进行 PowerShell 远程操作。

如果只是需要用 SSH 连接到交换机或者其它设备,那么可以使用免费的模块。该模块为所有 PowerShell 添加了大量有用的新的 SSH 命令。以下是如何下载和安装该模块的方法:

1
Install-Module -Name posh-ssh -Repository PSGallery -Scope CurrentUser

要列出所有新的命令,请运行以下代码:

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
PS C:\> (Get-Command -Module posh-ssh).Name
Get-PoshSSHModVersion
Get-SFTPChildItem
Get-SFTPContent
Get-SFTPLocation
Get-SFTPPathAttribute
Get-SFTPSession
Get-SSHPortForward
Get-SSHSession
Get-SSHTrustedHost
Invoke-SSHCommand
Invoke-SSHCommandStream
Invoke-SSHStreamExpectAction
Invoke-SSHStreamExpectSecureAction
New-SFTPFileStream
New-SFTPItem
New-SFTPSymlink
New-SSHDynamicPortForward
New-SSHLocalPortForward
New-SSHRemotePortForward
New-SSHShellStream
New-SSHTrustedHost
Remove-SFTPItem
Remove-SFTPSession
Remove-SSHSession
Remove-SSHTrustedHost
Rename-SFTPFile
Set-SFTPContent
Set-SFTPLocation
Set-SFTPPathAttribute
Start-SSHPortForward
Stop-SSHPortForward
Test-SFTPPath
Get-SCPFile
Get-SCPFolder
Get-SFTPFile
New-SFTPSession
New-SSHSession
Set-SCPFile
Set-SCPFolder
Set-SFTPFile

PowerShell 技能连载 - 管理 Lenovo BIOS 设置(第 4 部分)

在前一个技能中我们演示了如何读取和改变 Lenovo 计算机的 BIOS 设置。例如,以下代码禁止 WakeOnLan:

1
2
3
4
5
6
7
#requires -RunAsAdministrator

$currentSetting = Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi
$currentSetting.SetBiosSetting('WakeOnLAN,Disable').return

$SaveSettings = Get-WmiObject -Class Lenovo_SaveBiosSettings -Namespace root\wmi
$SaveSettings.SaveBiosSettings().return

如果某个 BIOS 设置是被密码保护的,以下代码演示如何更改一个受 BIOS 密码保护的设置:

1
2
3
4
5
6
7
8
#requires -RunAsAdministrator
$BIOSPassword = "topSecret"

$currentSetting = Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi
$currentSetting.SetBiosSetting("WakeOnLAN,Disable,$BIOSPassword,ascii,us").return

$SaveSettings = Get-WmiObject -Class Lenovo_SaveBiosSettings -Namespace root\wmi
$SaveSettings.SaveBiosSettings("$BIOSPassword,ascii,us").return

请注意该密码仅在该设置项受 BIOS 密码保护的情况下生效。如果实际中没有密码而您输入了密码,它并不会被验证,而且改动会生效。

PowerShell 技能连载 - 管理 Lenovo BIOS 设置(第 3 部分)

在前一个技能中我们介绍了如何在 PowerShell 中管理 Lenovo BIOS。通常,只需要管理单个设置。请注意某些操作需要管理员特权。

以下是转储所有可用设置名称的代码。请注意这些名字是大小写敏感的:

1
2
3
4
$currentSetting = Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi
$currentSetting.CurrentSetting |
Where-Object { $_ } |
ForEach-Object { $_.Split(',')[0] }

一旦您知道了想要操作的设置项的名称,就可以用这段代码来读取设置:

1
2
3
4
$Settingname = "WakeOnLAN"

$currentSetting = Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi -Filter "CurrentSetting LIKE '%$SettingName%'"
$currentSetting.CurrentSetting

以下代码转储某个指定设置的所有合法值:

1
2
3
4
5
6
7
#requires -RunAsAdministrator

# this is case-sensitive
$Setting = "WakeOnLAN"

$selections = Get-WmiObject -Class Lenovo_GetBiosSelections -Namespace root\wmi
$selections.GetBiosSelections($Setting).Selections.Split(',')

以下是如何将一个设置改为一个新的值(例如,禁止 WakeOnLan):

1
2
3
4
5
6
7
#requires -RunAsAdministrator

$currentSetting = Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi
$currentSetting.SetBiosSetting('WakeOnLAN,Disable').return

$SaveSettings = Get-WmiObject -Class Lenovo_SaveBiosSettings -Namespace root\wmi
$SaveSettings.SaveBiosSettings().return