powershell 基础
程序员文章站
2023-12-30 16:34:46
...
1、管道和重定向
2、条件操作比较
通过ls获取当前目录的所有文件信息,然后通过Sort -Descending对文件信息按照Name降序排列,最后将排序好的文
件的Name和Mode格式化成Table输出。
ls | sort -Descending Name | Format-Table Name,Mode
ipconfig | Select-String "IP"
比较运算符
-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: wwwPlease give a valid domain name.Input domain: mossfly.comPlease 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-AutoSizestatus DisplayName------ -----------OK Adobe Acrobat Update ServiceOK Application ExperienceOK Application Layer Gateway ServiceOK Application Host Helper ServiceOK Application IdentityOK Application InformationOK Application ManagementOK ASP.NET State Service
#但是如果想对每个服务进行更定制化的处理可是使用ForEach-ObjectPS C:Powershell> Get-WmiObject Win32_Service | ForEach-Object {"Name:"+ $_.DisplayName, ", Is ProcessId more than 100:" + ($_.ProcessId -gt 100)}Name:Adobe Acrobat Update Service , Is ProcessId more than 100:TrueName:Application Experience , Is ProcessId more than 100:FalseName:Application Layer Gateway Service , Is ProcessId more than 100:FalseName:Application Host Helper Service , Is ProcessId more than 100:TrueName:Application Identity , Is ProcessId more than 100:TrueName:Application Information , Is ProcessId more than 100:TrueName:Application Management , Is ProcessId more than 100:FalseName: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 iexploreHandles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- -----------883 29 14728 22432 181 34.26 4300 iexplore771 28 55552 129152 425 8.56 5732 iexplore1216 51 104324 143916 539 572.41 5912 iexplore801 25 49200 25372 285 5.99 6252 iexplore691 25 57564 95796 333 8.08 6388 iexplore1256 38 85848 127012 379 20.37 7856 iexplorePS 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 outCommandType 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] ] [-InputObjectCmdlet 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-ServiceStatus Name DisplayName------ ---- -----------Running AdobeARMservice Adobe Acrobat Update ServiceStopped AeLookupSvc Application ExperienceStopped ALG Application Layer Gateway ServicePS C:PowerShell> pwd;Get-ServicePath----C:PowerShellStatus : StoppedName : THREADORDERDisplayName : Thread Ordering ServerStatus : RunningName : TrkWksDisplayName : 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 lengthCount : 19Average :Sum :Maximum :Minimum :Property : lengthPS C:Powershell> ls | measure length -Average -Sum -Maximum -MinimumCount : 19Average : 53768.8421052632Sum : 1021608Maximum : 735892Minimum : 0Property : length
使用Measure-Object还可以统计文本文件中的字符数,单词数,行数
例如我们可以把下面的文本保存到:word.txt 。
Retirement Anxiety Spreads Among the One PercentReport: Green Monday a Boon for Online Shopping5 Lesser-Known Ways to Boost Your Credit ScorePS C:Powershell> Get-Content .word.txt | measure -Line -Word -CharacterLines Words Characters Property----- ----- ---------- --------3 23 141
比较对象
有时需要比较前后两个时间段开启了那些进程,服务状态有什么变化。类似这样的工作可以交给Compare-Object。
比较不同的时间段
可以先将所有开启的进程信息快照保存到一个变量中,过一段时间,再保存一份新的进程快照,然后就可以通过Compare-Object进行对比了。
PS C:Powershell> $before=Get-ProcessPS C:Powershell> $after=get-processPS C:Powershell> Compare-Object $before $afterInputObject 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 wsearchStatus Name DisplayName------ ---- -----------Running wsearch Windows SearchPS C:PowerShell> $svc1=Get-Service wsearchPS C:PowerShell> $svc1.stop()PS C:PowerShell> $svc2=Get-Service wsearchPS C:PowerShell> Compare-Object $svc1 $svc2 -Property Status,NameStatus 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.xmlPS C:PowerShell> $before=Import-Clixml .before.xmlPS C:PowerShell> $after=Get-ProcessPS C:PowerShell> Compare-Object -ReferenceObject $before -DifferenceObject $after
9、命令返回数组
当我们把一个命令的执行结果保存到一个变量中,可能会认为变量存放的是纯文本。
但是,事实上Powershell会把文本按每一行作为元素存为数组。如果一个命令的返回值不止一个结果时,Powershell也会自动把结果存储为数组。
PS C:Powershell> $IPcfg=ipconfigPS C:Powershell> $IPcfgWindows IP ConfigurationEthernet adapter Local Area Connection:Connection-specific DNS Suffix . : ***Link-local IPv6 Address . . . . . : ***IPv4 Address. . . . . . . . . . . : 192.168.140.128Subnet Mask . . . . . . . . . . . : 255.255.252.0Default Gateway . . . . . . . . . : 192.168.140.1Tunnel adapter isatap.mossfly.com:Connection-specific DNS Suffix . : ***Link-local IPv6 Address . . . . . : ***Default Gateway . . . . . . . . . :***Tunnel adapter Teredo Tunneling Pseudo-Interface:Media State . . . . . . . . . . . : Media disconnectedConnection-specific DNS Suffix . :PS C:Powershell> $IPcfg.Count22
使用数组存储结果
判断一个变量是否为数组
PS C:Powershell> $ip=ipconfigPS C:Powershell> $ip -is [array]TruePS C:Powershell> "abac" -is [array]FalsePS 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 ConfigurationLink-local IPv6 Address . . . . . : ***IPv4 Address. . . . . . . . . . . : ***Link-local IPv6 Address . . . . . : ***
使用真实的对象操作
为什么不愿把IPconfig返回的结果称为对象,因为它不是真正Cmdlet命令,真正的Powershell命令返回的数组元素可不止一个字符串,它是一个内容丰富的对象。
PS C:Powershell> lsDirectory: C:PowershellMode LastWriteTime Length Name---- ------------- ------ ----d---- 2011/11/23 17:25 ABCd---- 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.vbsPS C:Powershell> $result=lsPS C:Powershell> $result.Count20
数组的每一个元素存放的是一个System.IO.DirectoryInfo对象。
当我们输出这些对象时,Powershell会自动帮我们把它转换成友好的文本格式。
PS C:Powershell> $result[0].gettype().fullnameSystem.IO.DirectoryInfoPS C:Powershell> $result[0]Directory: C:PowershellMode LastWriteTime Length Name---- ------------- ------ ----d---- 2011/11/23 17:25 ABC
对于任何一个对象都可以使用Format-List * 查看它所有的属性和方法。
PS C:Powershell> $result[0] | fl *PSPath : Microsoft.PowerShell.CoreFileSystem::C:PowershellABCPSParentPath : Microsoft.PowerShell.CoreFileSystem::C:PowershellPSChildName : ABCPSDrive : CPSProvider : Microsoft.PowerShell.CoreFileSystemPSIsContainer : TrueBaseName : ABCMode : d----Name : ABCParent : PowershellExists : TrueRoot : C:FullName : C:PowershellABCExtension :CreationTime : 2011/11/23 17:25:53CreationTimeUtc : 2011/11/23 9:25:53LastAccessTime : 2011/11/23 17:25:53LastAccessTimeUtc : 2011/11/23 9:25:53LastWriteTime : 2011/11/23 17:25:53LastWriteTimeUtc : 2011/11/23 9:25:53Attributes : Directory