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

不幸的是,没有一个标准的方法来管理计算机厂商的 BIOS 设置。每个厂商使用专有的方法。对于 Lenovo 电脑,您可以使用 WMI 来存取和转储 BIOS 设置:

1
2
3
4
5
6
7
8
9
10
Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi |
Where-Object CurrentSetting |
ForEach-Object {
$parts = $_.CurrentSetting.Split(',')
[PSCustomObject]@{
Setting = $parts[0]
Status = $parts[1]
Active = $_.Active
}
}

结果看起来类似这样:

Setting                             Status                                Active
-------                             ------                                ------
WakeOnLAN                           ACOnly                                  True
WakeOnLANDock                       Enable                                  True
EthernetLANOptionROM                Enable                                  True
IPv4NetworkStack                    Enable                                  True
IPv6NetworkStack                    Enable                                  True
UefiPxeBootPriority                 IPv4First                               True
WiGigWake                           Disable                                 True
WirelessAutoDisconnection           Disable                                 True
MACAddressPassThrough               Disable                                 True
USBBIOSSupport                      Disable                                 True
AlwaysOnUSB                         Enable                                  True
TrackPoint                          Automatic                               True
TouchPad                            Automatic                               True
FnCtrlKeySwap                       Disable                                 True
FnSticky                            Disable                                 True
FnKeyAsPrimary                      Disable                                 True
BootDisplayDevice                   LCD                                     True
SharedDisplayPriority               DockDisplay                             True
TotalGraphicsMemory                 256MB                                   True
BootTimeExtension                   Disable                                 True
SpeedStep                           Enable                                  True
AdaptiveThermalManagementAC         MaximizePerformance                     True
AdaptiveThermalManagementBattery    Balanced                                True
CPUPowerManagement                  Automatic                               True
OnByAcAttach                        Disable                                 True
PasswordBeep                        Disable                                 True
KeyboardBeep                        Enable                                  True
AMTControl                          Enable                                  True
USBKeyProvisioning                  Disable                                 True
WakeByThunderbolt                   Enable                                  True
ThunderboltSecurityLevel            UserAuthorization                       True
PreBootForThunderboltDevice         Disable                                 True
PreBootForThunderboltUSBDevice      Disable                                 True
LockBIOSSetting                     Disable                                 True
MinimumPasswordLength               Disable                                 True
BIOSPasswordAtUnattendedBoot        Enable                                  True
BIOSPasswordAtReboot                Disable                                 True
BIOSPasswordAtBootDeviceList        Disable                                 True
PasswordCountExceededError          Enable                                  True
FingerprintPredesktopAuthentication Enable                                  True
FingerprintReaderPriority           External                                True
FingerprintSecurityMode             Normal                                  True
FingerprintPasswordAuthentication   Enable                                  True
SecurityChip                        Enable                                  True
TXTFeature                          Disable                                 True
PhysicalPresenceForTpmProvision     Disable                                 True
PhysicalPresenceForTpmClear         Enable                                  True
BIOSUpdateByEndUsers                Enable                                  True
SecureRollBackPrevention            Enable                                  True
WindowsUEFIFirmwareUpdate           Enable                                  True
DataExecutionPrevention             Enable                                  True
VirtualizationTechnology            Enable                                  True
VTdFeature                          Enable                                  True
EthernetLANAccess                   Enable                                  True
WirelessLANAccess                   Enable                                  True
WirelessWANAccess                   Enable                                  True
BluetoothAccess                     Enable                                  True
USBPortAccess                       Enable                                  True
MemoryCardSlotAccess                Enable                                  True
SmartCardSlotAccess                 Enable                                  True
IntegratedCameraAccess              Enable                                  True
MicrophoneAccess                    Enable                                  True
FingerprintReaderAccess             Enable                                  True
ThunderboltAccess                   Enable                                  True
NfcAccess                           Enable                                  True
WiGig                               Enable                                  True
BottomCoverTamperDetected           Disable                                 True
InternalStorageTamper               Disable                                 True
ComputraceModuleActivation          Enable                                  True
SecureBoot                          Disable                                 True
SGXControl                          SoftwareControl                         True
DeviceGuard                         Disable                                 True
BootMode                            Quick                                   True
StartupOptionKeys                   Enable                                  True
BootDeviceListF12Option             Enable                                  True
BootOrder                           USBCD:USBFDD:NVMe0:HDD0:USBHDD:PCILAN   True
NetworkBoot                         USBFDD                                  True
BootOrderLock                       Disable                                 True

PowerShell 技能连载 - 探索 PowerShell 模块

大多数 cmdlet 和函数是 PowerShell 模块的一部分。如果您希望探索这些命令究竟是从哪儿来的,以下是一个简单的实践。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# replace the command name with any PowerShell command name
# you'd like to explore
$Name = "Get-Printer"
$ModuleName = (Get-Command -Name $Name -CommandType Function, Cmdlet).Source

if ('' -eq $ModuleName)
{
Write-Warning "$Name was defined in memory, no module available."
return
}

Write-Warning "$Name resides in $ModuleName module"

$module = Get-Module -Name $ModuleName -ListAvailable
explorer $module.ModuleBase

只需要将 $name 改为您希望探索的任何 PowerShell cmdlet 名称即可。如果该命令存在于一个 PowerShell 模块中,该模块将打开一个 Windows 资源管理器,您可以在其中检查它的内容。

PowerShell 技能连载 - 锁定工作站

如果您希望在 PowerShell 中锁定当前工作站,您可以利用 PowerShell 可以运行可执行程序的特性。以下是一个使用 rundll32.exe 来调用一个 Windows 内部函数来锁定工作站的快速函数:

1
2
3
4
function Lock-Workstation
{
rundll32.exe user32.dll,LockWorkStation
}

PowerShell 技能连载 - 检测 WinPE

PowerShell 可以在 WinPE 环境中运行。如果您希望检测 PowerShell 脚本是否运行在 WinPE 员警中,您只需要检查某个注册表键是否存在:

1
2
3
4
function Test-WinPE
{
return Test-Path -Path Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlset\Control\MiniNT
}

如果您在 WinPE 环境中运行,这个函数返回 $true

PowerShell 技能连载 - 从 ZIP 压缩包中解压指定的文件

PowerShell 提供了新的 cmdlet,例如 Extract-Archive,可以从一个 ZIP 文件中解压(所有的)文件。然而,只能解压整个压缩包。

如果您希望解压独立的文件,您可以使用 .NET 方法。以下是一个实现的示例:

  • 它打开一个 ZIP 文件来读取内容
  • 它查找该 ZIP 文件中所有符合指定文件扩展名的文件
  • 它只解压这些文件到您指定的输出目录

代码中的注释解释了代码在做什么。只需要确保您调整了初始变量并且制定了一个存在的 ZIP 文件,以及一个在 ZIP 文件中存在的文件扩展名:

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
#requires -Version 5.0

# change $Path to a ZIP file that exists on your system!
$Path = "$Home\Desktop\Test.zip"

# change extension filter to a file extension that exists
# inside your ZIP file
$Filter = '*.wav'

# change output path to a folder where you want the extracted
# files to appear
$OutPath = 'C:\ZIPFiles'

# ensure the output folder exists
$exists = Test-Path -Path $OutPath
if ($exists -eq $false)
{
$null = New-Item -Path $OutPath -ItemType Directory -Force
}

# load ZIP methods
Add-Type -AssemblyName System.IO.Compression.FileSystem

# open ZIP archive for reading
$zip = [System.IO.Compression.ZipFile]::OpenRead($Path)

# find all files in ZIP that match the filter (i.e. file extension)
$zip.Entries |
Where-Object { $_.FullName -like $Filter } |
ForEach-Object {
# extract the selected items from the ZIP archive
# and copy them to the out folder
$FileName = $_.Name
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$OutPath\$FileName", $true)
}

# close ZIP file
$zip.Dispose()

# open out folder
explorer $OutPath

PowerShell 技能连载 - 提取 ZIP 压缩包信息

PowerShell 提供了新的 cmdlet,例如 Extract-Archive,可以从一个 ZIP 文件中解压(所有的)文件。然而,并没有方法列出一个 ZIP 文件中的内容。

要实现这个目的,您可以使用 Extract-Archive 中使用的 .NET 库。这段代码将输入一个 ZIP 文件并提取它的内容(请确保您将 ZIP 的路径改为一个实际存在的路径):

1
2
3
4
5
6
7
8
9
# adjust this to a valid path to a ZIP file
$Path = "$Home\Desktop\Test.zip"

# load the ZIP types
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($Path)
$zip.Entries

$zip.Dispose()

PowerShell 技能连载 - 验证变量内容

从 PowerShell 5 开始,您可以为一个变量增加一个验证器。该验证器可以接受一个正则表达式,而且当您向该变量赋值时,该验证其检查新内容是否匹配正则表达式模式。如果不匹配,将会抛出一个异常,而该变量内容保持不变。

以下是一个存储 MAC 地址的变量示例:

1
[ValidatePattern('^[a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$')][string]$mac = '12:AB:02:33:12:22'

运行这段代码,然后尝试将一个新的 mac 地址赋值给该变量。如果新的 mac 地址不符合验证器,PowerShell 将抛出一个异常。

PowerShell 技能连载 - 使用 profile 脚本

默认情况下,PowerShell 在重新运行时会自动“忘记”某些设置。如果您需要“保持”设置,您需要使用 profile 脚本。当 PowerShell 在任何情况下启动时,会运行一段脚本。您可以向该脚本中添加任何命令。

这行代码将会打开当前的 PowerShell profile 脚本,而如果目前该脚本不存在,将会用 notepad 创建一个:

1
PS C:\> notepad $profile

您现在可以向 profile 脚本增加这段代码:

1
2
"Hello $env:username!"
Set-Alias -Name web -Value "$env:ProgramFiles\Internet Explorer\iexplore.exe"

您也可以运行这段代码来确保允许 PowerShell 执行本地脚本:

1
PS  C:\> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force

下一次您运行 PowerShell 时,它将会向您致礼,并且创建一个新的名为 “web“ 的别名。该别名可以在 Internet Explorer 中打开网页:

1
PS C:\> web www.powershellmagazine.com

PowerShell 技能连载 - 优化命令自动完成

PowerShell 控制台(powershell.exe、pwsh.exe)提供了可扩展的自动完成支持。当您输入了一个空格和一个连字符,按下 TAB 键将循环切换可用的参数。

Windows PowerShell (powershell.exe) 与 Linux 和 macOS 的 PowerShell (pwsh.exe) 之间有一个巨大的差异。当您在后者中按下 TAB 键,它们将立即显示所有可用的选项,并且您可以选择一个需要的建议。

要为 powershell.exe 添加这个行为,只需要运行这行代码:

1
PS C:\> Set-PSReadlineOption -EditMode Emacs

下次当您输入参数的开头部分并按下 TAB 键时,您可以立即见到所有可用的选择。接下来,当重复输入这个命令时,您可以键入选择的首字母,按下 TAB 键即可完成选择。

这时候 Windows 用户可能会听到烦人的警告音。要关闭警告音,请运行:

1
PS C:\> Set-PSReadlineOption -BellStyle None

PowerShell 技能连载 - 远程读取配置表(第 2 部分)

在前一个例子中我们演示了使用早期的 DCOM 协议从远程读取另一台机器的注册表代码。

如果您可以使用 PowerShell 远程处理,情况变得更简单。您现在可以简单地编写在本机可运行的代码,然后将它“发射”到目标机器(支持多台):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# adjust this to a remote computer of your choice
# (or multiple computers, comma-separated)
# PowerShell remoting needs to be enabled on that computer
# and you need to have local Admin privileges on that computer
$ComputerName = 'pc01'

# execute this code remotely on the machine(s)
$code = {
# read the given registry value...
Get-ItemProperty -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* |
# and show the reg values with the names below
Select-Object DisplayName, DisplayVersion, UninstallString
}

# "beam" the code over to the target computer(s), and retrieve
# the result, then show it in a grid view window
Invoke-Command -ScriptBlock $code -ComputerName $ComputerName |
Out-GridView

通过使用 PowerShell 远程处理,您只需要确保 PowerShell 远程处理的先决条件都具备。您可以用这条命令(需要本地管理员特权):

1
PS C:\> Enable-PSRemoting -SkipNetworkProfileCheck -Force