欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PowerShell 入门2

程序员文章站 2022-03-09 12:16:43
...

更多请看(www.omob.cc
本文参考自Powershell快速入门(二) Shell编程
这部分介绍Powershell的程序基本语法知识,让我们能够编写功能强大的PowerShell脚本,完成具体的任务。

变量

变量使用$变量名创建和引用,取值为:$variable,赋值为:$variable=value

# 当前目录路径
PS D:\workspace\langs> pwd

Path
----
D:\workspace\langs

# 负责
PS D:\workspace\langs> $current=pwd
# 取值 返回值对象
PS D:\workspace\langs> $current

Path
----
D:\workspace\langs

# 取值的变量Drive得到当前路径所在的磁盘分区信息
PS D:\workspace\langs> $current.Drive

Name           Used (GB)     Free (GB) Provider      Root                                Cur
                                                                                         ren
                                                                                         tLo
                                                                                         cat
                                                                                         ion
----           ---------     --------- --------      ----                                ---
D                  69.72        861.79 FileSystem    D:\                                 ngs

# 取值的变量Drive得到当前路径的路径字符串
PS D:\workspace\langs> $current.Path
D:\workspace\langs

这里有一个命令Get-Member,别名是gm,用于获取对象的属性。比方说,我们将Get-Location命令的结果通过管道传递给Get-Member命令,就会显示下面的输出。如果不了解.NET的话,可能感觉比较陌生。上文的$current.Path就是和这个有关,取得是对象的属性

PS D:\workspace\langs> Get-Location|Get-Member


   TypeName:System.Management.Automation.PathInfo

Name         MemberType Definition
----         ---------- ----------
Equals       Method     bool Equals(System.Object obj)
GetHashCode  Method     int GetHashCode()
GetType      Method     type GetType()
ToString     Method     string ToString()
Drive        Property   System.Management.Automation.PSDriveInfo Drive {get;}
Path         Property   string Path {get;}
Provider     Property   System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath Property   string ProviderPath {get;}

我们还可以在变量上调用方法, 比如说将路径转换为全小写。

PS D:\workspace\langs> $current.Path.ToLower()
d:\workspace\langs

最后,如果不再需要一个变量,可以使用Remove-Variable删除变量,它的别名是rv。执行后销毁变量。

PS D:\workspace\langs> $current

Path
----
D:\workspace\langs


PS D:\workspace\langs> Remove-Variable current
PS D:\workspace\langs> $current

操作符

数学运算符

基本的数学运算符都是支持的,+-*/对应加减乘除。

PS D:\workspace\langs> $i=1
PS D:\workspace\langs> $j=2
PS D:\workspace\langs> $sum=$i+$j
PS D:\workspace\langs> $sum
3
PS D:\workspace\langs> $sub=$i-$j
PS D:\workspace\langs> $sub
-1
PS D:\workspace\langs> $multi=$i*$j
PS D:\workspace\langs> $multi
2
PS D:\workspace\langs> $div=$i/$j
PS D:\workspace\langs> $div
0.5

主流语言比如C/C++,JAVA,JavaScript支持的++,–也是可以的

PS D:\workspace\langs> $i=1
PS D:\workspace\langs> $i=$i++
PS D:\workspace\langs> $i
1
PS D:\workspace\langs> $i=++$i
PS D:\workspace\langs> $i
2
PS D:\workspace\langs> $i=$i--
PS D:\workspace\langs> $i=--$i
PS D:\workspace\langs> $i
1

比较运算符

比较运算符这些和Linux Shell中很相似,有大于(-gt),大于等于(-ge),小于(-lt),小于等于(-le),等于(-eq),不等于(-ne)几个。

PS D:\workspace\langs> $i
1
PS D:\workspace\langs> $j
2
PS D:\workspace\langs> $i -gt $j
False
PS D:\workspace\langs> $i -lt $j
True
PS D:\workspace\langs> $i -ge $j
False
PS D:\workspace\langs> $i -le $j
True
PS D:\workspace\langs> $i -eq $j
False

字符串匹配运算符

-like-notlike用于?*这样的通配符

PS D:\workspace\langs> 'hello' -like '?ello'
True
PS D:\workspace\langs> 'hello' -notlike '?ello'
False
PS D:\workspace\langs> 'hello' -like '*o'
True

-match-notmatch用于正则表达式

PS D:\workspace\langs> 'aabcc' -match 'a*b?c+'
True
PS D:\workspace\langs> 'aab' -match 'a*b?c+'
False

包含和替换运算符

-contains查找序列中是否包含某个元素。

PS D:\workspace\langs> 'hello','zhang3' -contains 'zhang3'
True

-replace用于替换字符串中某个部分,当然正则表达式也是支持的

PS D:\workspace\langs> 'hello zhang3' -replace 'zhang3','yitian'
hello yitian

上面这些运算符都是大小写不敏感的,如果需要大小写敏感的功能,可以在运算符前面添加c前缀

PS D:\workspace\langs> 'yitian' -match 'Yitian'
True
PS D:\workspace\langs> 'yitian' -cmatch 'Yitian'
False

逻辑运算符

逻辑运算符有与(-and)、或(-or)、非(-not!)以及异或(xor)几个,并且支持短路计算。

如果需要使用真值和假值字面量,可以使用$true$false

PS D:\workspace\langs> $true -and $false
False
PS D:\workspace\langs> $true -xor $false
True
PS D:\workspace\langs> $true -or $false
True
PS D:\workspace\langs> !$true
False
PS D:\workspace\langs> -not  $true
False

类型运算符

PS D:\workspace\langs> 3.14 -is [double]
True
PS D:\workspace\langs> 3.14 -is [float]
False

重定向运算符

首先是>>>运算符,用于将标准输出流重定向到文件,前者会覆盖已有文件,后者则是追加到已有文件末尾。

PS D:\workspace\langs> $true > a.txt
PS D:\workspace\langs> ls


    目录: D:\workspace\langs


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2018/7/14     11:27                c
d-----        2018/7/18     21:28                javascript
d-----        2018/7/14     11:27                nodejs
d-----        2018/7/18     21:28                scala
-a----        2018/7/18     23:31             14 a.txt
-a----        2018/7/14     11:26              7 README.md


PS D:\workspace\langs> cat .\a.txt
True
PS D:\workspace\langs> $false >> .\a.txt
PS D:\workspace\langs> cat .\a.txt
True
False
PS D:\workspace\langs> $1=1 >.\a.txt
PS D:\workspace\langs> cat .\a.txt
1

然后我们来说说日志级别,如果有使用过某些语言的日志框架的话,就很好理解了。在这里,2代表错误、3代表警告、4代表信息、5代表调试信息。n>和n>>运算符就是用于将对应级别的输出重定向到文件的,这两者的区别和前面相同。n>&1将对应级别的输出和标准输出一起重定向到文件。

# 标准输出
PS D:\workspace\langs> $true 1>.\b.txt
PS D:\workspace\langs> cat .\b.txt
True
# 无错误不输出
PS D:\workspace\langs> $true-1 2>> .\b.txt
0
PS D:\workspace\langs> cat .\b.txt
True
PS D:\workspace\langs> $true-1 1>> .\b.txt
PS D:\workspace\langs> cat .\b.txt
True
0

最后就是*>*>>了,这两者将所有输出信息重定向到文件。

PS D:\workspace\langs> $true+1 *>c.txt
PS D:\workspace\langs> cat .\c.txt
2

需要注意,PowerShell使用Unicode编码来输出信息。如果你需要使用其他类型的编码,就不能使用重定向运算符了,而应该使用Out-File命令。

特殊运算符

&运算符将它后面的命令设置为后台运行,当运行的命令需要阻塞当前终端的时候很有用

.\\运算符用于执行一个脚本或命令。如果执行的是PowerShell脚本,那么脚本会在自己的作用域中执行,也就是说在当前环境下无法访问被执行的脚本中的变量。

[]运算符用于转换变量的类型

PS D:\workspace\langs> [Float]$pi = 3.14
PS D:\workspace\langs> $pi -is [Float]
True

.运算符用于调用.NET对象的成员,它也可以用于执行脚本。当它用于执行脚本的时候,脚本会在当前作用域中执行。所以脚本结束之后,我们可以访问脚本中的元素。

::运算符用于调用类中的静态成员

下面就会调用.NET平台中DateTime类的Now属性

PS D:\workspace\langs> [DateTime]::Now

2018年7月18日 23:47:40

..运算符用于创建一个范围闭区间

PS D:\workspace\langs> 1..3
1
2
3
PS D:\workspace\langs> 3..1
3
2
1

-f运算符用于格式化数据

PS D:\workspace\langs> 'My name is {0}, I am {1} years old' -f 'powershell',24
My name is powershell, I am 24 years old

$运算符可以将字符串内部的变量转换为实际的值,即取值操作

PS D:\workspace\langs> $name='powershell'
PS D:\workspace\langs> $name
powershell

@()运算符用于将一系列值转换为一个数组

假如在脚本中有一个函数可能返回0、1或多个值,就可以使用这个操作符,将一系列值合并为一个数组,方便后续处理。

PS D:\workspace\langs> $name = @('microsoft','windows','powershell')
PS D:\workspace\langs> $name
microsoft
windows
powershell
PS D:\workspace\langs> $name[1]
windows

,逗号运算符如果放置在单个值前面,就会创建一个包含这个值的单元素数组。

PS D:\workspace\langs> $name=,'windows server'
PS D:\workspace\langs> $name[0]
windows server

条件判断

if else

$condition = $true

if ($condition -eq $true) {
    Write-Output "condition is $true"
}elseif ($condition -ne $true ) {
    Write-Output "condition is $false"
}else {
    Write-Output "other condition"
}

执行效果:

PS D:\workspace\langs> $condition = $true
PS D:\workspace\langs>
PS D:\workspace\langs> if ($condition -eq $true) {
>>     Write-Output "condition is $true"
>> }elseif ($condition -ne $true ) {
>>     Write-Output "condition is $false"
>> }else {
>>     Write-Output "other condition"
>> }

condition is True

switch

$n = 4
switch ($n) {
    1 {"n is 1"}
    2 {"n is 2"}
    3 {"n is 3"}
    default {"n is others"}
}

执行效果:

PS D:\workspace\langs> $n = 4
PS D:\workspace\langs> switch ($n) {
>>     1 {"n is 1"}
>>     2 {"n is 2"}
>>     3 {"n is 3"}
>>     default {"n is others"}
>> }
n is others

其实细说起来,这个switch的坑还是不少的。例如,switch语句可以接受多个值来测试,在switch语句中还可以编写多个case相同的语句。这里我就不细说了,想具体了解的话直接看官方文档 about_Switch吧。

循环语句

不管是哪种循环语句,在循环体内都可以使用break或continue中断/继续循环。

do

$i = 0
do {
    $i++
    Write-Output $i
}while ($i -ne 3)

执行效果:

PS D:\workspace\langs> $i = 0
PS D:\workspace\langs> do {
>>     $i++
>>     Write-Output $i
>> }while ($i -ne 3)
1
2
3

while

$i = 0
while ($i -lt 3) {
    Write-Output $i
    $i++
}

执行效果:

PS D:\workspace\langs> $i = 0
PS D:\workspace\langs> while ($i -lt 3) {
>>     Write-Output $i
>>     $i++
>> }
0
1
2

for

for ($i = 0; $i -ne 3; $i++) {
    Write-Output $i
}

执行效果:

PS D:\workspace\langs> for ($i = 0; $i -ne 3; $i++) {
>>     Write-Output $i
>> }
0
1
2

for-each

$array = @(1, 2, 3, 4)
foreach ($i in $array) {
    Write-Output $i
}

执行效果:

PS D:\workspace\langs> $array = @(1, 2, 3, 4)
PS D:\workspace\langs> foreach ($i in $array) {
>>     Write-Output $i
>> }
1
2
3
4

值得一提的是,for-each语句用在管道上时,还有以下一种用法。

<command> | foreach {<beginning command_block>}{<middle command_block>}{<ending command_block>}

使用这种方法时,for-each后面可以跟三个语句块,第一个语句块是开始语句块,在循环前执行一次,常用来初始化一些数据;第三个是结束语句块,在循环结束之后执行一次,常用于统计一些循环数据;第二个就是正常的循环语句块,会循环多次

函数

定义函数

定义函数使用function关键字,定义好函数之后,就可以使用函数名来调用函数了。

PS D:\workspace\langs> function hello {
>>     Write-Output 'Hello Powershell'
>> }
PS D:\workspace\langs> hello
Hello Powershell

函数的参数

函数当然也可以带参数了,参数列表有两种写法:第一种是C风格的,参数列表写在函数名后面,使用小括号分隔开;第二种方式是在方法体中,使用param关键字声明参数。这两种方法是完全等价的,当然我习惯上还是喜欢使用第一种方式。

Powershell是一种强类型的脚本语言,所以可以在参数列表上添加参数类型,参数类型是可选的,不过我还是推荐写的时候带上类型,方便阅读和类型检查。

function Say-Hello ([string] $name) {
    Write-Output "Hello, $name"
}

function Say-Hello2 {
    param([string] $name)
    Write-Output "Hello, $name"
}

执行效果:

PS D:\workspace\langs> function Say-Hello ([string] $name) {
>>     Write-Output "Hello, $name"
>> }
PS D:\workspace\langs> Say-Hello
Hello,
PS D:\workspace\langs> function Say-Hello2 {
>>     param([string] $name)
>>     Write-Output "Hello, $name"
>> }
PS D:\workspace\langs> Say-Hello2
Hello,
PS D:\workspace\langs> Say-Hello2('powershell')
Hello, powershell
PS D:\workspace\langs> Say-Hello('powershell')
Hello, powershell

这样也可以,调用带参数的函数时,需要向调用命令那样,使用-参数名来传递参数。

PS D:\workspace\langs> Say-Hello -name 'powershell'
Hello, powershell

默认参数

Powershell支持默认参数,直接用赋值号=在参数列表上指定参数默认值即可。

function Say-Hello3 {
    param([string] $name = 'zhang3')
    Write-Output "Hello, $name"
}

执行效果:

PS D:\workspace\langs> function Say-Hello3 {
>>     param([string] $name = 'zhang3')
>>     Write-Output "Hello, $name"
>> }
PS D:\workspace\langs> Say-Hello3
Hello, zhang3

开关参数

开关参数没有类型,作用仅仅是标志是或者否。如果在使用函数的时候带上开关参数,那么它就是开的状态,否则就是关的状态。开关参数需要指定参数类型为switch。

function Answer-Hello ([switch] $yes) {
    if ($yes) {
        Write-Output "Hi"
    }
}

然后在调用时就可以看出区别了。

Answer-Hello -yes
Answer-Hello

函数返回值

只要使用return语句就可以了

function Add ([double]$a, [double]$b) {
    $c = $a + $b
    return $c
}

然后我们调用函数,就可以看到结果

PS D:\workspace\langs> function Add ([double]$a, [double]$b) {
>>     $c = $a + $b
>>     return $c
>> }
PS D:\workspace\langs> Add -a 3 -b 5
8

关于Powershell编程的知识就介绍到这里,其实如果看看官方文档的话,就知道这里介绍的也仅仅是一部分而已。不过这一部分对于我们日常使用和学习基本上也够用了

如果要查看详细帮助的话,可以运行一下下面的命令,这样会显示所有和Powershell相关的帮助文档。

Get-Help about*

然后,就可以阅读自己感兴趣的部分了。比方说,如果我们想了解用Powershell编写类,就可以使用下面的命令。如果想在浏览器中浏览器在线版本,加上-online参数即可。

Get-Help about_Classes

相关标签: PowerShell