文章目录
- 介绍
- 输入输出
- 使用正则表达式解析文本文件
-
- 正则表达式入门
- 通过-Match和Select-String使用正则表达式
- 额外的提示,技巧以及技术
-
- PowerShell Profile脚本、自定义提示及颜色调整
- 运算符:-AS、-IS、-Replace、-Join、-Split、-IN、-Contains
- 字符串处理
- 日期处理
- 设置参数默认值
- 学习脚本块
- 总结
介绍
输入输出
Read-Host "Enter a computer name" Enter a computer name:SERVER-R2 # 输出 # SERVER-R2
该示例突出了
- 提示信息的最后添加了冒号
- 用户键入的任何信息都会作为该
Cmdlet 的返回结果
既然你可以收集输入信息,那么也会希望了解一些展示返回结果的方法。
Write-Host "COLORFUL!" -Fore Yellow -Back Magenta
在针对脚本或者命令来产生常规输出结果而言,这个不是一个好的方法。而对于手动格式化的输出,更不是一个好的选择。再比如,针对产生错误信息、警告信息、调试信息等而言,这也不是一个好的方法,只有当需要展示一个特定的信息,比如使用其他颜色来吸引人们的注意力。
与
Write-Output "Hello" | Where-Object { $_.Lenght -GT 10 } Write-Host "Hello" | Where-Object { $_.Lenght -GT 10 }
上面的示例的第一个命令,你不会看到任何结果,因为通过
Cmdlet | 作用 | 配置变量 |
---|---|---|
Write-Warning | 显示警告信息,默认会以黄色字体显示,同时前面带有“警告:”字样 | $WarningPreference(默认Conitinue) |
Write-Verbose | 显示详细信息,默认会以黄色字体显示,同时前面带有“详细信息:”字样 | $VerbosePreference(默认SilentlyConitinue) |
Write-Debug | 显示调试信息,默认会以黄色字体显示,同时前面带有“调试:”字样 | $DebugPreference(默认SilentlyConitinue) |
Write-Error | 产生一个错误信息 | $ErroActionPreference(默认Conitinue) |
注意:PowerShell v5中添加了一个新的命令:Write-Information
使用正则表达式解析文本文件
正则表达式入门
最简单的正则表达式就是你所期望匹配的文本字符串。
w 用于匹配“文本字符”,也就是字母、数字以及下划线,但不含标点符号和空格。正则表达式 “won ” 可以匹配"Don "、“Ron "以及"ton ”,w 可以代表任意字母、数字或下划线W 和w 相反,意思是它将会匹配空格于标点符号——也就是“非字母”d 用于匹配包括0 到9 的任意数字D 用于匹配任意非数字s 用于匹配任意空格字符,比如Tab 、空格或者回车等S 用于匹配任意非空格字符. (句号)代表任意单个字符[abcde] 用于匹配在该集合中任意字符。正则表达式d[aeiou]n 可以匹配"Don "、“Dan ”,但是不会匹配"Doun "或"Deen "[a-z] 匹配在此范围内的一个或多个字符,可以使用逗号分隔列表指定多个范围,比如[a-f,m-z] [^abcde] 用于匹配不在该集合中的一个或多个字符,意味着正则表达式d[^aeiou] 可以与"dns "匹配,但无法与"don "匹配- 将
? 置于另一个字符或特殊符号后,可以用于匹配该字符的一个实例。所以正则表达式"do?n "可以匹配"don ",但不会匹配"doon "。该正则表达式还可以匹配"dn ",这是由于? 还可以代表空实例 * 用于匹配该符号之前任意数量的实例。正则表达式"do*n "将会和"doon "和"don "匹配。该正则表达式还可以与"dn "匹配,这是由于* 还可以代表空实例+ 用于匹配该符号之前任意数量的实例。你会经常看到该字符和括号一起使用,从而创建了一种子表达式。举例来说,正则表达式"(dn)+o "可以与"dndndndno "匹配,这是由于该正则表达式可以重复匹配子表达式"dn "(反斜杠)是正则表达式转义字符。 {2} 用于匹配该字符之前特定数量的实例。比如,d{1} 用于匹配1 个数字,使用{2,} 匹配2 或多个 数字,使用{1,3} 匹配至少1 个但不超过3 个实例^ 用于匹配字符串开始部分。比如,正则表达式"d.n "既可以匹配"don ",又可以匹配"pteranodon "。而正则表达式"^d.n "只能匹配"don ",而无法匹配"pteranodon "。这是由于^ 使得匹配只能从字符串开始部分匹配,而^ 和[] 共同使用时表达式匹配的反义$ 用于匹配字符串结尾部分。比如,正则表达式".icks "既可以与"hicks "匹配,也可以与"sticks "(本例中匹配的其实是"ticks ")匹配,还可以与"Dickson "匹配。但正则表达式.icks$ 无法与"Dickson "匹配,这是因为$ 表示字符"s "应该是该字符串的最后一个字符
正则表达式还有大量内容,但是这些内容足够你完成基本工作。让我们来看一些正则表达式的例子。
d{1,3}.d{1,3}.d{1,3}.d{1,3} 可以匹配IPv4 地址的模式,但该表达式可以接收“432.567.879.000 ”这样的非法地址,也可以接收“192.168.23.24 ”这样的合法地址\\w+(\w+)+ 可以匹配通用命名惯例(UNC )路径。大量的反斜杠使得该正则表达式难以阅读,这也是为什么在将正则表达式部署到生产环境之前对正则表达式进行调试和调整w{1}[email protected] 可以匹配特定类型的电子邮件地址:首先是要给字母,然后句号,最后是@company.com 。比如[email protected] 可以与该正则表达式进行匹配,[email protected] 也能匹配。该正则表达式允许匹配文本的开始或结尾存在额外的字符,所以可以考虑使用^ 或$
通过-Match和Select-String使用正则表达式
"don" -match "d[aeiou]n" # 结果:True "dooon" -match "d[aeiou]n" # 结果:False "dooon" -match "d[aeiou]+n" # 结果:True "djjnn" -match "d[aeiou]+n" # 结果:False "dean" -match "d[aeiou]n" # 结果:False
虽然使用正则表达式的方法很多,但我们主要依靠
接下来我们看一个例子,从
Get-ChildItem -Filter *.log -Recurse | Select-String -Pattern "s40[0-9]s" | Format-Table FileName,LineNumber,Line -Wrap
该示例递归查找当前文件夹下所有以
接下来看一个
Get-EventLog -LogName Security | Where-Object { $_.EventId -EQ 4624 } | Select-Object -ExpandProperty Message | Select-String -Pattern "WIN[Ww]+TM[234][0-9]$" Get-EventLog -LogName Security | Where-Object { $_.EventId -EQ 4624 -And $_.Message -Match "WIN[Ww]+TM[234][0-9]$" }
第一个命令输出符合要求的字符串,即
额外的提示,技巧以及技术
PowerShell Profile脚本、自定义提示及颜色调整
在
(1) $PsHome/Profile.PS1——不管使用任何托管应用程序,计算机上的所有用户都会执行该脚本
(2) $PsHome/Microsoft.PowerShell_Profile.PS1——如果该计算机上的用户使用了控制台宿主,那么就会执行该脚本。如果他们使用的是
(3) $Home/Documents/WindowsPowerShell/Profile.PS1——无论用户使用的是何种托管应用程序, 只有当前用户会执行该脚本(因为该脚本存在于用户的根目录下)
(4) $Home/Documents/WindowsPowerShell/Microsoft.PowerShell_Profile.PS1——只有当前使用
如果上面的脚本中其中一个或几个不存在,那么也没有关系。托管程序会跳过不存在的脚本,继续寻找下一个脚本。
Fuction Prompt { $(IF (test-Path Variable:/PSDebugContent) { '[DBG]:' } ELSE { '' }) + 'PS' + $(Get-Location) ` + $(IF ($NestedPromptLevel -GE 1) { '>>' }) + '>' }
我们可以自定义一个函数,将其写入到任意
Funciton Prompt { $Time = (Get-Date).ToShortTimeString() "$Time [$ENV:COMPUTERNAME]:> " }
至于各种提示信息字体颜色等的调整,我们更建议使用属性中的【颜色】标签,在其中进行可视化的操作。
运算符:-AS、-IS、-Replace、-Join、-Split、-IN、-Contains
1000 / 3 -AS [int]
中括号中包含转换之后的类型,这些类型还可以是
123.354 IS [INT] "SERTSD" -IS [String] $True -IS [Bool] (Get-Date) -IS [DateTime]
"192.168.34.12" -Replace "34","15" # 结果:192.168.15.12
$Array ="One","Two","Three","Four","Five" $Array -Join "|" # 输出: One|Two|Three|Four|Five $Array = (Get-Content Computers.tdf) -Split "`t" # 输出: # server2 # Windows # East # Managed
'this' -Like '*his*' $Collection = 'abc','def','fhi','jkl' $Collection -Contains 'abc' # True $Collection -Contains 'xzy' # False
$Collection = 'abc','def','fhi','jkl' 'abc' -IN $Collection # True 'xyz' -IN $Collection # False
字符串处理
在
- IndexOf() 会返回特定字符在字符串中的位置。
"Server-R2".IndexOf("-") # 6
- Splite()、Join() 和 Replace() 类似上面讲的
-Splite 、-Join 和-Replace 。我们更倾向于使用与算法而不是字符串方法 - ToLower() 和 ToUpper() 可将字符串转换为小写或大写
$computername = "SERVER-R2" $computername.ToLower() # server-r2
- Trim() 会将一个字符串的前后空格去掉;TrimStart() 和 TrimEnd() 会将一个字符串的前面或后面的空格去掉
$UserName = " Don" $UserName.Trim() # Don
日期处理
通过上面列表中的属性,可以访问一个
$Today = Get-Date $Today.Month $90DayAgo = $Today.AddDays(-90) $90DayAgo $90DayAgo.ToShortDateString()
而在
Get-WMIObject Win32_OperatingSystem | Select-Object LastBootUpTime # 结果 # LastBootUpTime # ---------------- # 20150317090459.125599+480
$OS = Get-WMIObject Win32_OperatingSystem $OS.ConvertToDateTime($OS.LastBootUpTime)
设置参数默认值
大多数
例如,你希望创建一个包含用户名和密码的凭据对象,然后将该对象设置为所有对象中
# 第一个 $Credential = Get-Credential -UserName Administrator -Message "Enter Admin Credential" $PSDefaultParameterValues.Add('*:Credential',$Credential) # 第二个 $PSDefaultParameterValues.Add('Invoke-Command:Credential',{ Get-Credential -Message 'Enter Administrator Credential' -UserName Administrator }) # 查看变量内容 $PSDefaultParameterValues
可以看到该
学习脚本块
脚本是
Where-Object 命令的-FilterScript 参数会使用脚本块ForEach-Object 命令的-Process 参数会使用脚本块- 使用
Select-Object 创建自定义属性的哈希表或者使用Format-Table 创建自定义列的哈希表,都会需要一个脚本块作为E 或者Expression 的键值 - 参数的默认值也可以是一个脚本块
- 针对一些远程处理以及
Job 相关命令,比如Invoke-Command 和Start-Job 命令,也需要一个脚本块作为-ScriptBlock 参数的值
简单的说,脚本块是指包含在大括号中的全部命令——哈希表除外(哈希表在大括号之前会带有
$Block = { Get-Process | Sort-Object -Property Vm -Descending | Select-Object -First 10 } &$Block
最后,我们来说下使用他人的脚本所采用的方式——逐行检查。当你逐行查阅每一行时,完成下面的工作。
- 识别其中的变量,并找出其对应的值,之后将它们写在一张纸上。因为大部分情况下,变量都会被传递给某些命令,所以记下每个变量可能的值会帮助你预测每个命令的作用
- 当你遇到一些新的命令时,请阅读对应的帮助文档,这样可以理解这些命令的功能。针对
Get- 类型的命令,尝试运行它们——将脚本中变量的值传递给命令的参数——来查看这些命令的输出结果 - 当你遇到不熟悉的部分时,比如
[Environment] ,请考虑在虚拟机中执行简短的代码片段来查看该片段的功能(使用虚拟机有助于保护你的生产环境)。可以通过在帮助文档中搜寻(使用通配符)这些关键字来查阅更多的信息
总结
以上是对