[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 <=