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

powershell 基础

程序员文章站 2023-12-30 16:34:46
...
1、管道和重定向
通过ls获取当前目录的所有文件信息,然后通过Sort -Descending对文件信息按照Name降序排列,最后将排序好的文 件的Name和Mode格式化成Table输出。

ls | sort -Descending Name | Format-Table Name,Mode

ipconfig | Select-String "IP"


2、条件操作比较
比较运算符
-eq :等于
-ne :不等于
-gt :大于
-ge :大于等于
-lt :小于
-le :小于等于
-contains :包含
-notcontains :不包含

求反
-not 但是像高级语言一样”! “ 也支持求反。

布尔运算
-and :和
-or :或
-xor :异或
-not :逆

验证一个数组是否存在特定元素
PS C:Powershell> 1,9,4,5 -contains 10
False

3、命令返回数组
把一个命令的执行结果保存到一个变量中,可能会认为变量存放的是纯文本。
但是,事实上Powershell会把文本按每一行作为元素存为数组。如果一个命令的返回值不止一个结果时,Powershell也会自动把结果存储为数组。

判断一个变量是否为数组
$str.ToCharArray() -is [array]
true

使用真实的对象操作
PS C:Powershell> $result=ls 
PS C:Powershell> $result.Count

数组的每一个元素存放的是一个System.IO.DirectoryInfo对象。
当我们输出这些对象时,Powershell会自动帮我们把它转换成友好的文本格式。
$result[0].gettype().fullname

对于任何一个对象都可以使用Format-List * 查看它所有的属性和方法。
PS C:Powershell> $result[0] | fl *

4、管道

5、for循环
与C语法基本一致,只是变量是$形式
例如:

#判断域名:
for($domain="";!($domain -like "www.*.*");$domain=Read-Host "Input domain")
{
    Write-Host -ForegroundColor "Green" "Please give a valid domain name."
}
Please give a valid domain name.
Input domain: www
Please give a valid domain name.
Input domain: mossfly.com
Please give a valid domain name.

#逐行读文本

for($file=[IO.File]::OpenText("c:autoexec.bat") ; !($file.EndOfStream);$line=$file.ReadLine() )
{
    $line;
}
$file.Close()
REM Dummy file for NTVDM


6、ForEach-Object 循环

对管道对象逐个处理:

#使用Get-WmiObject 获取系统中的服务,为了排版可能会也会使用Format-Table对结果进行表格排版

PS C:Powershell> Get-WmiObject Win32_Service | Format-Table status,DisplayName
-AutoSize

status DisplayName
------ -----------
OK     Adobe Acrobat Update Service
OK     Application Experience
OK     Application Layer Gateway Service
OK     Application Host Helper Service
OK     Application Identity
OK     Application Information
OK     Application Management
OK     ASP.NET State Service


#但是如果想对每个服务进行更定制化的处理可是使用ForEach-Object

PS C:Powershell> Get-WmiObject Win32_Service | ForEach-Object {"Name:"+ $_.Disp
layName, ", Is ProcessId more than 100:" + ($_.ProcessId -gt 100)}
Name:Adobe Acrobat Update Service , Is ProcessId more than 100:True
Name:Application Experience , Is ProcessId more than 100:False
Name:Application Layer Gateway Service , Is ProcessId more than 100:False
Name:Application Host Helper Service , Is ProcessId more than 100:True
Name:Application Identity , Is ProcessId more than 100:True
Name:Application Information , Is ProcessId more than 100:True
Name:Application Management , Is ProcessId more than 100:False
Name:ASP.NET State Service , Is ProcessId more than 100:False

综合条件处理:
ForEach-Object的处理可以包含任意Powershell脚本,当然也包括条件语句

Get-WmiObject Win32_Service | ForEach-Object {
    if ($_.ProcessId -gt 3000)
    { "{0}({1})" -f $_.DisplayName,$_.ProcessID}
}


调用方法
在ForEach-Object中,$_代表当前对象,当然也允许通过$_,调用该对象支持的方法。
下面的例子杀死所有IE浏览器进程:

PS C:Powershell> Get-Process iexplore

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    883      29    14728      22432   181    34.26   4300 iexplore
    771      28    55552     129152   425     8.56   5732 iexplore
    1216      51   104324     143916   539   572.41   5912 iexplore
    801      25    49200      25372   285     5.99   6252 iexplore
    691      25    57564      95796   333     8.08   6388 iexplore
   1256      38    85848     127012   379    20.37   7856 iexplore
PS C:Powershell> Get-Process iexplore | ForEach-Object {$_.kill()}
PS C:Powershell> Get-Process iexplore


7、导出管道结果
可以将管道的结果转换成文本输出,默认是Out-Default。可以通过Get-Command -verb out查看Powershell都有哪些输出的命令。
Out-Default 将输出发送到默认的格式化程序和默认的输出 cmdlet。
Out-File 将输出发送到文件。
Out-GridView 将输出发送到单独窗口中的交互表。
Out-Host 将输出发送到命令行。
Out-Null 删除输出,不将其发送到控制台。
Out-Printer 将输出发送到打印机。
Out-String 将对象作为一列字符串发送到主机。
PS C:PowerShell> get-command -Verb out

CommandType Name         Definition
----------- ----         ----------
Cmdlet      Out-Default  Out-Default [-InputObject ]
Cmdlet      Out-File     Out-File [-FilePath]  [[-Encoding]
Cmdlet      Out-GridView Out-GridView [-InputObject ]
Cmdlet      Out-Host     Out-Host [-Paging] [-InputObject ]
Cmdlet      Out-Null     Out-Null [-InputObject ] [-Verbose]
Cmdlet      Out-Printer  Out-Printer [[-Name] ] [-InputObject
Cmdlet      Out-String   Out-String [-Stream] [-Width ]

吸收输出结果

有的命令无论执行成功或失败都会有输出,有时不需要这些输出时可以使用 | Out-Null,这条命令的作用和 >$null 一样。尤其在函数中使用比较多,因为如果没有特别指明return 。Powershell函数会把输出结果作为函数的返回值。为了避免这种麻烦,通常在管道后加一条命令Out-Null 或 >$null吸收输出结果。

修改管道格式

之前讨论过,Powershell默认会在每行命令的末尾追加一条Out-Default,Out-Default默认包含了一条Out-Host,那是不是Out-Host就是英雄无用武之地了。事实上,可以通过Out-Host控制管道的版式。
Powershell不但会自动把管道结果发送到输出设备上,而且还会把管道结果转换成可读的文本。这个自动转换与Format-Table有点像。但是完全依靠自动转换有时会碰到很奇怪的输出结果。
例如当单独使用Get-Service时,结果会以表格的形式输出,但是使用pwd;Get-Service时Service信息以列表形式输出。

PS C:PowerShell> Get-Service

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service
Stopped  AeLookupSvc        Application Experience
Stopped  ALG                Application Layer Gateway Service

PS C:PowerShell> pwd;Get-Service

Path
----
C:PowerShell

Status      : Stopped
Name        : THREADORDER
DisplayName : Thread Ordering Server

Status      : Running
Name        : TrkWks
DisplayName : Distributed Link Tracking Client

第二行使用了两条命令,通过分号间隔。但是为什么Service信息会以列表显示 呢?因为经过Powershell的解释器处理,上面例子中的第二条命令会变成:
& { pwd;Get-Service} | Out-Default
Powershell在命令中没有发现特别指定的版式信息,就会尝试从第一条命令的第一个结果对象中寻找线索。并且把这种版式强加给紧接着的其它命令。
怎样避免上述问题,最好的办法就是要明确指定。
pwd;Get-Service | Out-Host较多,因为如果没有特别指明return 。Powershell函数会把输出结果作为函数的返回值。为了避免这种麻烦,通常在管道后加一条命令Out-Null 或 >$null吸收输出结果


8、分析和比较管道结果

使用Measure-Object和Compare-Object可以统计和对比管道结果。Measure-Object允许指定待统计对象的属性。Compare-Object可以对比对象前后的快照。

统计和计算

使用Measure-Object可以对对象的属性求最小值、最大值、平均值、和。例如要查看当前目录文件占用空间的情况。

PS C:Powershell> ls | measure length
Count    : 19
Average  :
Sum      :
Maximum  :
Minimum  :
Property : length

PS C:Powershell> ls | measure length -Average -Sum -Maximum -Minimum
Count    : 19
Average  : 53768.8421052632
Sum      : 1021608
Maximum  : 735892
Minimum  : 0
Property : length

使用Measure-Object还可以统计文本文件中的字符数,单词数,行数
例如我们可以把下面的文本保存到:word.txt 。

Retirement Anxiety Spreads Among the One Percent
Report: Green Monday a Boon for Online Shopping
5 Lesser-Known Ways to Boost Your Credit Score
PS C:Powershell> Get-Content .word.txt | measure -Line -Word -Character
Lines Words Characters Property
----- ----- ---------- --------
    3    23        141

比较对象

有时需要比较前后两个时间段开启了那些进程,服务状态有什么变化。类似这样的工作可以交给Compare-Object。

比较不同的时间段
可以先将所有开启的进程信息快照保存到一个变量中,过一段时间,再保存一份新的进程快照,然后就可以通过Compare-Object进行对比了。

PS C:Powershell> $before=Get-Process
PS C:Powershell> $after=get-process
PS C:Powershell> Compare-Object $before $after

InputObject                             SideIndicator
-----------                             -------------
System.Diagnostics.Process (notepad)    =>
System.Diagnostics.Process (notepad)    =>
System.Diagnostics.Process (AcroRd32)

$before 是一个数组存储了当前所有的Process对象,Compare-Object的结果有两个列:InputObject为前后不一致的对象,SideIndicator为不一致状态,=>表示新增的对象,结合上面的例子分析:在before和after的时间段有3个进程(AcroRd32,AcroRd32,prevhost)关闭了,有2个进程开启了(notepad,notepad)。

检查对象的变化

Compare-Object并不仅仅能比较对象组中的是否新增和减少了对象,它还可以比较每个对象的属性变化,因为它有一个参数-property 。

PS C:PowerShell> Get-Service wsearch

Status   Name               DisplayName
------   ----               -----------
Running  wsearch            Windows Search

PS C:PowerShell> $svc1=Get-Service wsearch
PS C:PowerShell> $svc1.stop()
PS C:PowerShell> $svc2=Get-Service wsearch
PS C:PowerShell> Compare-Object $svc1 $svc2 -Property Status,Name

                    Status Name                       SideIndicator
                    ------ ----                       -------------
              StartPending wsearch                    =>
                   Running wsearch

比较文件的内容

对于文本文件可以通过Get-Content进行读取,并且将文件以行为单位保存为一个数组,这时依然可以通过Compare-Object进行比较。下面的例子创建两个不同的文本文件,然后通过Compare-Object比较两个文件的Get-Content结果。

PS C:PowerShell> "Hellow
>> Power
>> Shell" >a.txt
>>
PS C:PowerShell> "Hollow
>> Shell
>> Linux" >b.txt
>>
PS C:PowerShell> Compare-Object (Get-Content .a.txt) (Get-Content .b.txt)
InputObject SideIndicator
----------- -------------
Hollow      =>
Linux         =>
Hellow

保存快照以便后期使用

上面的例子都是把对象保存在变量中,变量有一个缺点就是一旦Powershell退出或者电脑关闭变量都会消失。所以最好的方法就是把对象保存到磁盘文件中。怎样把对象序列化成一个文件,Powershell提供了一条命令:Export-Clixml,可以完成此工作,还有一条反序列化的命令Import-Clixml。这样可以使Compare-object的命令更方便。例如一个月前保存一个$before对象,一个月后比较都可以。


PS C:PowerShell> Get-Process  | Export-Clixml before.xml
PS C:PowerShell> $before=Import-Clixml .before.xml
PS C:PowerShell> $after=Get-Process
PS C:PowerShell> Compare-Object -ReferenceObject $before -DifferenceObject $after


9、命令返回数组
当我们把一个命令的执行结果保存到一个变量中,可能会认为变量存放的是纯文本。
但是,事实上Powershell会把文本按每一行作为元素存为数组。如果一个命令的返回值不止一个结果时,Powershell也会自动把结果存储为数组。

PS C:Powershell> $IPcfg=ipconfig
PS C:Powershell> $IPcfg

Windows IP Configuration
Ethernet adapter Local Area Connection:

   Connection-specific DNS Suffix  . : ***
   Link-local IPv6 Address . . . . . : ***
   IPv4 Address. . . . . . . . . . . : 192.168.140.128
   Subnet Mask . . . . . . . . . . . : 255.255.252.0
   Default Gateway . . . . . . . . . : 192.168.140.1

Tunnel adapter isatap.mossfly.com:

   Connection-specific DNS Suffix  . : ***
   Link-local IPv6 Address . . . . . : ***
   Default Gateway . . . . . . . . . :***

Tunnel adapter Teredo Tunneling Pseudo-Interface:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
PS C:Powershell> $IPcfg.Count
22

使用数组存储结果

判断一个变量是否为数组


PS C:Powershell> $ip=ipconfig
PS C:Powershell> $ip -is [array]
True
PS C:Powershell> "abac" -is [array]
False
PS C:Powershell> $str="字符串"
PS C:Powershell> $str.ToCharArray() -is [array]
True

查看数组的元素个数用$array.Count属性。访问第x个元素,使用$array[x-1],因为数组是以0开始索引的。

使用管道对数组进一步处理

PS C:Powershell> ipconfig | Select-String "IP"

Windows IP Configuration
   Link-local IPv6 Address . . . . . : ***
   IPv4 Address. . . . . . . . . . . : ***
   Link-local IPv6 Address . . . . . : ***

使用真实的对象操作

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

PS C:Powershell> ls

    Directory: C:Powershell

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2011/11/23     17:25            ABC
d----        2011/11/29     18:21            myscript
-a---        2011/11/24     18:30      67580 a.html
-a---        2011/11/24     20:04      26384 a.txt
-a---        2011/11/24     20:26      12060 alias
-a---        2011/11/24     20:27      12060 alias.ps1
-a---        2011/11/23     17:25          0 b.txt
-a---        2011/11/23     17:25          0 c.txt
-a---        2011/11/23     17:25          0 d.txt
-a---        2011/11/25     11:20        556 employee.xml
-a---        2011/11/29     19:23      21466 function.ps1
-a---        2011/11/28     11:12        186 LogoTestConfig.xml
-a---        2011/11/24     17:37       7420 name.html
-a---        2011/11/28     15:30         63 ping.bat
-a---        2011/11/24     17:44     735892 Powershell_Cmdlets.html
-a---        2011/11/30     16:04       2556 psdrive.html
-a---         2011/12/2     18:47        140 test.ps1
-a---        2011/11/23     17:37        242 test.txt
-a---        2011/11/28     16:42        170 test.vbs
PS C:Powershell> $result=ls
PS C:Powershell> $result.Count
20

数组的每一个元素存放的是一个System.IO.DirectoryInfo对象。
当我们输出这些对象时,Powershell会自动帮我们把它转换成友好的文本格式。

PS C:Powershell> $result[0].gettype().fullname
System.IO.DirectoryInfo
PS C:Powershell> $result[0]
    Directory: C:Powershell
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2011/11/23     17:25            ABC

对于任何一个对象都可以使用Format-List * 查看它所有的属性和方法。

PS C:Powershell> $result[0] | fl *

PSPath            : Microsoft.PowerShell.CoreFileSystem::C:PowershellABC
PSParentPath      : Microsoft.PowerShell.CoreFileSystem::C:Powershell
PSChildName       : ABC
PSDrive           : C
PSProvider        : Microsoft.PowerShell.CoreFileSystem
PSIsContainer     : True
BaseName          : ABC
Mode              : d----
Name              : ABC
Parent            : Powershell
Exists            : True
Root              : C:
FullName          : C:PowershellABC
Extension         :
CreationTime      : 2011/11/23 17:25:53
CreationTimeUtc   : 2011/11/23 9:25:53
LastAccessTime    : 2011/11/23 17:25:53
LastAccessTimeUtc : 2011/11/23 9:25:53
LastWriteTime     : 2011/11/23 17:25:53
LastWriteTimeUtc  : 2011/11/23 9:25:53
Attributes        : Directory

上一篇:

下一篇: