PowerShell基本编程方法

begin

在Windows环境下,有时候需要编写批处理运行脚本,限于bat功能羸弱,因此简单学习一下PS(powershell)。

变量

PS的变量通过下面的方式声明:

1
$var = 10

即”$变量名=变量值“。

具体来说,PS支持下面几种数据类型:

  1. 数字:包括十进制、二进制、八进制和十六进制等饿等那个。
  2. 布尔值
  3. 字符串
  4. 数组
  5. 列表(键值对)
  6. XML

下面具体示例:

数字

1
2
3
4
$num1 = 10 #十进制
$num2 = 0xFE4A #十六进制
$num3 = 0b0001 #二六进制
$num4 = 10.5 #十进制小数

值得注意的是:

  1. 默认十进制为32位整型,浮点数默认32位浮点。可以使用后缀L声明64位。
  2. PS支持科学计数法
1
2
$num5 = 400000L #64位数字
$num6 = 3.1415e-3

布尔值

1
2
$bool1 = True
$bool2 = False

值得注意的是,PS在if等判断的时候,会对其他变量自动转换为布尔值,下面是规则:

结果 布尔值
$true True
$false False
$null False
Nonzero number True
Zero False
Nonempty string True
Empty string False
Nonempty array True
Empty array False
Hashtable(无论empty与否) True

字符串

PS的字符串支持单引号、双引号的方式进行声明,双引号优先级更高,因此想要打印双引号可以使用双引号嵌套或者转义(用`符号,不是反斜杠\),不能用单引号嵌套双引号。

  1. PS的字符串支持变量快捷引用。

  2. PS定义了一种特殊的跨行字符串,用@开头。可以直接跨行声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$str1 = 'string1'
$str2 = "string2"
$str3 = "string3 'inner'" #string3 'inner'
$str4 = "string4 "inner"" #string4 "inner"
$str5 = "string5 `"inner`"" #string4 "inner"

$var = 123
$str6 = "string6 $var1" # string6 123
$str7 = "string7 $(var1)" # string6 123 用于var是对象的时候方便用.符号引用

$str8 = @"
123
456
789
"@

数组

定义

有下面几种形式定义数组:

1
2
3
4
5
6
7
8
9
10
11
$arr1 = @()  #一个空的数组
$arr2 = 1,2,3 #一个非空的数组
$arr3 = 1,"two", False, 3.14 #数组支持多种数据形式

$arr4 = ,1 #只有一个元素的数组
$arr5 = @(1) #只有一个元素的数组

$arr6 = @(
(1,2,3),
(5,6,7)
) #数组的嵌套

数组的访问

可以通过下面的形式访问数组内容:

1
2
3
4
5
6
7
8
9
10
$arr = @(1,2,3,4,5,6,7) #先定义一个数组

$arr[2] #3,返回第二个元素,下标从0开始
$arr[-2] #3, 返回倒数第二个元素,下标从0开始

$arr[0..2] # 1,2,3 返回前三个元素

$arr[-1..2] #5,1,2,3 返回-1到第二个元素

$arr[-1..-3] #5,4,3 返回-1到-2个元素

此外,数组还支持通过+或,符号来从某处来分开检索以及使用数组作为下表来检索

1
2
3
4
$arr[0,2+4..5] #1,3,5,6 跳过了第一个、和第三个元素
$arr2 = 0,1,5

$arr[$arr2] #1,2,6 通过另一个数组作为下表来访问数组

列表

PS定义了一种键值对的数据类型,成为哈希表,则其键必须是唯一的。切和数组一样,值的数据类型不限。用;符号隔开。

列表定义

1
2
3
$hashtable1 = @{}

$hashtable2 = @{Key1: 1; "Key 2": "two"; Key3: 1,2,3; Key4: 3.14}

列表操作

1
2
3
4
5
$hashtable2["Key1"] #1 访问

$hashtable2."Key 2" # "two" 访问字符串键

$hashtable2["Key 5"] = 5 # 添加新的元素

XML(不再细讲)

1
2
3
4
5
6
7
8
9
$xml1 = [xml]@"
<xxx>
<yyy>
</yyy>
</xxx>
" #定义

$xml1.xxx #访问
$xml1.xxx[1] #访问

操作运算符

数学操作符

  1. +:数字则为加,其他类型都是拼接
  2. -:仅支持数组,为差
  3. *:数字为积,字符串*数字为重复;数组也为重复;不支持哈希表
  4. /:商,不支持其他类型
  5. %:余,不支持其他类型
  6. =:赋值

逻辑操作符

  1. -and:逻辑与,两个都为真才返回真
  2. -or:逻辑或,一个为真就返回真
  3. -xor:逻辑异或,一个为真、一个为假则返回真,否则返回假(一样返回假,不一样返回真)
  4. -not:逻辑非,取反

按位操作符

  1. -band: 按位与
  2. -bor:按位或
  3. -xor:按位异或
  4. -bont:按位取非

其他操作符

  1. -replace:用于字符串替换,语法:”target_string” -replace “pattern” “replacement”。
  2. -f:格式化字符串。
  3. -as:数据类型转换。如:3/2 as [int] 结果为2。

比较操作符

  1. -eq:比较两个元素是否相等。数字则正常,数字则返回两个中相同的元素。其他类型提供了Equals()方法
  2. -ne:不相等比较符,和上面的相反
  3. -ge:大于等于比较符。数组则返回大于等于的元素
  4. -gt:大于比较符,数组与上面类似
  5. -lt:小于比较符,数组与上面类似
  6. -le:小于等于比较符,数组与上面类似
  7. -like:正则表达式模式匹配。返回真或假。数组则匹配每一个元素
  8. -notlike:非类似运算符。返回真或假
  9. -match:返回真或假,但是匹配结果会被存放在$match元素中,其是一个数组
  10. -notmatch:与上面相反
  11. -contain:数组或哈希表中是否含有某元素。返回真或假
  12. -notcontains:与上面相反
  13. -is:判断数据类型,$leftvalue -is [type]
  14. -isnot:与上面相反

条件语句

1
2
3
4
5
6
7
8
9
10
11
12
if(condition)
{
statement block
}
elseif(condition)
{
statement block
}
else
{
statement block
}

switch语句

1
2
3
4
5
6
switch options expression
{
comparion value {statement block}
{comparion block}{statement block}
default {comparion}
}

for循环

1
2
3
4
for($counter = 0; $counter -lt 10; $counter++)
{
Wtite-Host "Process item $counter"
}

break和continue分别用来终结和跳过当前循环。

foreach循环

1
2
3
4
5
6
7
$handleSum = 0
foreach{$process in Get-process | Where-Object {$_.Handle -gt 500}}
{
$handleSum += $process.Handles
}

$handSum

Get-process和 Where-Object为内置函数。也可以用自定义数组和哈希表来作为遍历对象。

while循环

1
2
3
4
5
6
$command = "";

while($command -notmatch "quit")
{
$command = Read-Host "Enter your command"
}

当输入的是quit时才退出,否则一直输出“Enter your command”。

do…while/do…until语句

  1. do…while…:当条件为真的时候一直循环
  2. do…until…:当条件为假的时候一直循环
1
2
3
4
5
6
7
8
9
10
11
12
13
$validResporses = "Yes","No";
$response = ""
do
{
$response=read-host"Yes or No?"
}while($validResponses notcontains $response)
"Got it"

$response = ""
do
{
$response=read-host"Yes or No?"
}until($validResponses notcontains $response)

函数

形式如下,可以设置默认参数。

1
2
3
4
5
6
7
8
9
10
function Test-Function ($Parameter1='Default Value1', $Parameter2='Default Value2')
{
"You entered $Parameter1 and $Parameter2"
}

# 如果不需要参数则可以简化至如下形式
function Test-Function
{
'Hello World!'
}

脚本输入

通常一个powershell脚本的后缀为.ps1(区分Photoshop),则PS内置了一个特数的数组”args”来获取参数值。

1
2
3
$firstParam = $args[0] 
$SecondParam = $args[1]
$ThirdParam = $args[2]

此外,还可以强制规定一个参数:

1
param($mustParam = $(throw "This parameter is required."))

管道

所谓管道,就是可以把第一个程序执行的结果交给第二个程序作为参数,前后用-符号连接。如:为了列出所有正在运行进程名称中包含“Search”的进程,对进程名字属性使用-1ike操作符来比较进程的 Name 属性。

1
Get-Process | Where-Object {$_.Name -like "*Search"}

内置函数

PS有众多的内置函数,包括但不限于文件、用户、进程等等,且每个函数都有多种重载形式。下面列举最重要的一些和常见用法:

  1. Invoke-Command:执行命令,最简单的方法是直接跟命令字符串。也可以通过哈希表构建对应的键值对,然后Invoke-Command这个哈希表。如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $parameters = @{
    ComputerName = 'Server01'
    ScriptBlock = {
    Param ($param1, $param2)
    Get-ChildItem -Name $param1 -Include $param2
    }
    ArgumentList = 'a*', '*.pdf'
    }
    Invoke-Command @parameters
  2. Get-Process:获取在本地计算机上运行的进程。

    1
    2
    3
    4
    5
    # 获取本地计算机上所有活动进程的列表
    Get-Process

    # 获取有关一个或多个进程的所有可用数据,此命令获取计算机上的有关 Winword 和 Explorer 进程的所有可用的数据。 它使用 Name 参数来指定进程,但省略可选的参数名。 管道运算符 (|) 将数据传递给 Format-List cmdlet,后者将显示 Winword 和 Explorer 进程对象的所有可用属性 (*)。
    Get-Process winword, explorer | Format-List *
  3. Read-Host: 从控制台读取一行输入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 示例 1:将控制台输入保存到变量
    $Age = Read-Host "Please enter your age"

    # 示例 2:将控制台输入保存为安全字符串:此示例显示字符串“Enter a Password:”作为提示。 当输入某个值时,控制台中将显示星号 (*) 而非该输入。 按 Enter 键时,该值将作为 SecureString 对象存储在 $pwd_secure_string 变量中。
    $pwd_secure_string = Read-Host "Enter a Password" -AsSecureString

    # 示例 3:遮蔽输入并将其存储为纯文本字符串:此示例显示字符串“Enter a Password:”作为提示。 当输入某个值时,控制台中将显示星号 (*) 而非该输入。 按 Enter 键时,该值将作为 String 对象存储在 $pwd_string 变量中。
    $pwd_string = Read-Host "Enter a Password" -MaskInput

  4. Write-Host:将自定义的输出写入主机。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 示例 1:在不添加新行的情况下写入控制台
    Write-Host "no newline test " -NoNewline
    Write-Host "second string"

    no newline test second string

    # 示例 2:写入控制台并包含分隔符
    Write-Host (2,4,6,8,10,12) -Separator ", +2= "

    2, +2= 4, +2= 6, +2= 8, +2= 10, +2= 12

    # 示例 3:使用不同的文本和背景色进行写入
    Write-Host (2,4,6,8,10,12) -Separator ", -> " -ForegroundColor DarkGreen -BackgroundColor White

    2, -> 4, -> 6, -> 8, -> 10, -> 12

    # 示例 4:使用不同的文本和背景色进行写入

    Write-Host "Red on white text." -ForegroundColor red -BackgroundColor white

    Red on white text.
  5. Write-Output:将指定的对象写入管道。 如果 Write-Output 是管道中的最后一个命令,则这些对象将在控制台中显示。

    1
    2
    3
    4
    5
    6
    # 示例 1:获取对象并将其写入控制台
    $P = Get-Process
    Write-Output $P

    # 示例 2:将输出传递给另一个 cmdlet
    Write-Output "test output" | Get-Member
  6. Get-Item:获取位于指定位置的项。

    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
    # 此示例获取当前目录。 句点 ('.') 表示当前位置处的项(而非其内容)。
    Get-Item .

    Directory: C:\

    Mode LastWriteTime Length Name
    ---- ------------- ------ ----
    d---- 7/26/2006 10:01 AM ps-test


    # 此示例将获取当前目录中的所有项。 通配符 (*) 表示当前项的所有内容。
    Get-Item *

    Directory: C:\ps-test

    Mode LastWriteTime Length Name
    ---- ------------- ------ ----
    d---- 7/26/2006 9:29 AM Logs
    d---- 7/26/2006 9:26 AM Recs
    -a--- 7/26/2006 9:28 AM 80 date.csv
    -a--- 7/26/2006 10:01 AM 30 filenoext
    -a--- 7/26/2006 9:30 AM 11472 process.doc
    -a--- 7/14/2006 10:47 AM 30 test.txt


    # 获取驱动器的当前目录
    Get-Item C:

    #显示注册表项的内容
    Get-Item HKLM:\Software\Microsoft\Powershell\1\Shellids\Microsoft.Powershell\
  7. Get-Date:获取当前日期和时间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 示例 1:获取当前日期和时间
    Get-Date

    Tuesday, June 25, 2019 14:53:32

    # 示例 2:使用 .NET 格式说明符获取日期和时间
    Get-Date -Format "dddd MM/dd/yyyy HH:mm K"

    Tuesday 06/25/2019 16:17 -07:00

end

简单了解其API与语法即可,一般也只是用来编写批量执行脚本,对于其深入的系统API可以暂时不用了解。还有PS在Microsoft.PowerShell.Utility中提供了大量的内置工具类,包括关于Json,markdown等,需要的时候查看,PS还是比较强大,相较于Windows Command确实算是编程语言了。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2019 - 2024 My Wonderland All Rights Reserved.

UV : | PV :