PowerShell 技能连载 - 伪造对象类型

适用于 PowerShell 3.0 及以上版本

PowerShell 内部的类型扩展系统的作用是负责将对象转换为文本。它的实现方法是通过查询一个名为“PSTypeName”的属性。您可以为自定义的对象添加这个属性来模拟其它对象类型并使 ETS 用相同方式显示该对象:

$object = [PSCustomObject]@{
  ProcessName = 'notepad'
  ID = -1
  PSTypeName = 'System.Diagnostics.Process'
}

The object pretends to be a process object, and ETS will format it accordingly:

PS> $object

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
              0        0          0     0              -1 notepad



PS>

获取所有支持管道的 Cmdlet

用这段代码可以获取所有支持管道的 PowerShell 命令:

Get-Command -CommandType Cmdlet | Where-Object {
    $_.Parameters.Values | Where-Object {
        $_.Attributes.ValueFromPipeline
    }
}

PowerShell 技能连载 - 创建新对象

适用于 PowerShell 3.0 或以上版本

这是一个创建自定义对象的简单有效的方法:

$object = [PSCustomObject]@{
  Name = 'Weltner'
  ID = 123
  Active = $true
}

这将创建一个包含预设属性值的完整功能的 PowerShell 对象:

PS> $object

Name                                                ID                    Active
----                                                --                    ------
Weltner                                            123                     True



PS> $object.Name
Weltner

PS> $object.Active
True

PS>

PowerShell 技能连载 - 在非域环境中使用 PowerShell 远程操作

适用于 PowerShell 3.0 及以上版本

缺省情况下,当您通过 Enable-PSRemoting 来启用 PowerShell 远程操作时,只启用了 Kerberos 身份验证。这要求双方主机处于同一个域(或信任的域)中,并且仅能通过计算机名访问(很可能包括域名前缀)。它无法跨域、通过域之外的机器,或通过 IP 地址来访问。

要达到上述目的,您需要在启用远程操作的机器上做一些调整。在初始化连接的机器上以管理员权限运行 PowerShell 控制台,键入以下代码:

PS> Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force

如果该路径不可用,您可能需要在该机器上(临时地)启用 PowerShell 远程操作(用 Enable-PSRemoting –SkipNetworkProfileCheck –Force)。

当您做了上述改动以后,就可以支持 NTLM 验证了。只需要记住从现在开始,要访问加入域的计算机,您需要通过 -Credential 参数提交用户名和密码。

PowerShell 技能连载 - 启用、禁用 PowerShell 远程操作

适用于 PowerShell 3.0 及更高版本

如果您想通过 PowerShell 访问一台远程计算机,那么在目标机器(您想访问的机器)上,以管理员身份运行这行代码:

PS> Enable-PSRemoting -SkipNetworkProfileCheck -Force

执行完之后,您就可以通过别的计算机访问该计算机了——假设您拥有目标机器的管理员权限,您需要指定计算机名而不是它的 IP 地址,并且两台机器都需要在同一个域中。

要交互式地连接目标机器,使用这行代码:

PS> Enter-PSSession -ComputerName targetComputerName

要在远程计算机上运行代码,请使用这种方式:

PS> Invoke-Command -ScriptBlock { Get-Service } -ComputerName targetComputerName

PowerShell 技能连载 - 从文件中读取系统日志

适用于 PowerShell 所有版本

有些时候,您可能会需要读取已经导出到磁盘上的系统日志文件,或者您希望直接从一个“evtx”格式的文件中读取系统日志。

以下是实现的方法:

$path = "$env:windir\System32\Winevt\Logs\Setup.evtx"
Get-WinEvent -Path $path

PowerShell 技能连载 - WMI 搜索工具

适用于 PowerShell 所有版本

WMI 是一个很棒很强大的技术:只需要指定一个 WMI 类名,您就可以获取该类的所有实体。

PS> Get-WmiObject -Class Win32_BIOS


SMBIOSBIOSVersion : 76CN27WW
Manufacturer      : LENOVO
Name              : 76CN27WW
SerialNumber      : 1006250300406
Version           : LENOVO - 1

那么如何知道有哪些 WMI 类呢?以下是一个搜索工具函数:

function Find-WMIClass
{
   param
   (
      [Parameter(Mandatory=$true)]
      $SearchTerm = 'Resolution'
   )

   Get-WmiObject -Class * -List |
   Where-Object { $_.Properties.Count -ge 3 } |
   Where-Object { $_.Name -notlike 'Win32_Perf*'  } |
   Where-Object {
      $ListOfNames = $_.Properties | Select-Object -ExpandProperty Name
      ($ListOfNames -like "*$SearchTerm*") -ne $null
   } |
   Sort-Object -Property Name
}

只需要指定一个搜索条件。该函数将会查找所有属性名中包含搜索条件的 WMI 类(可以用通配符来扩大搜索范围)。

这段代码能搜索属性以“resolution”结尾的 WMI 类:

PS> Find-WMIClass -SearchTerm *resolution


   NameSpace: ROOT\cimv2

Name                                Methods              Properties
----                                -------              ----------
CIM_CacheMemory                     {SetPowerState, R... {Access, AdditionalErr...
CIM_CurrentSensor                   {SetPowerState, R... {Accuracy, Availabilit...
CIM_FlatPanel                       {SetPowerState, R... {Availability, Caption...
CIM_Memory                          {SetPowerState, R... {Access, AdditionalErr...
CIM_MonitorResolution               {}                   {Caption, Description,...
CIM_NonVolatileStorage              {SetPowerState, R... {Access, AdditionalErr...
CIM_NumericSensor                   {SetPowerState, R... {Accuracy, Availabilit...
CIM_PCVideoController               {SetPowerState, R... {AcceleratorCapabiliti...
CIM_PointingDevice                  {SetPowerState, R... {Availability, Caption...
CIM_Printer                         {SetPowerState, R... {Availability, Availab...
CIM_Tachometer                      {SetPowerState, R... {Accuracy, Availabilit...
CIM_TemperatureSensor               {SetPowerState, R... {Accuracy, Availabilit...
CIM_VideoController                 {SetPowerState, R... {AcceleratorCapabiliti...
CIM_VideoControllerResolution       {}                   {Caption, Description,...
CIM_VolatileStorage                 {SetPowerState, R... {Access, AdditionalErr...
CIM_VoltageSensor                   {SetPowerState, R... {Accuracy, Availabilit...
Win32_CacheMemory                   {SetPowerState, R... {Access, AdditionalErr...
Win32_CurrentProbe                  {SetPowerState, R... {Accuracy, Availabilit...
Win32_DisplayControllerConfigura... {}                   {BitsPerPixel, Caption...
Win32_MemoryArray                   {SetPowerState, R... {Access, AdditionalErr...
Win32_MemoryDevice                  {SetPowerState, R... {Access, AdditionalErr...
Win32_NetworkAdapterConfiguration   {EnableDHCP, Rene... {ArpAlwaysSourceRoute,...
Win32_PointingDevice                {SetPowerState, R... {Availability, Caption...
Win32_Printer                       {SetPowerState, R... {Attributes, Availabil...
Win32_PrinterConfiguration          {}                   {BitsPerPel, Caption, ...
Win32_SMBIOSMemory                  {SetPowerState, R... {Access, AdditionalErr...
Win32_TemperatureProbe              {SetPowerState, R... {Accuracy, Availabilit...
Win32_VideoConfiguration            {}                   {ActualColorResolution...
Win32_VideoController               {SetPowerState, R... {AcceleratorCapabiliti...
Win32_VoltageProbe                  {SetPowerState, R... {Accuracy, Availabilit...

下一步,选择一个类名并观察它的实际数据:

PS> Get-WmiObject -Class CIM_CacheMemory | Select-Object -Property *

PowerShell 技能连载 - 列出所有信息

适用于 PowerShell 所有版本

大多数时候,PowerShell 不会显示从 cmdlet 中返回的所有信息。相反地,PowerShell 限制了只显示信息中最常见的部分。

PS> Get-WmiObject -Class CIM_CacheMemory


BlockSize      : 1024
CacheSpeed     :
CacheType      : 4
DeviceID       : Cache Memory 0
InstalledSize  : 32
Level          : 3
MaxCacheSize   : 32
NumberOfBlocks : 32
Status         : OK

(...)

要看到完整的信息,请像这样加一句 Select-Object 语句:

PS> Get-WmiObject -Class CIM_CacheMemory | Select-Object -Property *


PSComputerName              : TOBI2
DeviceID                    : Cache Memory 0
ErrorCorrectType            : 5
Availability                : 3
Status                      : OK
StatusInfo                  : 3
BlockSize                   : 1024
CacheSpeed                  :
CacheType                   : 4
InstalledSize               : 32
Level                       : 3
MaxCacheSize                : 32
NumberOfBlocks              : 32
WritePolicy                 : 3
__GENUS                     : 2
__CLASS                     : Win32_CacheMemory
__SUPERCLASS                : CIM_CacheMemory
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_CacheMemory.DeviceID="Cache Memory 0"
__PROPERTY_COUNT            : 53
__DERIVATION                : {CIM_CacheMemory, CIM_Memory, CIM_StorageExtent,
                              CIM_LogicalDevice...}
__SERVER                    : TOBI2
__NAMESPACE                 : root\cimv2
__PATH                      : \\TOBI2\root\cimv2:Win32_CacheMemory.DeviceID="Cache
                               Memory 0"
Access                      :
AdditionalErrorData         :
Associativity               : 7
Caption                     : Cache Memory
ConfigManagerErrorCode      :
ConfigManagerUserConfig     :
CorrectableError            :
CreationClassName           : Win32_CacheMemory
CurrentSRAM                 : {5}
Description                 : Cache Memory
EndingAddress               :
ErrorAccess                 :
ErrorAddress                :
ErrorCleared                :
ErrorData                   :
ErrorDataOrder              :
ErrorDescription            :
ErrorInfo                   :
ErrorMethodology            :
ErrorResolution             :
ErrorTime                   :
ErrorTransferSize           :
FlushTimer                  :
InstallDate                 :
LastErrorCode               :
LineSize                    :
Location                    : 0
Name                        : Cache Memory
OtherErrorDescription       :
PNPDeviceID                 :
PowerManagementCapabilities :
PowerManagementSupported    :
Purpose                     : L1 Cache
ReadPolicy                  :
ReplacementPolicy           :
StartingAddress             :
SupportedSRAM               : {5}
SystemCreationClassName     : Win32_ComputerSystem
SystemLevelAddress          :
SystemName                  : TOBI2
Scope                       : System.Management.ManagementScope
Path                        : \\TOBI2\root\cimv2:Win32_CacheMemory.DeviceID="Cache
                               Memory 0"
Options                     : System.Management.ObjectGetOptions
ClassPath                   : \\TOBI2\root\cimv2:Win32_CacheMemory
Properties                  : {Access, AdditionalErrorData, Associativity,
                              Availability...}
SystemProperties            : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}
Qualifiers                  : {dynamic, Locale, provider, UUID}
Site                        :
Container                   :

(...)

PowerShell 技能连载 - 获取美国邮政编码

适用于 PowerShell 所有版本

是否曾需要查找某个(美国)城市的邮政编码,或者反过来通过邮政编码查找城市的名称?

只需要简单地用 PowerShell 连接到一个免费的 Web Service 就可以获得这些信息:

$webservice = New-WebServiceProxy -Uri 'http://www.webservicex.net/uszip.asmx?WSDL'
$webservice.GetInfoByCity('New York').Table
$webservice.GetInfoByZIP('10286').Table

在 PowerShell 中利用正则表达式来解析文本块

需求

给定一段文本,如:

1, abcd [xxxx]
vkjl gas kje asld
gew wef
2, bbb [wefs]
oioias wmfjalkjs
3, ccc [wegas]
kzxlj kjlwiewe ii

要求分割成多段以数字开头的文本块,如:

第一块:

1, abcd [xxxx]
vkjl gas kje asld
gew wef

第二块:

2, bbb [wefs]
oioias wmfjalkjs

第三块:

3, ccc [wegas]
kzxlj kjlwiewe ii

思路

  • 定义我们要东西为 n 个“block”。
  • 每个“block”的特征是:
    • 以数字开头
    • block 之前可能是整段文本的起始也有可能是一个回车符。
    • block 之后可能是一个回车符+下一行的数字也有可能是整段文本的结束。
  • block 之前和之后的回车符是不需要的
  • block 应该尽可能“非贪婪”,遇到下一个符合条件的,算作一个新的 block 开始。

其中,“block 之前和之后的回车符是不需要的”可以用正则表达式的“零宽断言”来解决。

代码

$subject = @'
1, abcd [xxxx]
vkjl gas kje asld
gew wef
2, bbb [wefs]
oioias wmfjalkjs
3, ccc [wegas]
kzxlj kjlwiewe ii
'@

$resultlist = new-object System.Collections.Specialized.StringCollection
$regex = [regex]@'
(?snx)(^|(?<=\n))
(?<block>\d, .*?)
((?=\n\d, )|$)
'@
$match = $regex.Match($subject)
while ($match.Success) {
    $resultlist.Add($match.Groups['block'].Value) | out-null
    $match = $match.NextMatch()
}

$resultlist | ForEach-Object {
    echo $_
    echo ---
}

输出结果

1, abcd [xxxx]
vkjl gas kje asld
gew wef
---
2, bbb [wefs]
oioias wmfjalkjs
---
3, ccc [wegas]
kzxlj kjlwiewe ii
---