[TOC]

0x00 PS字符串内容分隔识别校验

替换 - Replace

描述: PowerShell 文本替换方式演示巧妙用法参考。

  • .Replace(“原字符串”,”新字符串”)
  • -Replace “原字符串(支持正则)”,”新字符串”
  • -Creplace “原字符串(支持正则且大小写敏感)”,”新字符串”

基础示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# - 1.字符串"Hello WeiyiGeek"将这个字符串的Hello替换为Hi。(注意默认不是大小写敏感的)
"Hello WeiyiGeek".Replace("Hello","Hi") # 结果: Hi WeiyiGeek
"Hello WeiyiGeek".Replace("hello","Hi") # 结果: Hi WeiyiGeek

# - 2.将字符串中特殊字符利用正则表达式进行替换。(注意采用得形式)
"He,.l^lo Weiy'./iGeek" -Replace '\W','' # 结果: HelloWeiyiGeek
"Hi WeiyiGeek" -Replace '(.*) (.*)','$2 $1' # 结果: WeiyiGeek Hi (利用元组进行替换)

# - 3.采用-Replace形式时不进行正则表达式解析匹配
"[Hello] WeiyiGeek" -Replace '\[Hello\]','Hi' # 结果: Hi WeiyiGeek
"[Hello] WeiyiGeek" -Replace ([Regex]::Escape("[Hello]")),"Hi" # 结果: Hi WeiyiGeek

# - 4.该操作符默认是大小写敏感的,即只能完全大小匹配使进行替换
"[Hello] WeiyiGeek" -creplace 'hello','Hi' # 结果: [Hello] WeiyiGeek
"[Hello] WeiyiGeek" -creplace 'Hello','Hi' # 结果: [Hi] WeiyiGeek
"[Hello] WeiyiGeek" -creplace ([Regex]::Escape("[hello]")),"Hi"


实践案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -1.我想从字符串中搜索具有特定格式的数字并使用powershell将最后一个数字增加1,该字符串取自大型txt文件。
$str = "Android version 4.4.2, Alfa = 1.2.0400, Beta = 2.0.0200, Prod 3.4.0104" # 我想将beta版本增加1(2.0.0200==> 2.0.0201)运行powershell命令后:$str = "Android version 4.4.2, Alfa = 1.2.0400, Beta = 2.0.0201, Prod 3.4.0104"

# 方式1
if($str -match "(?<=Beta = \d+\.\d+\.)(?<bv>\d+)"){
$str -replace "(?<=Beta = \d+\.\d+\.)(\d+)", ("{0:0000}" -f (([int]::Parse($matches.bv)+1)))
}
# 方式2: 注意此处没有++运算符是因为其运算符仅适用于数字,而非字符串.
[regex]::Replace($str, '(?<Head>.+\.)(?<Beta>\d+)(?<Tail>,[^,]+)$',
{ param( [System.Text.RegularExpressions.Match]$m )
$bv = 1 + $m.Groups['Beta'].Value
'{0}{1:0000}{2}' -f $m.Groups['Head'].Value,$bv,$m.Groups['Tail'].Value
}
)

Tips : 非常注意Replace中得[Regex]类里面有个Escape静态方法非常方便我们进行禁用正则解析。


匹配 - Match

描述: PowerShell 文本匹配方式演示巧妙用法参考。

  • match 运算符: 通过 $Matches来获取字段。
  • matches 方法: 通过该方法获取字段。

基础示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# - 1.基础字符串匹配显示match
PS > "[Hello] WeiyiGeek" -match '(?<name>(W\w.+k$))' # True
PS > $Matches.name # WeiyiGeek

# - 2.采用matches方法进行多次匹配邮箱格式
$txt='WeiyiGeek Email <[email protected]>;
test <[email protected]>;
demo <[email protected]>;'
[regex]::matches($txt, '<(.+)>;') | %{$_.Groups[1].Value}
# [email protected]
# [email protected]
# [email protected]

# - 3.网页指定正则表达式匹配到得字符串获取
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$ true }
$WebClient=New-Object System.Net.WebClient
$url="https://www.weiyigeek.top"
$WebClient.DownloadString($url) -match '(?<name>(W\w.+k))'|out-null # 网站字符串
$Matches.name # WeiyiGeek

$WebClient.DownloadString("http://ident.me/") -match '(?<ip>(\d+\.){3}\d+)'|out-null # 外网地址
$Matches.ip # 120.17.50.229


0x03 内存字符串处理

Select-String 命令 - 在字符串和文件中查找文本

描述:可以按照字符串以及属性进行过滤显示通过管道符;

基础语法:

1
2
# 语法
Select-String [-Pattern] <System.String[]> [-AllMatches] [-CaseSensitive] [-Context <System.Int32[]>] [-Encoding {ASCII | BigEndianUnicode | Default | OEM | Unicode | UTF7 | UTF8 | UTF32}] [-Exclude <System.String[]>] [-Include <System.String[]>] -InputObject <System.Management.Automation.PSObject> [-List] [-NotMatch] [-Quiet] [-SimpleMatch] [<CommonParameters>]

基础示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 1.过滤选择显示特定的字符串
PS > ipconfig | Select-String "IPv6"
# 本地链接 IPv6 地址. . . . . . . . : fe80::d97d:fe6c:10bf:4244%15
# 本地链接 IPv6 地址. . . . . . . . : fe80::34d5:4b52:1627:64dc%14
# 本地链接 IPv6 地址. . . . . . . . : fe80::50fc:1560:33a5:b73f%5
ipconfig | Select-String "以太网"
# 以太网适配器 以太网:
# 以太网适配器 VMware Network Adapter VMnet1:
# 以太网适配器 VMware Network Adapter VMnet8:

# 2.查找区分大小写的匹配项(默认不区分大小写)
# SimpleMatch是一个可选参数,指定模式中的字符串不被解释为正则表达式。
'Hello', 'HELLO' | Select-String -Pattern 'HELLO' -CaseSensitive -SimpleMatch
HELLO

# 3.在文本文件中查找匹配项(简单通配符|正则匹配)
Get-Alias | Out-File -FilePath .\Alias.txt
Get-Command | Out-File -FilePath .\Command.txt

# Simple Match
Select-String -Path .\*.txt -Pattern 'Get-' -SimpleMatch
# Alias.txt:8:Alias cat -> Get-Content
# Alias.txt:28:Alias dir -> Get-ChildItem
# Alias.txt:43:Alias gal -> Get-Alias
# Command.txt:966:Cmdlet Get-Acl
# Command.txt:967:Cmdlet Get-Alias

# Find a pattern match
Select-String .\Testfile1.txt -Pattern "Weiy|3"
# Testfile1.txt:1:Weiyieek
# Testfile1.txt:4:3
Select-String -Path "$PSHOME\en-US\*.txt" -Pattern '\?'
# C:\Program Files\PowerShell\6\en-US\default.help.txt:27: beginning at https://go.microsoft.com/fwlink/?LinkID=108518.
# C:\Program Files\PowerShell\6\en-US\default.help.txt:50: or go to: https://go.microsoft.com/fwlink/?LinkID=210614


# 4.在函数中使用Select字符串
PS> Function Search-Help
>> {
>> $PSHelp = "$PSHOME\en-US\*.txt"
>> Select-String -Path $PSHelp -Pattern 'About_'
>> }

PS> Search-Help
C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_ActivityCommonParameters.help.txt:2: about_ActivityCommonParameters
C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_ActivityCommonParameters.help.txt:31: see about_WorkflowCommonParameters.
C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_ActivityCommonParameters.help.txt:33: about_CommonParameters.


# 5.在Windows事件日志中搜索字符串
$Events = (Get-WinEvent -LogName Application -MaxEvents 50)
$Events | Select-String -InputObject {$_.message} -Pattern '错误'
# “C:\Program Files (x86)\Google\Update\GoogleUpdate.exe”的激活上下文生成失败。在指令清单或策略文件“C:\Program Files (x86)\Google\Update\GoogleUpdate.exe”的第 0 行出现错误。 无效的 Xml 语法。


# 6.在子目录中查找字符串 (常用)
Get-ChildItem -Path C:\Windows\System32\*.txt -Recurse | Select-String -Pattern 'Microsoft' -CaseSensitive


# 7.查找与模式不匹配的字符串
Get-Command | Out-File -FilePath .\Command.txt
Select-String -Path .\Command.txt -Pattern 'Get', 'Set' -NotMatch

# 8.查找匹配前后的行
Get-Command | Out-File -FilePath .\Command.txt
# Context参数使用两个值before和after并用尖括号(`>`)标记输出中的模式匹配。Context参数输出第一个模式匹配之前的两行和之后的三行最后的模式匹配。
Select-String -Path .\Command.txt -Pattern 'Get-Computer' -Context 2, 3


# 9.查找所有模式匹配
PS> $A = Get-ChildItem -Path "$PSHOME\en-US\*.txt" | Select-String -Pattern 'PowerShell'
PS> $A
# C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_ActivityCommonParameters.help.txt:5: Describes the parameters that Windows PowerShell
# C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_ActivityCommonParameters.help.txt:9: Windows PowerShell Workflow adds the activity common
PS> $A.Matches
# Groups : {0}
# Success : True
# Name : 0
# Captures : {0}
# Index : 4
# Length : 10
# Value : PowerShell
PS> $A.Matches.Length
# 2073
PS> $B = Get-ChildItem -Path "$PSHOME\en-US\*.txt" | Select-String -Pattern 'PowerShell' -AllMatches
PS> $B.Matches.Length
# 2200
# 长度属性增加,因为对于每一行,模式PowerShell的每一次出现都会被计数。


# 10.从文本文件中获取前几行或者后几行
echo "ServerId = VMlinux-b71655e1
DatabaseId = db-ecb2e784
Status = completed
LocationId = 344067960796
DatabaseSize = 30

ServerId = VMlinux-0db8d45b
DatabaseId = db-cea2f7a6
Status = completed
LocationId = 344067960796
DatabaseSize = 35

ServerId = VMlinux-c5388693
DatabaseId = db-9a421bf2
Status = completed
LocationId = 344067960796
DatabaseSize = 8

etc" > result.txt
# 此处获取匹配得字符串上方得前三行
(gc result.txt | Select-String 'DatabaseSize = 35' -Context 3).context.precontext
# DatabaseId = db-cea2f7a6
# Status = completed
# LocationId = 344067960796
# 此处获取匹配得字符串下方得后三行
(gc result.txt | Select-String 'DatabaseSize = 35' -Context 3).context.precontext
#
# ServerId = VMlinux-c5388693
# DatabaseId = db-9a421bf2

PowerShell 文本处理实例(三) 4

原始文本:”data1″:111,”data2″:22,”data3″:3,”data4″:4444444,”data5″:589

要求:转换成对象

1
2
3
4
5
$rawTxt='"data1":111,"data2":22,"data3":3,"data4":4444444'
$rawTxt -split ',' | ForEach-Object {
$temp= $_ -split ':'
"{0}={1}" -f $temp[0].Substring(1,$temp[0].Length-2),$temp[1]
} | ConvertFrom-StringData

结果:
1
2
3
4
5
6
Name                           Value
---- -----
data1 111
data2 22
data3 3
data4 4444444

XML节点选择:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#$xml = [xml](Get-Content "c:\folder\app.config") 
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="IIS_VERSION" value="8" />
<add key="somekey" value="somevalue" />
</appSettings>
</configuration>
"@

$IISVersion = $xml.SelectSingleNode("//add[@key='IIS_VERSION']")

if ($IISVersion.Value -eq 7)
{
Write-Host "IIS's version is already 7"
}
else
{
Write-Host "Update IIS version to 7"
$IISVersion.Value = "7"
}

$xml.Save("c:\folder\app.config")