PowerShell 技能连载 - 将“列出所有变量”功能加入 PowerShell

在前一个技能中我们展示了一个可以显示 PowerShell ISE 中所有打开的脚本的所有变量名的脚本。

以下是一个改造,能够在 PowerShell ISE 的“附加工具”菜单中新增一个“List Variables”命令:

$code = {
  $psise.CurrentPowerShellTab.Files |
  ForEach-Object {
        $errors = $null
        [System.Management.Automation.PSParser]::Tokenize($_.Editor.Text, [ref]$errors) |
        Where-Object { $_.Type -eq 'Variable'} |
        Select-Object -Property Content |
        Add-Member -MemberType NoteProperty -Name Script -Value $_.DisplayName -PassThru
      } |
      Sort-Object -Property Content, Script -Unique |
      Out-GridView -Title 'Variables in use' -PassThru
    }

$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add('List Variables', $code, 'ALT+V')

当您运行这段代码后,您可以按下 ALT+V 打开一个网格窗口显示所有打开的脚本中用到的变量。

PowerShell 技能连载 - 列出所有脚本中的所有变量

是否希望列出 PowerShell ISE 中打开的所有文件中的变量清单?

以下是一段能够创建这样清单的代码:

$psise.CurrentPowerShellTab.Files |
  ForEach-Object {
        $errors = $null
        [System.Management.Automation.PSParser]::Tokenize($_.Editor.Text, [ref]$errors) |
        Where-Object { $_.Type -eq 'Variable'} |
        Select-Object -Property Content |
        Add-Member -MemberType NoteProperty -Name Script -Value $_.DisplayName -PassThru
    } |
    Sort-Object -Property Content, Script -Unique

PowerShell 技能连载 - 快捷循环

适用于 PowerShell 4.0 及以上版本

PowerShell 中有一系列循环的语法。以下是一些 PowerShell 4.0 中循环执行代码的不太常见的方法。这个例子将播放一段频率不断提高的声音(请确保打开了扬声器):

(1..100).Foreach{[Console]::Beep($_ * 100, 300)}

在 PowerShell 4.0 及以上版本,数组拥有了 Where()ForEach() 方法。您可以像这样写一个过滤器:

@(Get-Service).Where({$_.Status -eq 'Running'})

PowerShell 的语法糖能让您省略这些语句中的大括号:

@(Get-Service).Where{$_.Status -eq 'Running'}

请注意该方法是针对数组的。相对于传统的管道方法,这种方法速度更快,但是内存消耗更大。

PowerShell 技能连载 - 分析(所有)事件日志源

您也许知道 Get-EventLog 命令。该命令能从一个指定的系统日志中读取所有条目:

Get-EventLog -LogName System

然而,Get-EventLog 一次只能查询一个事件日志源。所以如果您希望在所有事件日志源中查找所有错误信息,您需要创建一个循环,并且需要知道事件日志名字。

以下是一个单行的查询所有事件日志的简单技巧:

Get-EventLog -List |
  Select-Object -ExpandProperty Entries -ErrorAction SilentlyContinue |
  Where-Object { $_.EntryType -eq 'Error' }

PowerShell 技能连载 - 查找最重要的错误系统日志

如果您没有充裕的时间来调查您系统日志中出现频率最高的错误来源,请试试这行代码:

Get-EventLog -LogName System -EntryType Error, Warning |
 Group-Object -Property Source |
 Sort-Object -Property Count -Descending

当您找到导致一系列错误(或警告)的源头时,这行代码可以显示错误的细节:

# change this variable to the name of the source you want
# to explore:
$source = 'Schannel'
Get-EventLog -LogName System -Source $source |
  Out-GridView

PowerShell 技能连载 - 刷新新挂载的磁盘

如果您的脚本刚刚挂载了一个新的驱动器,PowerShell 可能无法立即存取它(例如通过 Get-ChildItem),因为 Powerell 尚未更新它的驱动器列表。

要更新 PowerShell 驱动器列表,请用这行代码:

$null = Get-PSDrive

PowerShell 技能连载 - 从 PSSnapin 中加载 cmdlet

近期多数 cmdlet 都是包装在模块中。模块是从 PowerShell 2.0 开始引入的概念。它们的主要好处是可以复制粘贴部署(不需要安装)以及模块自动加载(当您需要时,PowerShell 将自动加载模块)。

有一些 cmdlet 还是用 PowerShell snap-in (PSSnapin) 的方式包装,而不是采用模块的方式包装。PSSnapin 是从 PowerShell 1.0 就开始引入的。PSSnapin 需要安装才能使用。而且由于它们是注册在 HKEY_LOCAL_MACHINE 中,所以它们安装时往往需要管理员权限。

要列出所有可用的 PSSnapin,请运行这行代码:

Get-PSSnapin -Registered

与模块相对,PSSnapin 需要先手动加载,才能使用其中的 cmdlet。这行代码将会加载所有可用的 PSSnapin:

Get-PSSnapin -Registered | Add-PSSnapin -Verbose

PowerShell 技能连载 - 加载 PowerShell 模块

所有的 cmdlet 都位于模块或是 snap-in 中。要查看当前加载了哪些模块,请使用 Get-Module 命令。

在 PowerShell 3.0 或更高版本中,当您运行多数模块中的 cmdlet 时,它们都将被隐式地导入。这种聪明的机制实现了“按需加载”的效果,所以在多数情况下不需要手动加载模块,或是显式地手动加载所有模块。

要关闭自动加载,请使用这行代码:

$PSModuleAutoLoadingPreference = 'none'

请注意当您这么做的时候,您有责任加载所有需要的模块。

如果您希望加载所有可用的模块,请使用 Import-Module 命令。

这将读取您整个系统中所有可用的模块:

Get-Module -ListAvailable | Import-Module -Verbose

PowerShell 技能连载 - 如何查找包含指定参数的命令

Get-Command 是当您需要查找某个命令来完成一件事情时的主要工具。

您可以这样搜索动词和/或名词:

# find all cmdlets/functions that stop things
Get-Command -Verb Stop
# find all cmdlets/functions that affect services
Get-Command -Noun Service

从 PowerShell 3.0 开始,Get-Command 还可以根据一个给定的参数查找 cmdlet 或函数:

# new in PS3 and better
# find all cmdlets/functions with a -ComputerName parameter
Get-Command -ParameterName ComputerName

请注意 Get-Command 是在已加载的 cmdlet/函数中搜索。请确保在搜索前已导入了所需的模块。

PowerShell 技能连载 - 获取 CPU 核心和处理器信息

通过一行 WMI 代码,就可以查看您的 CPU 详情:

PS> Get-WmiObject -Class Win32_Processor | Select-Object -Property Name, Number*

Name                                    NumberOfCores NumberOfLogicalProcessors
----                                    ------------- -------------------------
Intel(R) Core(TM) i7-26...                          2                         4