[TOC]

PS 数组和哈希表

描述:数组引入PS会将命令执行后的结果文本按每一行作为元素存为数组,在命令的返回值不止一个结果时,PS也会自动把结果存储为数组。

  • 数组的多态:PS中数组像变量一样如果数组中元素的类型为弱类型,默认可以存储不同类型的值。
  • PS数组在内存中是顺序存储的,所以数组的大小必须是确定的方便分配存储空间
  • 数组属于引用类型,使用默认的的赋值运算符在两个变量之间赋值只是复制了一个引用两个变量共享同一份数据,则改变一个另一个也会相应的改变;
常规PS数组

基础示例:

#1.PS将命令执行后返回的结果存入到数组之中
PS > $IP=IPCONFIG
PS > $IP -is [array]
True

PS > $IP.getType()
# IsPublic IsSerial Name BaseType
# -------- -------- ---- --------
# True True Object[] System.Array

PS > $IP.Count #看数组的元素个数用$array.Count属性
32

#访问第x个元素,使用$array[x-1],因为数组是以0开始索引的。
PS > $IP[4]
#以太网适配器 以太网:
PS > $IP[8]
# IPv4 地址 . . . . . . . . . . . . : 10.0.0.19

思考为什么不愿把IPconfig返回的结果称为对象?
答:因为它不是真正Cmdlet命令,真正的Powershell命令返回的数组元素可不止一个字符串,它是一个内容丰富的对象。


1.数组创建

  • 使用@()创建数组
  • 使用@{}创建哈希表
PS > $array[email protected]()        #空数组
PS > $array=1,2,3,4,5 #常规定义数组
PS > $array=1..5 #连续的数字数组(推荐方式)
PS > $array=1,1.2,"String" #多种数据类型融合的数组
PS > $array -is [array]
True
PS > $array.Count #元素个数
3

PS > $arr=1..3
PS > $arr+=5..8 #突发奇想给数组添加数组
PS > $arr
1
2
3
5
6
7
8

#所以给数组增加元素其实相当于创建一个新的数组,只不过之后会把原来的副本删除。在当前数组追加元素可以使用“+=”操作符。
PS C:Powershell> $books="元素1","元素2","元素3"
PS C:Powershell> $books+="元素4"
PS C:Powershell> $books
元素1
元素2
元素3
元素4


2.数组访问

PS > $arr[0]  #元素都是从0下标开始索引的

1
PS > $arr[($arr.Count-1)] #输出最后一个元素
8

PS > $arr[0,1,3,5] ##一次输出多个元素 (值得学习)
1
2
5
7

PS > $arr[($arr.Count)..0] #将数组逆序输出 (值得学习)
8
7
6
5
3
2
1

PS > $arr = 1..3
PS > $arr = $arr[1..2] + 4..6 #数组之间可以直接追加元素或者删除元素
PS > $arr
2
3
4
5
6


3.复制数组
描述:复制数组最好使用Clone()方法,除非有特殊需求。

PS > $arr=1..3
PS > $arr1=$arr
PS > $arr1.Equals($arr) #两个变量指向同一个地址的数组(表示是相同的)
True
PS > $arr2=$arr.Clone() #一个新的数组不是两个变量指向同一个数组
PS > $arr2.Equals($arr) #这里是为False
False
PS > $arr2[0]=1024
PS > $arr2
1024
2
3


强类型数组

描述:数组一般具有多态性,如果你不指定元素的具体类型,解释器会自动选择合适的类型存储每个元素

  • 如果要统一限制所有元素的类型,可是使用类型名和一对方括号作为数组变量的类型。
  • 每当赋值时会自动类型检查, 如果目标数据类型不能转换成功,就会抛出一个异常。

基础示例:

PS > [int[]] $num = @()
PS > $num += 1024
PS > $num += 3.1415926 #这里由于强制类型的作用(会直接忽略小数点后的数字)
PS > $num += 999
PS > $num
1024
3
999


哈希表(HASH)

描述:哈希表存放的是键值对(Key-Value),在哈希表中不再仅仅限制使用数字寻址,可以使用任意类型的数据类型寻址
在创建哈希表时就使用数组,因为创建数组和哈希表的的元素关键字不冲突一个是逗号,一个是分号

PS > $hash[email protected]{ Name="WeiyiGeek";Age="15" }  #创建一个HASH表示
PS > $hash['Name'] #使用哈希表的键访问对应的值
WeiyiGeek
PS > $hash.Keys #HASH表的所有键
Age
Name
PS > $hash.Values #HASH表的所有值
15
WeiyiGeek
PS > $hash.Count #HASH表的键值对数量
2

PS > $hash[email protected]{ Name="WeiyiGeek";Age="15"; Books="C","C++","PYTHON"} #在哈希表中存储数组
PS > $hash.Sex="Woman"
PS > $hash
# Name Value
# ---- -----
# Books {C, C++, PYTHON}
# Name WeiyiGeek
# Age 15
# Sex Woman

#哈希表值的更新和删除
PS > $hash.Name="weiyi"
PS > $hash.remove("Books")
PS > $hash
# Name Value
# ---- -----
# Name weiyi
# Age 15
# Sex Woman

使用哈希表格式化输出
PS许多命令的输出结果都是以表格的形式,当然可以使用Format-Table自定义表格格式,例如:

PS C:Powershell> Dir | Format-Table FullName,Mode #命令只能限制表格输出那些列,隐藏那些列,但是对于列的宽度,列标题无能为力
FullName Mode
-------- ----
C:PowershellABC d----
C:Powershellmyscript d----
C:Powershella.html -a---


#表格的每一个列包含四个属性:
* Expression:绑定的表达式
* Width:列宽度
* Label:列标题
* Alignment:列的对齐方式

PS > $column1 = @{expression="Name"; width=30;label="filename"; alignment="left"}
PS > $column2 = @{expression="LastWriteTime"; width=40;label="last modification"; alignment="right"}
PS > ls | Format-Table $column1, $column2
# filename last modification
# -------- -----------------
# .android 2019/7/26 8:45:03
# .config 2019/8/19 17:27:45

PS 条件判断

比较运算符:

-eq :等于
-ne :不等于
-gt :大于
-ge :大于等于
-lt :小于
-le :小于等于
-contains :包含
-notcontains :不包含

布尔运算符号:

-and :和
-or :或
-xor :异或
-not :逆

条件判断语法:

  • Where-Object
  • IF-ElseIf-Else
  • Switch

ForEach

PS C:Powershell> ls | ForEach-Object {"文件名:{0} 文件大小{1}KB: " -f $_.Name,($_.length/1kb).tostring()}
文件名:a.html 文件大小65.99609375KB:
文件名:a.txt 文件大小25.765625KB:
文件名:alias 文件大小11.77734375KB:


PS 函数

描述:函数就是将大大小小的命令组合成一个集合里面进行执行,有利于提高代码复用以及简练代码量;

#
function Test-conn {
Test-Connection -Count 2 -ComputerName $args
}

Set-Alias tc test-conn
PS C:\PS> tc localhost