PowerShell笔记

本系列是一个重新学习PowerShell的笔记,内容引用自PowerShell中文博客

定义文本

文本中的特殊字符

如果文本放置在一个闭合的双引号中,Powershell解释器回去寻找特殊字符.在这方便主要有两种特殊字符,一个是变量的前缀$,一个是反引号`位于数字键1左边。

处理变量

将变量放在字符串中,输出时变量会被替换成变量本身的值或者内容。如果将表达式放置在字符串中,并且使用的格式如$(expression),表达式也会被执行,并被替换成表达式执行的输出。

PS C:PowerShell> "系统目录位于:$env:windir" 
系统目录位于:C:WINDOWS
PS C:PowerShell> "默认安装程序目录位于:$env:ProgramFiles"
默认安装程序目录位于:C:Program Files
PS C:PowerShell> "机器名为:$env:computername"
机器名为:CN2373092W2
PS C:PowerShell> "当前日期:$(get-date)"
当前日期:09/17/2021 15:47:30
PS C:PowerShell> "1GB=$(1gb/1kb)KB"                                                                                    1GB=1048576KB

Powershell转义字符

在其它编程语言中喜欢将反斜杠作为转义字符,但是在Powershell中扮演转义字符角色的不是反斜杠,而是反引号`字符串中的反引号,会对紧跟随其后的字符进行特殊处理。例如下面的,在一个字符串中输出双引号,和换行符。

PS C:PowerShell> #使用单引号闭合字符串输出双引号
PS C:PowerShell> 'The site of my blog is"www.mossfly.com"' 
The site of my blog is"www.mossfly.com"
PS C:PowerShell> #使用转义字符输出双引号      
PS C:PowerShell> "My blog site is`"www.mossfly.com`""  
My blog site is"www.mossfly.com"
PS C:PowerShell> #在字符串中输出换行符         
PS C:PowerShell> "The site of my blog is `"www.mossfly.com`",`n飞苔博客"
The site of my blog is "www.mossfly.com",
飞苔博客

Powershell转义字符表

转义字符 描述
[`n] 换行符
[`r] 回车符
[`t] 制表符
[`a] 响铃符
[`b] 退格符
[`’] 单引号
[`”] 双引号
[`0] Null
[``] 反引号本身

Here strings 定义多行文本

@"字符串"@格式定义多行文本,尤其是较长的文本,再好不过了

PS C:PowerShell> @"
>> 这首诗用来评价陶渊明的诗歌再好不过了
>>
>> 一语天然万古新,豪华落尽见真淳。
>> 南窗白日羲皇上,未害渊明是晋人。
>> "@                                                                                                                   这首诗用来评价陶渊明的诗歌再好不过了

一语天然万古新,豪华落尽见真淳。
南窗白日羲皇上,未害渊明是晋人。

这里要注意开始和结束的标记必须另起一行。

PS C:PowerShell> @"这首诗"@                                                                                            
At line:1 char:3
+ @"这首诗"@
+   ~
No characters are allowed after a here-string header but before the end of the line.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedCharactersAfterHereStringHeader

用户交互

如果要提示用户输入可以使用read-host

PS C:PowerShell>  $name=Read-Host "请输入您的用户名"                                                                   请输入您的用户名: hua hua
PS C:PowerShell> $Name                                                                                                 hua hua

只是有一点Read-Host存储的字符串使用的单引号闭合,也就是说不会自动解析变量,不过可以通过ExpandString方法解析,例如:

PS C:PowerShell>  $name=Read-Host "请输入您的用户名"                                                                   请输入您的用户名: hua hua
PS C:PowerShell> $Name                                                                                                 hua hua
PS C:PowerShell>  $inputPath=Read-Host "请输入文件路径"                                                                请输入文件路径: $env:windir
PS C:PowerShell> $inputPath                                                                                            $env:windir
PS C:PowerShell> $ExecutionContext.InvokeCommand.ExpandString($inputPath)                                              C:WINDOWS
PS C:PowerShell> $inputPath = $env:windir                                                                              PS C:PowerShell> $ExecutionContext.InvokeCommand.ExpandString($inputPath)                                              C:WINDOWS

但是如果想通过Read-Host接受敏感数据,比如密码,可以使用-asSecureString选项,不过这样读取到的数据为SecureString,及为加过密后的数据,当然你可以将密码转换成普通文本.

PS C:PowerShell>  $pwd=Read-Host -AsSecureString "请输入密码"                                                          请输入密码: ********
PS C:PowerShell> $pwd                                                                                                  System.Security.SecureString
PS C:PowerShell> [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd))                                                                                                               12345678

询问用户名和密码

如果你想授权一个用户需要提供用户凭据,可以使用Get-Credential命令,该命令会弹出一个安全对话框,一旦用户输入完毕,就会返回一个Credential对象包含用户名和密码

PS E:> $cre=Get-Credential MossserLee
PS E:> $cre
UserName                        Password
--------                        --------
MossserLee System.Security.SecureString

字符串操作符

格式化操作符 –F 在PowerShell文本操作符中非常重要,经常被用来增强数字类型和日期类型的可读性:

PS C:PowerShell> "{0} diskettes per CD" -f (720mb/1.44mb)  
500 diskettes per CD

-F 右边的表达式必选放在圆括号中,作为一个整体,先进行计算,然后在格式化。否则可能会解析错误:

PS C:PowerShell> "{0} diskettes per CD" -f 720mb/1.44mb
Cannot convert value "754974720 diskettes per CD" to type "System.Double". Error: "Input string was not in a correct fo
rmat."
At line:1 char:1
+ "{0} diskettes per CD" -f 720mb/1.44mb
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToDoubleOrSingle

可以在-F的左边放置多个字符串通配符,类似.NET中的String.Format方法。
-F右边相应的值或表达式也须要使用逗号分隔。

PS C:PowerShell> "{0} {3} at {2}MB fit into one CD at {1}MB" -f (720mb/1.44mb), 720, 1.44, "diskettes"  
500 diskettes at 1.44MB fit into one CD at 720MB

所有的基本操作符形式都大同小异,要处理的数据位于操作符的左右两边,然后通过操作符建立连接。
例如,你可以使用下面的语句将文本中指定的字符串替换成目标文本:

PS C:PowerShell> "Hello Carl" -replace "Carl", "Eddie"
Hello Eddie

-replace操作符有三种实现方式,其它文本操作符也类似地有三种实现方式,像-replace-ireplace-creplacei前缀表示字符串大小写不敏感(insensitive),c前缀表示字符串大小写敏感(case sensitive)。
下面的例子没有完成替换,因为当前大小写敏感:

PS C:PowerShell> "Hello Carl" -creplace "carl", "eddie" 
Hello Carl

第三类i前缀,表示大小写不敏感,和没有前缀的命令逻辑一样(PowerShell中默认的字符串比较是不区分大小写的,所以这里保持一致)。
字符串操作符

操作符 描述 示例
* 代表一个字符串 “PsTips” -like “*”
+ 合并两个字符串 “Power” + “Shell”
-replace,-ireplace 替换字符串,大小写不敏感 “PsTips” -replace “tip”,”1″
-creplace 替换字符串,大小写敏感 “PsTips” -replace “Tip”,”1″
-eq, -ieq 验证是否相等,大小写不敏感 “Power” -eq “power”
-ceq 验证是否相等,大小写敏感 “Power” -eq “Power”
-like, -ilike 验证字符串包含关系,允许模式匹配,大小写不敏感 “PsTips” -like “p*”
-clike 验证字符串包含关系,允许模式匹配,大小写敏感 “PsTips” – clike “P*”
-notlike,-inotlike 验证字符串不包含关系,允许模式匹配,大小写不敏感 “PowerShell” -notlike “PS*”
-cnotlike 验证字符串不包含关系,允许模式匹配,大小写敏感 “PowerShell” -cnotlike “PO*”
-match,-imatch 验证模式匹配,大小写不敏感 “PowerShell” -match “P*”
-cmatch 验证模式匹配,大小写敏感 “Hello” -match “[ao]”
-notmatch,-inotmatch 验证模式不匹配,大小写不敏感 “Hello” -notmatch “[ao]”
-cnotmatch 验证模式不匹配,大小写敏感 “Hello” -cnotmatch “[ao]”

设置数值格式

格式化操作符 -f 可以将数值插入到字符串,每一个通配符都有统一的结构。

{index[,alignment][:format]}:

  • Index:
    索引编号用来识别把那个值用来替换通配符。例如你可能使用了多个通配符,或者同一个通配符使用了多次,甚至多种格式。此时,索引编号是唯一能够识别那个值将用来替换。另外两个选项Alignment和Format则作为辅助条件。

  • Alignment:
    正数和负数,可以指定目标值是否左对齐或者右对齐。还可以支持数值以指定的宽度显示,如果数值的实际宽度大于指定宽度,则忽略指定宽度。如果数值宽度小于指定宽度,剩余的部分会以空白填充,这一选项非常利于制表。

  • Format:
    数值可以被格式化成许多不同的类型,下面会预览这些你可能会用到一些格式概要。

格式化语句比较特殊,大小写敏感,这和PowerShell中其它语句的使用稍有不同。下面举个例子:

$date = Get-Date
$formatArr = "d", "D", "f", "F", "g", "G", "m", "r", "s", "t", "T", "u", "U", "y", "dddd, MMMM dd yyyy", "M/yy", "dd-MM-yy"
Foreach ($format in $formatArr) {
	"PowerShell 日期格式, 使用 $format : {0}" -f $date.ToString($format) 
}

PS C:PowerShell> test.ps1                                                                            PowerShell 日期格式, 使用 d : 2021/9/17
PowerShell 日期格式, 使用 D : 2021年9月17日
PowerShell 日期格式, 使用 f : 2021年9月17日 16:52
PowerShell 日期格式, 使用 F : 2021年9月17日 16:52:33
PowerShell 日期格式, 使用 g : 2021/9/17 16:52
PowerShell 日期格式, 使用 G : 2021/9/17 16:52:33
PowerShell 日期格式, 使用 m : 9月17日
PowerShell 日期格式, 使用 r : Fri, 17 Sep 2021 16:52:33 GMT
PowerShell 日期格式, 使用 s : 2021-09-17T16:52:33
PowerShell 日期格式, 使用 t : 16:52
PowerShell 日期格式, 使用 T : 16:52:33
PowerShell 日期格式, 使用 u : 2021-09-17 16:52:33Z
PowerShell 日期格式, 使用 U : 2021年9月17日 8:52:33
PowerShell 日期格式, 使用 y : 2021年9月
PowerShell 日期格式, 使用 dddd, MMMM dd yyyy : 星期五, 九月 17 2021
PowerShell 日期格式, 使用 M/yy : 9/21
PowerShell 日期格式, 使用 dd-MM-yy : 17-09-21

如果你想找出那些类型支持被格式化选项,只须查找.NET中那些类型支持多余的ToString()方法.

[appdomain]::currentdomain.getassemblies() | ForEach-Object {
	$_.GetExportedTypes() | Where-Object { ! $_.IsSubclassof([System.Enum]) }
} | ForEach-Object {
	$Methods = $_.GetMethods() | Where-Object { $_.name -eq "tostring" } | ForEach-Object { "$_" };
	If ($methods -eq "System.String ToString(System.String)") {
		$_.fullname
	}
}

PS C:PowerShell> test.ps1 
System.DateTime
System.DateTimeOffset
System.Byte
System.Convert
System.Decimal
System.Double

例如,其中的数据类型 ”全球唯一标示符”:

System.Guid

因为你会经常使用到它,它是全球通用的,下面会给你一个简单的例子来创建GUID。

$guid = [GUID]::NewGUID()
Foreach ($format in "N", "D", "B", "P") {
	"GUID with $format : {0}" -f $GUID.ToString($format)
}

PS C:PowerShell> test.ps1
GUID with N : ee4afcc59e044f1e80cd0fa3b6b0b188
GUID with D : ee4afcc5-9e04-4f1e-80cd-0fa3b6b0b188
GUID with B : {ee4afcc5-9e04-4f1e-80cd-0fa3b6b0b188}
GUID with P : (ee4afcc5-9e04-4f1e-80cd-0fa3b6b0b188)

固定宽度的制表输出

在一个固定宽度和对齐格式中,显示输出多行文本,要求每一列的输出必选具有固定的宽度。格式化操作符可以设置固定宽度输出。

下面的例子通过DIR返回个目录的中的文件列表,然后通过循环输出,文件名和文件大小,因为文件的名字和大小都是不确定的,长度不一样,所以结果拥挤粗糙,可读性差。

PS C:PowerShell> dir | ForEach-Object { "$($_.name) = $($_.Length) Bytes" }  
Error.txt = 812 Bytes
pipeline.ps1 = 397 Bytes
test.exe = 0 Bytes
test.ps1 = 36 Bytes
test.txt = 58 Bytes

下面固定列宽的结果,就显得可读性强了。
要设置列宽可以将一个逗号放置在通配符与列宽编号的中间,负数设置右对齐,正数设置左对齐。

PS C:PowerShell> dir | ForEach-Object { "{0,-20} = {1,10} Bytes" -f $_.name, $_.Length }  
Error.txt            =        812 Bytes
pipeline.ps1         =        397 Bytes
test.exe             =          0 Bytes
test.ps1             =         36 Bytes
test.txt             =         58 Bytes

简单模式识别

在验证用户的条目时,模式识别是必要并且常见的任务。例如判断用户的输入的字符串是否是一个合法的网络IP地址,或者电子邮箱。有用并且高效的模式匹配需要一些能代表确切数字和字符的通配符。

许多年前,人们就发明了简单的模式匹配,一直沿用至今。

#列出当前目录中的文本文件
Dir *.txt
# 列出系统目录中以‘n’或‘w’打头的文件
dir $env:windir[nw]*.*
# 列出文件后缀名以‘t’打头,并且后缀名只有三个字符的文件
Dir *.t??
# 列出文件中包含一个’e’到’z’之间任意字符的文件
dir *[e-z].*

上面表格中的通配符主要被使用在文件系统中,但是在字符串操作符-like和-notlike 中也可以。例如通过下面的方式可以简单验证IP地址。

$ip = Read-Host "IP address"
If ($ip -like "*.*.*.*") { "valid" } Else { "invalid" }

也可以简单验证电子邮件地址。

$email = ".@."
$email -like "*.*@*.*"

然而上面的例子也仅能验证一些低级错误,还不是很确切。例如a.b.c.d不是一个有效的IP地址,但是上面的模式匹配却能通过验证。

原文地址:https://www.cnblogs.com/MerLin-LiuNian/p/15307541.html