PowerShell 技能连载 - 测试服务的响应性

适用于 PowerShell 所有版本

要测试某个服务是否仍然可响应,可以使用这个聪明的点子。首先,向 WMI 查询您想要检查的服务。WMI 将会开心地返回对应进程的 ID。

接下来,查询该进程。进程对象将会告知您该进程是冻结还是可响应的状态:

function Test-ServiceResponding($ServiceName)
{
  $service = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'"
  $processID = $service.processID

  $process = Get-Process -Id $processID

  $process.Responding
}

这个例子将会检测 Spooler 服务是否可响应:

PS> Test-ServiceResponding -ServiceName Spooler
True

请注意,该示例代码假设服务正在运行。如果您想试试的话,您可以自己检测一下,排除非正在运行的服务。

PowerShell 技能连载 - 获取 WMI 设备清单

适用于 PowerShell 所有版本

WMI 服务可以用来汇报许多关于计算机硬件的详细信息。通常,每种类型的硬件表现为一个对应的 WMI 类。不过,不太容易找出这些硬件的类。

由于所有硬件类都继承自相同的 WMI 根类(CIM_LogicalDevice),所以您可以使用这个根类来查找所有的硬件:

Get-WmiObject -Class CIM_LogicalDevice | Out-GridView

这将返回一个基本的硬件清单。不过您还可以做更多的事情。通过一点额外的代码,您可以用 WMI 获取一个硬件的类名清单:

Get-WmiObject -Class CIM_LogicalDevice |
  Select-Object -Property __Class, Description |
  Sort-Object -Property __Class -Unique |
  Out-GridView

您现在可以使用这些类名中的任意一个来查询某种特定的硬件,获取其详细信息:

PS> Get-WmiObject -Class Win32_SoundDevice

Manufacturer        Name                Status                       StatusInfo
------------        ----                ------                       ----------
Cirrus Logic, Inc.  Cirrus Logic CS4... OK                                    3
Intel(R) Corpora... Intel(R) Display... OK                                    3

PowerShell 技能连载 - 获取睡眠或休眠的时间

适用于 PowerShell 所有版本

如果您希望确认某台机器是否频繁地进入睡眠或者休眠模式,以下是一个读取对应的日志并返回详细信息的函数。它能汇报计算机何时进入睡眠模式,以及它进入睡眠模式的时长:

function Get-HibernationTime
{

  # get hibernation events
  Get-EventLog -LogName system -InstanceId 1 -Source Microsoft-Windows-Power-TroubleShooter |
  ForEach-Object {
    # create new object for results
    $result = 'dummy' | Select-Object -Property ComputerName, SleepTime, WakeTime, Duration

    # store details in new object, convert datatype where appropriate
    [DateTime]$result.Sleeptime = $_.ReplacementStrings[0]
    [DateTime]$result.WakeTime = $_.ReplacementStrings[1]
    $time = $result.WakeTime - $result.SleepTime
    $result.Duration = ([int]($time.TotalHours * 100))/100
    $result.ComputerName = $_.MachineName

    # return result
    $result
  }
}

PowerShell 技能连载 - 理解顺序过滤

适用于 PowerShell 所有版本

当您在解析基于文本的日志文件时,或是需要过滤其它类型的信息时,往往需要使用 Where-Object 命令。以下是一些常见的场景,演示如何合并过滤器:

# logical AND filter for ALL keywords
Get-Content -Path C:\windows\WindowsUpdate.log |
  Where-Object { $_ -like '*successfully installed*' } |
  Where-Object { $_ -like '*framework*' } |
  Out-GridView

# above example can also be written in one line
# by using the -and operator
# the resulting code is NOT faster, though, just harder to read
Get-Content -Path C:\windows\WindowsUpdate.log |
  Where-Object { ($_ -like '*successfully installed*') -and ($_ -like '*framework*') } |
  Out-GridView

# logical -or (either condition is met) can only be applied in one line
Get-Content -Path C:\windows\WindowsUpdate.log |
  Where-Object { ($_ -like '*successfully installed*') -or ($_ -like '*framework*') } |
  Out-GridView

PowerShell 技能连载 - 过滤 Hotfix 信息

适用于 PowerShell 所有版本

Get-HotFix 是一个用于返回已安装的 hotfix 的 cmdlet。不过它没有可以过滤 hotfix 编号的参数。

通过一个 cmdlet 过滤器,您可以很方便地查看您关注的 hotfix。这个例子只返回编号为“KB25”开头的 hotfix:

Get-HotFix |
  Where-Object {
    $_.HotfixID -like 'KB25*'
  }

请注意 Get-HotFix 有一个 -ComputerName 参数,所以如果您拥有了合适的权限,那么您也可以从远程计算机中获取 hotfix 信息。

PowerShell 技能连载 - 获取关机信息

适用于 PowerShell 所有版本

Windows 在系统事件日志中记录了所有的关机事件。您可以从那儿提取和分析信息。

以下是一个读取适当的事件日志记录、从 ReplacementStrings 数组中读取相关的信息,并以对象数组的方式返回关机信息的函数。

function Get-ShutdownInfo
{

  Get-EventLog -LogName system -InstanceId 2147484722 -Source user32 |
  ForEach-Object {

    $result = 'dummy' | Select-Object -Property ComputerName, TimeWritten, User, Reason, Action, Executable

    $result.TimeWritten = $_.TimeWritten
    $result.User = $_.ReplacementStrings[6]
    $result.Reason = $_.ReplacementStrings[2]
    $result.Action = $_.ReplacementStrings[4]
    $result.Executable = Split-Path -Path $_.ReplacementStrings[0] -Leaf
    $result.ComputerName = $_.MachineName

    $result
  }
}

现在要检查关机问题就容易多了:

PS> Get-ShutdownInfo |  Out-GridView

PowerShell 技能连载 - 复制命令行历史

适用于所有 PowerShell 版本

如果您操作了一阵子 PowerShell,然后突然意识到想保存刚才输入过的命令,那么请试试这行简单的代码:

(Get-History).CommandLine | clip

这段代码将您的所有命令行历史复制到剪贴板中。您可以把它粘贴到任何您喜欢的编辑器中,然后将命令保存到文件中。

如果您将命令粘贴到 PowerShell ISE 编辑器中,那么这些命令将会成为一段 PowerShell 脚本。

PowerShell 技能连载 - 用正则表达式搜索文件

适用于 PowerShell 所有版本

Get-ChildItem 不支持高级的文件过滤。当您使用简单的通配符时,无法利用上正则表达式。

要用上正则表达式,需要增加一个过滤用的 cmdlet 和 -match 操作符。

这个例子将在 Windows 目录中查找所有文件名包含至少 2 位数字,且文件名不超过 8 个字符的文件:

Get-ChildItem -Path $env:windir -Recurse -ErrorAction SilentlyContinue |
  Where-Object { $_.BaseName -match '\d{2}' -and $_.Name.Length -le 8 }

请注意 BaseName 属性的使用。它只返回主文件名(不包含扩展名)。通过这种方式,扩展名中的数字不会被包含在内。

PowerShell 技能连载 - 获取指定扩展名的文件

适用于 PowerShell 所有版本

当您使用 Get-ChildItem 来获取一个文件列表时,您可能会注意到 -Filter 参数有时候会导致返回比你预期的更多的文件。

以下是一个例子。这段代码并不只是返回“.ps1”扩展名的文件,而也会返回“.ps1xml”扩展名的文件:

Get-ChildItem -Path C:\windows -Recurse -ErrorAction SilentlyContinue -Filter *.ps1

要限制只返回您需要的扩展名的文件,请用一个 cmdlet 来过滤结果:

Get-ChildItem -Path C:\windows -Recurse -ErrorAction SilentlyContinue -Filter *.ps1 |
  Where-Object { $_.Extension -eq '.ps1' }

这将只返回您指定的扩展名的文件。

PowerShell 技能连载 - 修正 ISE 的编码

适用于所有 PowerShell 版本

当您在 ISE 编辑器中运行一个控制台程序时,非标准字符,例如“ä”或“ß”将会显示不正常。要修正 ISE 和隐藏的控制台之间通信的编码,请使用这段代码:

# Repair encoding. This REQUIRES a console app to run first because only
# then will ISE actually create its hidden background console

$null = cmd.exe /c echo
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# Now all is fine

cmd.exe /c echo ÄÖÜäöüß