PS对象处理操作常用命令

2022-09-29 15:23:38 浏览数 (1)

[TOC]

0x00 对象操作处理相关命令

描述: 下述命令常用于对象的相关操作,涉及创建、排序分组与比较等。

代码语言:javascript复制
Get-Command -Noun Object | ? { $_.Source -eq "Microsoft.PowerShell.Utility" } | Format-Table -Property Name,Version,CommandType
# Name           Version CommandType
# ----           ------- -----------
# Compare-Object 3.1.0.0      Cmdlet
# Group-Object   3.1.0.0      Cmdlet
# Measure-Object 3.1.0.0      Cmdlet
# New-Object     3.1.0.0      Cmdlet
# Select-Object  3.1.0.0      Cmdlet
# Sort-Object    3.1.0.0      Cmdlet
# Tee-Object     3.1.0.0      Cmdlet

0x01 对象创建属性和方法

New-Object 命令 - 创建新的对象

描述: 通过New-Object cmdlet 创建Microsoft.NET Framework或COM对象的实例,您可以指定.NET Framework类的类型(缺省)或COM对象的ProgID(需要使用ComObject参数)。

基础语法:

代码语言:javascript复制
New-Object [-TypeName] <System.String> [[-ArgumentList] <System.Object[]>] [-Property <System.Collections.IDictionary>] [<CommonParameters>]
New-Object [-ComObject] <System.String> [-Property <System.Collections.IDictionary>] [-Strict] [<CommonParameters>]

参数说明:

  • TypeName : .NET Framework类。
  • ComObject : 指定要使用的 COM 类的编程标识符(或 ProgId )(获取请参照基础语法对象章)。
  • Strict : 生成非终止错误(只能在Com对象中使用)。
  • Property : 指定传递的参数采用 { } 进行包含。

基础示例:

代码语言:javascript复制
# 0.New-Object可以创建一个对象,空对象什么都没有,如果调用它不会返回任何东西, 但可以在后续为他增加方法和属性。
PS > $obj = New-Object object  #空对象

# 1.通过String类输入字符和数字创建一个包含指定个数字符的字符串
PS > New-Object String("*",10)
  # **********

# 2.创建System.Version对象(.NET Framework类)
New-Object -TypeName System.Version -ArgumentList "1.2.3.4"  # 方式1: 通过New-object创建对象
[System.Version]"1.2.3.4" # 方式2: 通过类型转换创建对象
  # Major  Minor  Build  Revision
  # -----  -----  -----  --------
  # 1      2      3      4

# 3.创建Internet Explorer COM对象(注意必须以管理员权限运行才行)
$IE1 = New-Object -COMObject InternetExplorer.Application.1 -Strict -Property @{Navigate2="www.microsoft.com"; Visible = $True}  # 实践脚本编写中推荐
# 方式2:下面的命令得到与上面示例相同的结果。
$IE2 = New-Object -COMObject InternetExplorer.Application`
$IE2.Navigate2("www.microsoft.com")`
$IE2.Visible = $True`


# 4.将多个参数传递给.net的构造函数 (Collections - 集合)
# PowerShell将数组的每个成员绑定到构造函数的一个参数。
$array = @('One', 'Two', 'Three')
$parameters = @{
    TypeName = 'System.Collections.Generic.HashSet[string]'
    ArgumentList = ([string[]]$array, [System.StringComparer]::OrdinalIgnoreCase)
}
$set = New-Object @parameters     # # $set | Get-Member -MemberType Property 
$set
  # One
  # Two
  # Three
$set.length  # 显示每个字符串的字符串长度
  # 3
  # 3
  # 5

# 5.调用将数组作为单个参数的构造函数
$array = @('One', 'Two', 'Three')
# This command throws an exception.
$set = New-Object -TypeName 'System.Collections.Generic.HashSet[string]' -ArgumentList $array
# This command succeeds.
$set = New-Object -TypeName 'System.Collections.Generic.HashSet[string]' -ArgumentList (,[string[]]$array)
$set
One
Two
Three

# 6.进行事件日志访问
# .NET Framework 类库包括一个名为 System.Diagnostics.EventLog 的类
[System.Diagnostics.EventLog]::GetEventLogs()
  # Max(K) Retain OverflowAction        Entries Log
  # ------ ------ --------------        ------- ---
  # 20,480      0 OverwriteAsNeeded      15,146 Application
  # 20,480      0 OverwriteAsNeeded           0 HardwareEvents
  #    512      7 OverwriteOlder              0 Internet Explorer
  # 20,480      0 OverwriteAsNeeded           0 Key Management Service
  #    128      0 OverwriteAsNeeded          62 OAlerts
  #                                             Security
  # 20,480      0 OverwriteAsNeeded      35,409 System
  # 15,360      0 OverwriteAsNeeded       8,402 Windows PowerShell
# 如果随后键入 $AppLog 你将可以看到它包含应用程序日志:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
  # Max(K) Retain OverflowAction        Entries Log
  #   ------ ------ --------------        ------- ---
  #   20,480      0 OverwriteAsNeeded      15,146 Application

# 若要访问远程计算机上的应用程序日志,必须同时将日志名称和计算机名称(或 IP 地址)作为参数提供。
$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application,192.168.1.81
# 采用对象方法清除事件日志, 可以使用 Get-Member 来显示与对象关联的方法
$AppLog | Get-Member -MemberType Method
PS C:WINDOWSsystem32> $AppLog
  Max(K) Retain OverflowAction        Entries Log
  ------ ------ --------------        ------- ---
  20,480      0 OverwriteAsNeeded      15,146 Application

PS C:WINDOWSsystem32> $AppLog.Clear()  # 清除后Entries条目为0
PS C:WINDOWSsystem32> $AppLog
  Max(K) Retain OverflowAction        Entries Log
  ------ ------ --------------        ------- ---
  20,480      0 OverwriteAsNeeded           0 Application

Tips : Windows PowerShell 允许你使用具有 .NET Framework 和 COM 接口的软件组件,使用它们可执行许多系统管理任务。

Tips : 由于大多数 .NET Framework 核心类都包含在 System 命名空间中,所以如果 PS 找不到你指定的类型名称的匹配项,它将自动尝试查找你在 System 命名空间中指定的类,所以可以忽略System。

Tips : 可以采用 New-Object 来处理组件对象模型 (COM) 件, 组件的范围从 Windows 脚本宿主 (WSH) 包含的各种库到 ActiveX 应用程序(如大多数系统上安装的 Internet Explorer)。

代码语言:javascript复制
# 通过指定以下 progid 来创建 WSH 对象: WScript.Shell 、 WScript.Network 、 Scripting.Dictionary 和 Scripting.FileSystemObject
# 有时使用 WSH 类执行某些任务(如创建快捷方式)仍更加简单。
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

Add-Member 命令 - 向PowerShell对象的实例添加自定义属性和方法。

描述: 该 cmdlet 允许您将成员(属性和方法)添加到PowerShell对象的实例中。例如可以添加包含对象描述的NoteProperty成员或运行脚本以更改对象的ScriptMethod成员。

语法说明

代码语言:javascript复制
add-Member [-MemberType] {AliasProperty | CodeProperty | Property | NoteProperty | ScriptProperty | Properties | PropertySet | Method | CodeMethod | ScriptMethod | Methods | ParameterizedProperty | MemberSet | Event | Dynamic | All} [-Name] <System.String> [[-Value] <System.Object>] [[-SecondValue] <System.Object>] [-Force] -InputObject <System.Management.Automation.PSObject> [-PassThru] [-TypeName <System.String>] [<CommonParameters>]

Add-Member [-NotePropertyName] <System.String> [-NotePropertyValue] <System.Object> [-Force] -InputObject <System.Management.Automation.PSObject> [-PassThru] [-TypeName <System.String>] [<CommonParameters>]

Add-Member [-NotePropertyMembers] <System.Collections.IDictionary> [-Force] -InputObject <System.Management.Automation.PSObject> [-PassThru] [-TypeName <System.String>] [<CommonParameters>]

Add-Member -InputObject <System.Management.Automation.PSObject> [-PassThru] [-TypeName <System.String>] [<CommonParameters>]

参数说明: MemberType 参数 : 指定要添加到成员的的类型,添加包括属性和方法。

  • 1.属性相关
    • NoteProperty(增加一个属性)
    • Property:真正的属性
    • AliasProperty:另外一个属性的别名
    • CodeProperty:通过静态的.Net方法返回属性的内容
    • ScriptProperty:通过脚本执行返回一个属性的值
    • ParameterizedProperty:需要传递参数的属性
  • 2.方法相关
    • ScriptMethod(增加一个执行Powershell脚本方法)
    • Method:正常的方法
    • CodeMethod:映射到静态的.NET方法

PassThru 参数 : 生成输出对象。 Force 参数 : 强制执行比如覆盖已存在的成员(属性)

基础示例:

代码语言:javascript复制
# 1.创建一个PSObject对象并为其添加属性
PS > $obj=New-Object PSObject
PS > Add-Member -MemberType NoteProperty -Name "A" -Value "1" -InputObject $obj
PS > Add-Member -MemberType NoteProperty -Name "B" -Value "2" -InputObject $obj
PS > Add-Member -MemberType NoteProperty -Name "C" -Value "3" -InputObject $obj
PS > Add-Member -MemberType NoteProperty -Name "D" -Value "4" -InputObject $obj
PS > $obj
# A B C D
# - - - -
# 1 2 3 4
PS > Add-Member -MemberType NoteProperty -Name "E" -Value "5" -InputObject $obj
PS > $obj
# 未知对象格式化ETS遵循一个规律如果对象的属性`少于5个则表格显示,否则列表显示`。
# A : 1
# B : 2
# C : 3
# D : 4
# E : 5

# 2.向表示Test.txt文件的FileInfo对象添加一个值为“Done”的Status note属性。
PS C:UsersWeiyiGeek> $A = Get-ChildItem ping.bat
PS C:UsersWeiyiGeek> $A | Add-Member -NotePropertyName Status -NotePropertyValue Done
PS C:UsersWeiyiGeek> $A.ToString()
  # C:UsersWeiyiGeekping.bat
PS C:UsersWeiyiGeek> $A.Status
  # Done

# 3.以下示例将Size alias属性添加到表示Test.txt文件的对象中,向PSObject添加别名属性。
PS C:UsersWeiyiGeek> $A.Length  # 55 Bytes
PS C:UsersWeiyiGeek> $A | Add-Member -MemberType AliasProperty -Name Size -Value Length # 新属性是长度属性的别名。
PS C:UsersWeiyiGeek> $A.Size    # 55 Bytes

# 4.此示例将StringUse注释属性添加到字符串,因为Add成员不能向字符串输入对象添加类型,最后一个命令显示新属性
$S = "WeiyiGeek"
$S = Add-Member -NotePropertyMembers @{StringUse="Display";StringName="Name"} -InputObject $S -PassThru
$S            # WeiyiGeek
$S.StringUse  # Display
$S.StringName # Name

# 5.创建一个对象给它添加静态属性和动态属性(执行PS脚本返回的值),以及添加PS脚本方法。
$obj=New-Object PSObject
$d = [ordered]@{Name="Server";System="Server Core";PSVersion="4.0"}
$obj | Add-Member -NotePropertyMembers $d -TypeName Asset -PassThru -Force
  # Name   System      PSVersion
  # ----   ------      ---------
  # Server Server Core 4.0
$obj | Add-Member -MemberType NoteProperty -Name AddTime -Value (get-date)
$obj | Add-Member -MemberType ScriptProperty -Name CurrentTime -Value {get-date}
$obj
  # AddTime            CurrentTime
  # -------            -----------
  # 2021/4/28 22:42:48 2021/4/28 22:43:06
$obj | Add-Member ScriptMethod corkscrew { "Pop! Cheers!" } # 直接通过管道增加一个新方法
Add-member -MemberType ScriptMethod -InputObject $obj demo1 {"I'm is function, $obj "}
Add-Member -memberType ScriptMethod -InputObject $obj -Name demo2 -Value { "I'm Write now, Args : $Args" }
PS C:UsersWeiyiGeek> $obj.demo1()
  #I'm is function, @{AddTime=04/28/2021 22:42:48; CurrentTime=System.Management.Automation.PSScriptProperty}
PS C:UsersWeiyiGeek> $obj.demo2("WeiyiGeek")
  # I'm Write now, Args : WeiyiGeek
PS C:UsersWeiyiGeek> $obj.corkscrew()
  # Pop! Cheers!


# 6.将SizeInMB脚本方法添加到FileInfo对象,该对象将文件大小计算为最接近的兆字节。
$A = Get-ChildItem *.sh  # 可以是多个文件
$S = {[math]::Round(($this.Length / 1MB), 5)}
$A | Add-Member -MemberType ScriptMethod -Name "SizeInMB" -Value $S
$A.SizeInMB()
0.01263
0.00176
0.00164


# 7.此函数用于将一个对象的所有属性复制到另一个对象。foreach循环使用Get-Member cmdlet获取From对象的每个属性。
function Copy-Property ($From, $To)
{
  $properties = Get-Member -InputObject $From -MemberType Property
  foreach ($p in $properties)
  {
    $To | Add-Member -MemberType NoteProperty -Name $p.Name -Value $From.$($p.Name) -Force
  }
}

Get-Member 命令 - 对象属性和方法获取

描述: Get-Member 可帮助发现可用于命令的对象、属性和方法。任何生成基于对象的输出的命令都可以通过管道传递到该Cmdlet中。

Tips : 此处对于属性、对象和方法的名词介绍不在做过多的介绍(学习过面向对象编程的都应该知道)。 Tips :为了获得关于静态成员的信息,类的成员(而不是实例的成员)使用static参数,要仅获取某些类型的成员如(NoteProperties)请使用MemberType参数。

语法说明:

代码语言:javascript复制
Get-Member [[-Name] <System.String[]>] [-Force] [-InputObject <System.Management.Automation.PSObject>] [-MemberType {AliasProperty | CodeProperty | Property | NoteProperty | ScriptProperty | Properties | PropertySet | Method | CodeMethod | ScriptMethod | Methods | P
  arameterizedProperty | MemberSet | Event | Dynamic | All}] [-Static] [-View {Extended | Adapted | Base | All}] [<CommonParameters>]

参数说明: MemberType : 指定成员类型取值包括:

  • Property:真正的属性
  • AliasProperty:另外一个属性的别名
  • CodeProperty:通过静态的.Net方法返回属性的内容
  • NoteProperty:随后增加的属性
  • ScriptProperty:通过脚本执行返回一个属性的值
  • ParameterizedProperty:需要传递参数的属性
  • Method:正常的方法
  • CodeMethod:映射到静态的.NET方法
  • ScriptMethod:一个执行Powershell脚本的方法 Static : 获取成员的静态方法 View :仅获取特定类型的属性和方法,指定一个或多个值。
  • Extended : 仅获取在Types.ps1xml文件中或通过使用Add Member cmdlet添加的属性和方法。
  • Adapted : 仅获取在PowerShell扩展类型系统中定义的属性和方法。
  • Base : 仅获取.NET对象的原始属性和方法(没有扩展或调整)。
  • All : Gets the members in the Base, Adapted, and Extended views.

基础示例:

代码语言:javascript复制
# 1.检索计算机上运行的 Windows 时间服务的相关信息的属性
Get-Service -Name w32time | Get-Member
# TypeName 指示返回的对象类型。
# TypeName:System.ServiceProcess.ServiceController

# 知道命令生成的对象类型之后,就可以使用此信息查找接受该类型的对象作为输入的命令
Get-Command -ParameterType ServiceController
# CommandType     Name                                               Version    Source
# -----------     ----                                               -------    ------
# Cmdlet          Get-Service                                        3.1.0.0    Microsoft.PowerShell.Management
# Cmdlet          Restart-Service                                    3.1.0.0    Microsoft.PowerShell.Management
......

# 2.查看对象的静态方法
Get-Member -static -memberType *Method  

# 3.查看Get-Host 对象的属性以及方法
Host | Get-Member -MemberType Property 
     # Name             MemberType Definition
     # ----             ---------- ----------
     # CurrentCulture   Property   cultureinfo CurrentCulture {get;}
     # CurrentUICulture Property   cultureinfo CurrentUICulture {get;}
     # DebuggerEnabled  Property   bool DebuggerEnabled {get;set;}
     # InstanceId       Property   guid InstanceId {get;}
     # IsRunspacePushed Property   bool IsRunspacePushed {get;}
     # Name             Property   string Name {get;}
     # PrivateData      Property   psobject PrivateData {get;}
     # Runspace         Property   runspace Runspace {get;}
     # UI               Property   System.Management.Automation.Host.PSHostUserInterface UI {get;}
     # Version          Property   version Version {get;}
(Host).Version  # 以Version属性值获得PS版本
     # Major  Minor  Build  Revision
     # -----  -----  -----  --------
     # 5      1      19041  610

Host | Get-Member -MemberType Method
     # TypeName:System.Management.Automation.Internal.Host.InternalHost
     # Name                   MemberType Definition
     # ----                   ---------- ----------
     # EnterNestedPrompt      Method     void EnterNestedPrompt()
     # Equals                 Method     bool Equals(System.Object obj)
     # ExitNestedPrompt       Method     void ExitNestedPrompt()
     # GetHashCode            Method     int GetHashCode()
     # GetType                Method     type GetType()
     # .........
     # ToString               Method     string ToString()
(Host).GetHashCode();
     # 14844108


# 4.通过将 Get-Service 的结果通过管道传递到 Select-Object 并将 * 通配符指定为 Property 参数的值来选择所有属性或者进行制定。
Get-Service -Name TermService | Get-Member -MemberType Property
     # Status   Name               DisplayName
     # ------   ----               -----------
     # Running  TermService        Remote Desktop Services

(Get-Service -Name TermService).ServiceName
     # TermService
(Get-Service -Name TermService).DisplayName
     # Remote Desktop Services
(Get-Service -Name TermService).Status
     # Running

# 采用 Select-Object 命令搞定服务名称、描述、以及其状态
Get-Service -Name TermService | Select-Object -Property ServiceName,DisplayName,Status
# ServiceName DisplayName              Status
# ----------- -----------              ------
# TermService Remote Desktop Services Running


# 5.方法是可执行的操作
Get-Service -Name TermService | Get-Member -MemberType Method
# 例如 Stop 方法可用于停止 Windows 远程桌面服务。
(Get-Service -Name TermService).Stop()


# 6.使用 Start-Service cmdlet 指定 PassThru 参数,以使其生成输出,然后通过管道将输出传递到 Get-Member
Start-Service -Name w32time -PassThru | Get-Member
  # TypeName:System.ServiceProcess.ServiceController
  # Name                      MemberType    Definition
  # ----                      ----------    ----------
  # Name                      AliasProperty Name = ServiceName
  # RequiredServices          AliasProperty RequiredServices = ServicesDependedOn
  # Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs)
  # Close                     Method        void Close()


# 7.获取服务对象的扩展成员
# 描述: 此示例获取通过使用 `Types.ps1xml` 文件或 `Add Member` cmdlet扩展的服务对象的方法和属性。
$obj=New-Object PSObject
$d = [ordered]@{Name="Server";System="Server Core";PSVersion="4.0"}
$obj | Add-Member -NotePropertyMembers $d -TypeName Asset -PassThru -Force
$obj | Get-Member -View Extended
  #   TypeName:Asset
  # Name      MemberType   Definition
  # ----      ----------   ----------
  # Name      NoteProperty string Name=Server
  # PSVersion NoteProperty string PSVersion=4.0
  # System    NoteProperty string System=Server Core


# 8.此示例获取事件查看器中系统日志中事件日志对象的脚本属性。
Get-WinEvent -LogName System -MaxEvents 1 | Get-Member -View All
Get-WinEvent -LogName System -MaxEvents 1 | Select-Object -Property Id,LevelDisplayName,LogName,Message
  #    Id LevelDisplayName LogName Message
  #    -- ---------------- ------- -------
  #  7040 信息             System  Background Intelligent Transfer Service 服务的启动类型从 自动启动 更改为 按需启动。


# 9.接受从通道里面传递的对象也可以指定-InputObject参数接收。
$array = @(1,'hello')
$array | Get-Member             # 显示  TypeName:System.Int32 - TypeName:System.String
Get-Member -InputObject $array  # 显示  TypeName:System.Object[]

Tips : 许多初学者认为无法使用 Get-* 命令进行颠覆性更改。 但是如果方法使用不当,也会带来严重后果。

Tips : 若要通过管道将命令传递到 Get-Member,命令必须生成基于对象的输出,例如以下命令是不行的 Get-Service -Name w32time | Out-Host | Get-Member,因为Out-Host 直接写入 PowerShell 主机,但它不会为管道生成基于对象的输出。 因此无法通过管道将该命令传输到 Get-Member。 。


0x02 排序分组

Sort-Object 命令 - 按属性值对对象排序

描述:主要是根据传递过来的对象的属性作为条件来进行排序,例如升序(Ascending)或者降序(Descending),别名是 sort;

基础语法:

代码语言:javascript复制
# 语法
Sort-Object [[-Property] <System.Object[]>] [-CaseSensitive] [-Culture <System.String>] [-Descending] [-InputObject <System.Management.Automation.PSObject>] [-Unique] [<CommonParameters>]

实际案例:

代码语言:javascript复制
# 1.因此输出按默认排序属性Name排序。
Get-ChildItem -Path C:Test | Sort-Object

# 2.按文件长度对当前目录排序
PS> Get-ChildItem -Path C:Test -File | Sort-Object -Property Length

# 3.按内存使用情况对进程排序
PS> Get-Process | Sort-Object -Property WS | Select-Object -Last 5

# 4.按Id对HistoryInfo对象排序
Get-History | Sort-Object -Property Id -Descending
# 默认会根据length进行升序排序
ls | Sort-Object Length
# 如果要降序排列使用Descending选项
ls | Sort-Object Length -Descending
# 通过ls获取当前目录的所有文件信息,然后通过Sort -Descending对文件信息按照Name降序排列,最后将排序好的文件的Name和Mode格式化成Table输出。
ls | sort -Descending Name | Format-Table Name,Mode
# Name        Mode
# d.txt       -a---
# c.txt       -a---

# 5.主要关键字降序排序,次要关键字升序的排序
Get-Service | Sort-Object @{expression="Length";Descending=$true},@{expression="Name";Ascending=$true}
# Status   Name               DisplayName
#   ------   ----               -----------
#   Running  Appinfo            Application Information
#   Running  BthAvctpSvc        AVCTP service
#   Running  BrokerInfrastru... Background Tasks Infrastructure Ser...
#   Running  BDESVC             BitLocker Drive Encryption Service

# 6.按时间跨度对文本文件排序
Get-ChildItem -Path C:Test*.txt | Sort-Object -Property @{Expression = {$_.CreationTime - $_.LastWriteTime}; Descending = $False} | Format-Table CreationTime, LastWriteTime, FullName

# 7.对文本文件中的名称或者整型进行排序(并去重)
Get-Content -Path C:TestServerNames.txt | Sort-Object -Unique
# 在第二个示例中,`Get Content`获取文件的内容,并将管道行发送到`Sort Object` cmdlet。`Sort Object`使用脚本块将字符串转换为整数。
# 在示例代码中,`[int]`将字符串转换为整数,`$`表示每个字符串在管道中的位置。整数对象通过管道发送到“Sort Object”cmdlet。
# `Sort Object`按数字顺序对整数对象进行排序。
Get-Content -Path C:TestProductId.txt | Sort-Object {[int]$_}

Group-Object 命令 - 对包含指定属性的相同值的对象进行分组。

语法参数:

代码语言:javascript复制
Group-Object [[-Property] <System.Object[]>] [-AsHashTable] [-AsString] [-CaseSensitive] [-Culture <System.String>] [-InputObject <System.Management.Automation.PSObject>] [-NoElement] [<CommonParameters>]

基础示例:

代码语言:javascript复制
# 1.查看当前关闭和开启的所有服务,并且通过状态进行分组
PS > Get-Service | Group-Object Status | Format-Table -AutoSize -Wrap
  # Count Name    Group
  # ----- ----    -----
  #   170 Stopped {AarSvc_48f8d, AJRouter, ALG, AppIDSvc...}
  #   103 Running {AMD External Events Utility, AnyShare Service, Appinfo, AudioEndpointBuilder...}


# 2.当前目录的文件以扩展名进行分组
PS> ls | Group-Object Extension
  # Count Name   Group
  # ----- ----   -----
  #     5        {11, 2, Dell-Latitude-E6330-Mojave-Hackintosh-EFI, 课件...}
  #     1 .py    {123.py}
  #     1 .gz    {back.tar.gz}
  #     9 .lnk   {eclipse.exe.lnk..}
$files = Get-ChildItem -Path $PSHOME -Recurse
$files | Group-Object -Property extension -NoElement | Sort-Object -Property Count -Descending
  # Count Name
  # ----- ----
  #   365 .xml
  #   231 .cdxml
# 根据当前应用程序的发布者分组
Get-Process | Group-Object Company -NoElement | Sort-Object -Property Count -Descending


# 3.奇与偶数分组
1..20 | Group-Object -Property {$_ % 2}
  # Count Name                      Group
  # ----- ----                      -----
  #     10 0                         {2, 4, 6, 8...}
  #     10 1                         {1, 3, 5, 7...}


# 4.按EntryType对事件日志事件进行分组(根据数量排序)
Get-WinEvent -LogName System -MaxEvents 1000 | Group-Object -Property Level -NoElement | Sort-Object -Property Count -Descending
  # Count Name
  # ----- ----
  #   720 4
  #   151 2
  #   127 3
  #     2 1
Get-WinEvent -LogName System -MaxEvents 1000 | Group-Object -Property LevelDisplayName
  # Count Name                      Group
  # ----- ----                      -----
  #   719 信息                      {System.Diagnostics.Eventing.Reader.EventLogRecord...}
Get-WinEvent -LogName System -MaxEvents 1000 | Group-Object -Property Id | Sort-Object -Property Count -Descending
  # Count Name                      Group
  # ----- ----                      -----
  #   374 7040                      {System.Diagnostics.Eventing.Reader.EventLogRecord...}
  #   186 16                        {System.Diagnostics.Eventing.Reader.EventLogRecord...}


# 6.在哈希表中对对象进行分组
$A = Get-Command Get-*, Set-* -CommandType cmdlet | Group-Object -Property Verb -AsHashTable -AsString
  # $A
  # Name     Value
  # ----     -----
  # Get      {Get-Acl, Get-Alias, Get-AppLockerFileInformation, Get-AppLockerPolicy...}
  # Set      {Set-Acl, Set-Alias, Set-AppBackgroundTaskResourcePolicy, Set-AppLockerPolicy...}
$A.Get
  # CommandType     Name                               Version    Source
  # -----------     ----                               -------    ------
  # Cmdlet          Get-Acl                            3.0.0.0    Microsoft.PowerShell.Security
  # Cmdlet          Get-Alias                          3.1.0.0    Microsoft.PowerShell.Utility
  # Cmdlet          Get-AppLockerFileInformation       2.0.0.0    AppLocker
  # Cmdlet          Get-AppLockerPolicy                2.0.0.0    AppLocker

# 7.使用表达式来进行分组
# 根据文件的大小是否大于1kb分组
ls | Group-Object {$_.Length -gt 1kb}
# 如果按照文件名的首字母分组
ls | Group-Object {$_.name.SubString(0,1).toUpper()}

TIPS: Group-Object并不是唯一可以完成分组功能的命令,事实上格式化命令,例如Format-Object支持一个GroupBy的参数,也可以完成分组。

Get-Unique 命令 - 删除重复对象

描述: Get-Unique 可以从已排序的对象列表中删除重复对象, 它会逐个遍历对象,每次遍历时都会与前一个对象进行比较,如果和前一个对象相等就会抛弃当前对象,否则就保留一般是排序后再进行去重,与Linux中uniq命令有一致之处;

基础语法:

代码语言:javascript复制
Get-Unique [-AsString] [-InputObject <System.Management.Automation.PSObject>] [<CommonParameters>]

Get-Unique [-InputObject <System.Management.Automation.PSObject>] [-OnType] [<CommonParameters>]

基础示例:

代码语言:javascript复制
# 1.去重实例 Get-Unique 与 Sort-Object -Unique 效果一致。
PS > 1,2,3,1 | Get-Unique
  # 1
  # 2
  # 3
  # 1
PS > 1,2,3,1 | Sort-Object -Unique
  # 1
  # 2
  # 3

# 2.不换行显示(值得需学习)
PS > Get-ChildItem | foreach{$_.Extension} | Sort-Object | Get-Unique | Write-Host -NoNewline
.CHM.chw.docx.gz.jpg.lnk.png.properties.py.sql.txt


# 3.获取文本文件中的唯一单词
$A = $( foreach ($line in Get-Content C:Test1File1.txt) {
    $line.tolower().split(" ")
  }) | Sort-Object | Get-Unique
$A.count


# 4.获取目录中唯一的对象类型
Get-ChildItem | Sort-Object {$_.GetType()} | Get-Unique -OnType

# 5.AsString参数告诉“Get Unique”将ProcessName值视为字符串。如果没有此参数`Get Unique`将ProcessName值视为对象,并且只返回对象的一个实例,即列表中的第一个进程名。
Get-Process | Sort-Object | Select-Object processname | Get-Unique -AsString
  # ProcessName
  # -----------
  # ApplicationFrameHost
  # ...

0x03 筛选过滤

描述: 如果您要过滤某些对象和对象的属性可以采用以下cmdlet.

  • 如果要过滤对象可以使用 Where-Object;
  • 如果要过滤对象的属性,可以使用 Select-Object;
  • 如果要自定义个性化的过滤效果可以使用 ForEach-Object。
  • 最后如果想过滤重复的结果,可是使用 Get-Uinque。

Select-Object 命令 - 对象属性数据筛选呈现

描述:显示特定对象属性的列字段的数据进行呈现,即选择对象或对象特性;

语法说明:

代码语言:javascript复制
语法
Select-Object 
[[-Property] <System.Object[]>] [-ExcludeProperty <System.String[]>]
[-ExpandProperty <System.String>]
[-First <System.Int32>] 
[-InputObject <System.Management.Automation.PSObject>] 
[-Last <System.Int32>] 
[-Skip <System.Int32>] 
[-Unique] 
[-Wait] 
[<CommonParameters>]

Select-Object [[-Property] <System.Object[]>] [-ExcludeProperty <System.String[]>] [-ExpandProperty <System.String>] [-InputObject <System.Management.Automation.PSObject>] [-SkipLast <System.Int32>] [-Unique] [<CommonParameters>]

Select-Object [-Index <System.Int32[]>] [-InputObject <System.Management.Automation.PSObject>] [-Unique] [-Wait] [<CommonParameters>]

基础实例:

代码语言:javascript复制
# 1.获取get-process对象中的 Handle,Id,ProcessName 三个属性此为表格的形式
# Tips :除非使用自定义格式设置,否则返回超过四个属性的命令默认为列表。
PS > get-process | Select-Object Handle,Id,ProcessName 
  # Handle    Id ProcessName
  # ------    -- -----------
  #            0 Idle
  #            4 System
  #            8 svchost
PS C:UsersWeiyiGeek> Get-Service -Name w32time | Select-Object -Property Status, DisplayName, Can*
  # Status              : Running
  # DisplayName         : Windows Time
  # CanPauseAndContinue : False
  # CanShutdown         : True
  # CanStop             : True


# 2.按特性选择对象并设置结果格式
Get-Process Explorer | Select-Object -Property ProcessName -ExpandProperty Modules | Format-List


# 3.显示第一个或者前几个条目
PS> Get-service | Select-Object -First 2
  # Status   Name               DisplayName
  # ------   ----               -----------
  # Stopped  AarSvc_48f8d       AarSvc_48f8d
  # Stopped  AJRouter           AllJoyn Router Service
Get-Process | Sort-Object -Property WS | Select-Object -Last 5
# 列出占用CPU最大的5个进程
Get-process | sort -Descending cpu | select -First 5


# 4.从数组中选择唯一字符
"a","b","c","a","a","a" | Select-Object -Unique
  # a
  # b
  # c


# 5.在事件日志中选择最新和最旧的事件
$a = Get-EventLog -LogName "Windows PowerShell"
$a | Select-Object -Index 0, ($A.count - 1)
  # Index Time          EntryType   Source                 InstanceID Message
  # ----- ----          ---------   ------                 ---------- -------
  # 7427 4月 07 15:29  Information PowerShell                    400 引擎状态已从 None 更改为 Available。...
  # 1    11月 05 00:10 Information PowerShell                    600 提供程序“Registry”为 Started...

# 5.支持通配符过滤排除显示指定属性
PS> Dir | Select-Object * -Exclude 'Last*'
# 限制对象的数量
Dir | Select-Object -ExcludeProperty "*N*" -First 5


# 6.选择除第一个对象以外的所有对象
New-PSSession -ComputerName (Get-Content Servers.txt | Select-Object -Skip 1)

# 7.重命名文件并选择几个要查看的文件
Get-ChildItem *.txt -ReadOnly | 
Rename-Item -NewName {$_.BaseName   "-ro.txt"} -PassThru |
Select-Object -First 5 -Wait

# 8.演示-ExpandProperty参数的复杂性
# Create a custom object to use for the Select-Object example.
$object = [pscustomobject]@{Name="CustomObject";Expand=@(1,2,3,4,5)}
# Use the ExpandProperty parameter to Expand the property.
$object | Select-Object -ExpandProperty Expand -Property Name
  # 1
  # 2
  # 3
  # 4
  # 5

# 9.在对象上创建自定义特性
$customObject = 1 | Select-Object -Property MyCustomProperty
$customObject.MyCustomProperty = "New Custom Property"
$customObject
  # MyCustomProperty
  # ----------------
  # New Custom Property

# 10.为每个InputObject创建计算属性
Get-Process | Select-Object -Property ProcessName,{$_.StartTime.DayOfWeek}
  # ProcessName  $_.StartTime.DayOfWeek
  # ----         ----------------------
  # alg                       Wednesday
  # ati2evxx                  Wednesday
  # ati2evxx                   Thursday

# 添加自定义属性以计算传入的每个FileInfo对象的大小(以KB为单位)。 (非常值得学习)
# Use the pipeline variable to divide each file's length by 1 KiloBytes
$size = @{label="Size(KB)";expression={$_.length/1KB}}

# Create an additional calculated property with the number of Days since the file was last accessed.
# You can also shorten the key names to be 'l', and 'e', or use Name instead of Label.
$days = @{l="Days";e={((Get-Date) - $_.LastAccessTime).Days}}

# You can also shorten the name of your label key to 'l' and your expression key to 'e'.
Get-ChildItem $PSHOME -File | Select-Object Name, $size, $days
  # Name                        Size(KB)        Days
  # ----                        --------        ----
  # Certificate.format.ps1xml   12.5244140625   223
  # Diagnostics.Format.ps1xml   4.955078125     223
  # DotNetTypes.format.ps1xml   134.9833984375  223

Where-Object 命令 - 自定义条件过滤

描述:它的主要作用是可以自定义过滤条件,并过滤从管道传递来的对象数据。(一般在管道符之后)

关系操作符号:

WeiyiGeek.

基础示例:

代码语言:javascript复制
#1.获得C:Windows目录下所有大小超过200 bytes的文件。(? / where)
> Get-ChildItem C:Windows | Where-Object -FilterScript {$_.Length -gt 200}
> ls . | Where-Object -FilterScript {$_.Extension -eq ".txt"}
##目录: C:UsersAdministrator
# Mode                LastWriteTime     Length Name                                         ----                -------------     ------ ----                                         -a---        2019/11/18     20:58          4 1.txt      


#2.别名使用与like相似过滤
> ls . | ? -FilterScript {$_.BaseName -like "无线网络连接-GEEK"}


#3.我要获得所有名为svchost的进程信息。
> Get-Process | Where-Object{$_.ProcessName -eq "svchost"}
# Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
# -------  ------    -----      -----     ------     --  -- -----------
#     354      33     8956      11296       0.14    276   0 svchost
Get-Process | Where-Object ProcessName -EQ "svchost"  #PowerShell 3.0版本后Where就有了更简单的写法我们不需要?和{};
# 608      28    21124      23296    95     4.80    292 svchost   

#4.甚至可以筛选之后继续筛选(在JAVA中我们叫链式编程)
Get-Process | Where-Object{$_.ProcessName -eq "svchost"} | Where-Object{$_.Id -gt 1000}


#5.补充过滤案例
PS D:> get-alias | Where-Object -FilterScript {$_.Name -like 'sa*'}
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           sajb -> Start-Job
Alias           sal -> Set-Alias
Alias           saps -> Start-Process
Alias           sasv -> Start-Service

0x04 统计对比

Measure-Object 命令 - 计算对象的数字特性,以及字符串对象(如文本文件)中的字符、单词和行。

描述: Measure-Object 允许指定待统计对象的属性如求最小值、最大值、平均值、和

基础语法:

代码语言:javascript复制
# 语法
Measure-Object [[-Property] <System.String[]>] [-Average] [-InputObject <System.Management.Automation.PSObject>] [-Maximum] [-Minimum] [-Sum] [<CommonParameters>]

Measure-Object [[-Property] <System.String[]>] [-Character] [-IgnoreWhiteSpace] [-InputObject <System.Management.Automation.PSObject>] [-Line] [-Word] [<CommonParameters>]

基础示例:

代码语言:javascript复制
# 1.要查看当前目录文件占用空间的情况。
PS > ls | measure length -Average -Sum -Maximum -Minimum
  # Count    : 26
  # Average  : 6109027.96153846
  # Sum      : 158834727
  # Maximum  : 97612275
  # Minimum  : 250
  # Property : length

# 2.统计文本文件中的字符数,单词数,行数
"One", "Two", "Three", "Four" | Set-Content -Path C:Temptmp.txt
Get-Content C:Temptmp.txt | Measure-Object -Character -Line -Word
# Lines Words Characters Property
# ----- ----- ---------- --------
#     4     4         15

# 3.包含指定特性的度量对象
$services = Get-Service
$processes = Get-Process
$services   $processes | Measure-Object
$services   $processes | Measure-Object -Property DisplayName

# 4.测量CSV文件的内容
Import-Csv d:testserviceyrs.csv | Measure-Object -Property years -Minimum -Maximum -Average

# 5.测量布尔值
Get-ChildItem | Measure-Object -Property psiscontainer -Maximum -Sum -Minimum -Average

# 6.换行符`n将字符串分隔为单独的行用以下参数分别统计行、单词、字符数
"One`nTwo`nThree" | Measure-Object -Line -Word -Character
Lines Words Characters Property
----- ----- ---------- --------
    3     3         13

Compare-Object 命令 - 比较两组对象

描述: 比较前后两个时间段开启了那些进程,服务状态有什么变化,新增和减少了对象。

基础语法:

代码语言:javascript复制
# 语法
Compare-Object [-ReferenceObject] <System.Management.Automation.PSObject[]> [-DifferenceObject] <System.Management.Automation.PSObject[]> [-CaseSensitive] [-Culture <System.String>] [-ExcludeDifferent] [-IncludeEqual] [-PassThru] [-Property <System.Object[]>] [-SyncWindow <System.Int32>] [<CommonParameters>]

基础示例:

代码语言:javascript复制
# 1.比较不同时间段进程信息 (=>表示新增的对象, <=表示剔除的对象>)
PS > $before=Get-Process
PS > $after=get-process
PS > Compare-Object $before $after
PS > Compare-Object -ReferenceObject $before -DifferenceObject $after 
# InputObject                                   SideIndicator
# -----------                                   -------------
# System.Diagnostics.Process (YoudaoDict)       <=
# System.Diagnostics.Process (YoudaoDictHelper) <=
# System.Diagnostics.Process (YoudaoDictHelper) <=
# System.Diagnostics.Process (YoudaoEH)         <=
# System.Diagnostics.Process (YoudaoOcr)        <=
# System.Diagnostics.Process (YoudaoWSH)        <=


# 2.比较每个对象的属性变化,因为它有一个参数-property
PS > $svc1=Get-Service wsearch
PS > $svc1.stop()
PS > $svc2=Get-Service wsearch
PS > Compare-Object $svc1 $svc2 -Property Status,Name
# Status Name                       SideIndicator
# ------ ----                       -------------
# StartPending wsearch                    =>
# Running wsearch


# 3.比较文件的内容(显示不同的)
PS C:PowerShell> "Hellow
>> Power
>> Shell" >a.txt
>>
PS C:PowerShell> "Hollow
>> Shell
>> Linux" >b.txt
>>
PS C:PowerShell> Compare-Object (Get-Content .a.txt) (Get-Content .b.txt)
InputObject SideIndicator
----------  - -------------
Hollow       => 目标文件中不相同的行
Linux        =>
Hellow       <= 源文件中不相同的行

# 4.比较每一行内容并排除差异(即显示两边文件都有的)
$objects = @{
  ReferenceObject = (Get-Content -Path ./Testfile1.txt)
  DifferenceObject = (Get-Content -Path ./Testfile2.txt)
}
Compare-Object @objects -IncludeEqual -ExcludeDifferent
# InputObject SideIndicator
# ----------- -------------
# Weiyieek    ==
# 2           ==

# 5.使用PassThru参数时显示差异
$a = $True
Compare-Object -IncludeEqual $a $a -PassThru
(Compare-Object -IncludeEqual $a $a -PassThru) | Get-Member


# 6.使用属性比较两个简单对象
Compare-Object -ReferenceObject 'abc' -DifferenceObject 'xyz' -Property Length -IncludeEqual
  # Length SideIndicator
  # ------ -------------
  #       3 ==

# 7.比较实现IComparable的复杂对象
Compare-Object ([TimeSpan]"0:0:1") "0:0:1" -IncludeEqual
  # InputObject SideIndicator
  # ----------- -------------
  # 00:00:01    ==
  #  在第二种情况下,TimeSpan被转换成一个字符串这样对象就不同了。
Compare-Object "0:0:1" ([TimeSpan]"0:0:1")
  # InputObject SideIndicator
  # ----------- -------------
  # 00:00:01    =>
  # 0:0:1       <=

0 人点赞