PowerShell基础命令篇

PowerShell基础命令篇

一、运行命令

PowerShell,如其名称所示,是一个Shell。使用PowerShell,你输入一个命令,然后通过添加一些参数来定制化命令行为,单击返回,立刻就能看到结果。将其复制粘贴到一个文本文件中,并将文件的扩展名更名为.PS1,然后你瞬间就拥有了一个“PowerShell脚本”。 PowerShell拥有能够访问整个.Net Framework底层的能力(虽然在非Windows操作系统中,只是整个Framework的子集),我们也看到PowerShell“脚本”实际上与通过Visual Studio编写的C#语言使用模式也十分类似。

1.1、命令的完整语法

https://img.kancloud.cn/4c/ca/4cca867b8b22a0f2db888061033f75a9_2130x476.jpeg

为了确保你能够完全熟悉PowerShell的规则,下面更详细地阐述上图中的每一部分:

  • 名称为Get-EventLog的Cmdlet。PowerShell Cmdlet总是以这种动词-名词形式命名。
  • 第一个参数名称为-LogName,并赋值为Security。由于参数值中并不包含任何空格或标点符号,因此并不需要用引号括起来。
  • 第二个参数名称为-ComputerName,以逗号分隔列表的形式赋了两个值:Win8和Server1。由于这两个参数中都不包含空格或标点符号,因此这两个参数都不需要用引号括起来。
  • 最后一个参数是-Verbose,是一个开关参数。这意味着该参数无须赋值,仅仅指定参数即可。
  • 注意:在命令名称和第一个参数之间必须有空格。
  • 参数名称总是以英文短横线(-)开头。
  • 参数名称之间必须有空格,多个参数值之间也必须有空格。
  • 无论参数名称之前的破折号,还是参数值本身包含的破折号,都不需要加空格。
  • PowerShell不区分大小写。

多注意空格、破折号和其他部分可以最大程度减少PowerShell报低级错误的机会。

1.2、Cmdlet命名惯例

  • Cmdlet是一个原生的PowerShell命令行工具。该术语仅仅存在于PowerShell和类似C#的.Net Framework语言中。Cmdlet仅仅出现在PowerShell中,所以当你在Google或Bing搜索该关键字时,返回结果主要是关于PowerShell的。该术语读音为“command-let”。
  • 函数和Cmdlet类似,但不是以.Net语言编写,而是以PowerShell自己的脚本语言编写。
  • 工作流是嵌入PowerShell的工作流执行系统的一类特殊函数。
  • 应用程序是任意类型的外部可执行程序,包括类似PING、Ipconfig等命令行工具。
  • 命令是一个通用的术语,用于代表任何或所有上面提到的术语。

微软已经为Cmdlet建了一个命名惯例。因此同样的命名规则也应该被用于函数和工作流。虽然微软并没有强制要求,但开发人员应该遵循该惯例。

规则应该以标准的动词开始,比如Get、Set、New或Pause。你可以运行Get-Verb查看允许使用的动词列表(虽然只有少部分是常用的,但你大概会看到100个左右)。在动词之后紧接着一个破折号,然后是一个单数形式的名词,比如Service或Process或EventLog。

1.3、命令的别名

虽然PowerShell命令名称足够好,并具有良好的一致性,但仍然可能很长。类似Set-WinDefaultInputMethodOverride的命令名称,即使有Tab键补全,对于输入来说也是太长。虽然命令名称非常清晰——看到名称就能大概猜到其功能,但对于输入来说还是太长。

这也是为什么需要PowerShell别名。别名仅仅是命令的昵称。

Get-Alias -Definition “Get-Service”

 

现在你知道Gsv是Get-Service的别名了。

无论是否使用别名,命令的工作方式不会变。参数还是原来的参数,其他部分也不会有任何改变——仅仅是命令名称变得更短。如果你习惯使用UNIX或Linux,就会知道别名也可以包含一些参数,只是记住PowerShell并不是以这种方式工作。

如果你看到一个别名(网上的一些家伙倾向于使用别名,就好像我们都能够记住所有150个内置别名)而不知道其含义,请查阅帮助。

Help gsv

 

1.4、快捷方式

除了作为快捷方式的命令的别名之外,参数也同样可以使用别名。总共有三种方式可以实现这一点,每一种都可能造成混淆。

PowerShell并不强制要求输入完整的参数名称。例如,你可以通过输入-comp代替-ComputerName,简化的规则是必须输入足够的字母让PowerShell可以识别不同参数。如果既存在-composite参数,也存在-computerName以及-common参数,你至少要输入-compu、-commo和-compo。这是由于上述值是唯一识别参数所需要输入的最少部分。

如果你很希望使用简便方式,那上面就是一个不错的选择。如果你在输入最少部分的参数之后记得按Tab键,PowerShell会帮你自动完成余下的输入。

1.5、Show-Command

尽管我们拥有多年使用PowerShell的经验,但命令语法的复杂度有时依然会让我们抓狂。PowerShell v3(以及更新版本,虽然不包含非Windows操作系统)提供的一个非常棒的特性是Show-Command commlet。如果你在命令语法方面遇到困难,包括空格、破折号、逗号、引号或是其他方面,Show-Command将成为你的助手。该命令允许你指定你无法用对的命令名称,并以图形化的方式将命令的参数名称展示出来。

 

当完成后,你可以单击运行执行命令,或使用其他选项——单击复制将完成后的命令复制到剪贴板,返回Shell,将命令粘贴(右击控制台,或是在ISE中使用Ctrl+V组合键)到Shell中进行查看。

 

以这种方式产生的命令,总会是命令的完整形式。完整的命令名称,完整的参数名称,所有的参数名称都显式输入(即不会出现位置参数)。因此,这种方式可以说是使用PowerShell最完美、被推荐并符合最佳实践的方式。Show-Command一次只能展示一个命令。

1.6、扩展命令的支持

可以使用一些或许你已经使用多年的外置命令行工具,包括Ping、Nslookup、Ipconfig、Net等。由于这些都不是原生PowerShell Cmdlet,因此你可以按照原来使用这些命令的方法继续使用这些命令。PowerShell将会在后台启动Cmd.exe。由于PowerShell知道如何运行扩展命令,因此返回的结果都会被显示在PowerShell窗口。

比如运行命令行工具`sc.exe`查询一个服务

sc.exe --% qc Eventlog

 

1.7、处理错误

在刚开始使用PowerShell时无可避免地会遇见丑陋的红色文本提示,先不管用于警告目的的红字,PowerShell的错误信息的目的是用于帮助。

 

错误信息几乎总是会包括PowerShell认为有歧义地方的行数和字符数。第一行,字符1——就是命令开始部分。其表达的意思为“你输入了‘get’,我不知道该词的意思”。这是由于我们输错了命令,正确应该是Get-Command,而不是Get Command。

 

图中所示的错误信息“第二路径不得为驱动器或UNC名称”让人感到困惑,什么第二路径?我们并没有输入第二路径。我们输入了一个路径c:\windows和一个命令行参数/s,不是吗?

当然不是。解决该类问题最简便的方式就是阅读帮助,并完整输入命令。如果你输入Get-ChildItem -path C:\Windows,就会发现/s并不是正确的语法。我们希望该值对应的参数是-recurse。有时,错误信息并不一定很有帮助,就好像你和PowerShell说的不是同一种语言。当然,PowerShell不可能改变其语言,那么只能是你错了,所以你得去改变。通过咨询帮助并拼写出完整的命令和参数,通常都是解决问题的最快方式。还有不要忘了使用Show-Command找出正确语法。

二、使用提供程序

一个PowerShell的提供程序,或者说PSProvider,其本质上是一个适配器。它可以接受某些数据存储,并使得这些介质看起来像是磁盘驱动器一样。你可以通过下面的命令查看当前Shell中已经存在的提供程序。

Get-PSProvider

 

- `ShouldProcess`——这部分提供程序支持`-WhatIf`和`-Confirm`参数,保证我们在正式执行这部分脚本之前可以对它们进行测试。

- `Filter`——在Cmdlet中操作提供程序的数据时,支持`-Filter`参数。

- `Credentials`——该提供程序允许使用可变更的凭据连接数据存储。这也就是`-Credentials`参数的作用。

- `Transactions`——该提供程序支持事务,也就是允许你在该提供程序中将多个变更作为一个原子操作进行提交或者全部回滚。

PSDrive可以通过一个特定的提供程序连接到某些存储数据的介质。这和在Windows资源管理器中类似,本质上是创建了一个驱动器映射。但是由于PSDrive使用了提供程序,除了可以连接磁盘之外,还能连接更多的数据存储介质

 

在上面返回的列表中,可以看到有3个驱动器使用了FileSystem提供程序,两个使用了Registry提供程序,等等。PSProvider会适配对应的数据存储,通过PSDrive机制使得数据存储可被访问,然后可以使用一系列Cmdlets去查阅或者操作每个PSDrive呈现出来的数据。

2.1、FileSystem的结构

Windows文件系统(以及macOS与Linux的文件系统)主要由3种对象组成:磁盘驱动器、文件夹和文件。磁盘驱动器是最上层的对象,包含文件夹和文件。文件夹是一种容器对象,它可以包含文件以及其他文件夹。文件不是一种容器对象,该对象处于层级的末尾。

PowerShell中的术语和文件系统中的略有不同。因为PSDrive可能不是指向某个文件系统——比如PSDrive可以映射到注册表(显然注册表并不是一种文件系统),所以PowerShell并不会使用“文件”以及“文件夹”的说法。相反,PowerShell采用更通俗的说法——“项”(Item)。一个文件或者一个文件夹都叫作项,尽管本质上是两种不同的项。这也就是为什么前面返回的Cmdlet名字中都有“Item”字符。

每个项基本上都会存在对应的属性。比如,一个文件项可能有最后写入的时间、是否只读等属性。一些项,比如文件夹,可能包含子项(子项包含在文件夹项中)。了解这些信息会有助于你们理解前面演示的命令列表中的名词以及动词。

  • 比如Clear、Copy、Get、Move、New、Remove、Rename以及Set等动词可以应用于这些项(比如文件或者文件夹)以及它们对应的属性(比如该项最后写入的时间或者该项是否只读)。
  • Item名词对应的是单独对象,比如文件或者文件夹。
  • ItemProperty代表一个项对应的属性。比如只读、项创建时间、长度等。
  • ChildItem名词对应一个项(比如文件或者子文件夹)包含于另外一个项(文件夹)中。

需要记住的是,这些Cmdlet都是通用的,因为它们需要处理各种不同的数据源。但是某些Cmdlet在某些特定场合下不一定能正常工作。比如,FileSystem提供程序不支持事务,所以文件系统驱动器下的Cmdlet中的命令都不支持-UseTransaction参数。再比如,注册表不支持Filter功能,所以注册表驱动器下的Cmdlet也都不支持-Filter参数。

某些PSProvider并不具有对应的项属性。比如,Environment这个PSProvider主要用来构造PowerShell中可用的ENV:类型驱动器(如Env:\PSModulePath)。该驱动器主要的作用是访问Windows中的环境变量,但是如下所示,它并没有对应的项属性。

 

2.2、文件系统与其他数据存储

文件系统可以算作其他数据存储的模板。

注册表以类似文件系统的结构呈现,其中注册表的键等同于文件系统中的文件夹,对应的键值类似于文件系统中的文件,等等。正是这种广泛的相似性,使得文件系统成为其他形式数据源的最佳模板。所以当用PowerShell访问其他数据存储的时候,显示为驱动器的形式(可以依次展开为项以及查看对应的属性)。但是相似性到这一层级也就结束了:如果你再继续向下展开,那么你会发现不同形式的存储其实差别很大。这也就是为什么各种项的Cmdlet支持如此多的功能,但是并不是每个功能在每种存储中都能运行。

 

注册表和文件系统具有相同的分层结构。

2.3、使用文件系统

在使用提供程序时,需要熟悉的另外一个Cmdlet是Set-Location。该参数的功能是将Shell中当前路径变更为不同路径,比如变更到另一个文件夹下。

Set-Location -Path C:\Windows\

 

对应的其实就是cmd.exe中的cd命令。

PowerShell中另外一个比较棘手的任务是创建新的项。比如,如何创建一个新的目录。运行`New-Item`,将会返回一个意外的提示。

需要注意的是,`New-Item`这个Cmdlet在很多地方都是通用的——它根本无法得知你是想新建一个文件夹。这个Cmdlet可以用来新建文件夹、文件、注册表项以及其他项,所以你必须告知你希望创建的类型是什么。

New-Item -Path .\testFolder.txt    ---文本文件

New-Item -Path .\testFolder -ItemType Directory   ---文件夹

 

 

PowerShell中也包含`MKDir`命令。很多人都认为该命令是`New-Item`的别名,但使用`MKDir`并不需要输入类型

 

2.4、使用通配符与字面路径

大部分项的Cmdlet都包含了-Path属性。默认情况下,该属性支持通配符输入。比如,我们查看Get-ChildItem的完整帮助文档。

 

 

 

“`*`”通配符代表0个或者多个字符,“`?`”通配符仅代表单个字符。

PowerShell新增一个参数`-LiteralPath`。该参数并不支持通配符。

 

-LiteralPath 

    指定一个或多个位置的路径。与 Path 参数不同,LiteralPath 参数的值严格按

    照其键入形式使用。不会将任何字符解释为通配符。如果路径包括转义符,请将

    其括在单引号中。单引号会告知 Windows PowerShell 不要将所有字符都解释为

    转义序列。

如果需要查询名字中带有`*`或者`?`,就要使用`-LiteralPath`参数,而不要使用`-Path`。需要注意的是,`-LiteralPath`这个参数不可隐式赋予。如果确定需要使用该参数,必须显式申明`-LiteralPath`参数。

三、连接命令

让PowerShell独树一帜的不是运行命令的方式,而是它提供了管道功能,通过管道功能,只需要在一个序列行中,多个命令就可以很好地彼此连接。

PowerShell通过管道(pipeline)把命令互相连接起来。管道通过传输一个命令,把其输出作为另外一个Cmdlet的输入,使得第二个命令可以通过第一个的结果作为输入并联合起来运行。

你已经见过如“Dir | More”命令的运行情况,它把“Dir”命令的输出以管道方式传输给“More”命令。“More”命令把目录每次展现到一个页中。PowerShell把管道的概念有效延伸。实际上,PowerShell的管道类似UNIX和Linux的Shell中的管道功能。

3.1、输出结果

Get-Process| Export-Csv D:\procs.csv

与用管道把“Dir”连接到“More”类似,我们已经把进程信息传输到“`Export-CSV`”中。第二个Cmdlet有一个强制的位置参数,用于指定输出文件名称。

每当你通过“Get-Service”或者“Get-Process”创建一些美观的输出时,你可能想把它们保存到一个文件中甚至纸上。通常来说,Cmdlet是直接输出到PowerShell所在的本地机器的屏幕上,但是你可以修改输出位置。

Dir > DirectoryList.txt

其中“>”符是PowerShell向后兼容旧版本cmd.exe命令的一个快捷方式。而实际上,当运行这个命令时,PowerShell底层会以下面的方式实现。

Dir | Out-File DirectoryList.txt

用这种方式替代“`>`”符号。“`Out-File`”提供了一些参数让你定制替代的字符编码(如UTF8或Unicode)、追加内容到现有文件等功能。

当你运行“Dir”时,实际上是在运行“`Dir | Out-Default`”。“`Out-Default`”只是把内容指向“`Out-Host`”,意味着你在无意中运行了:

Dir | Out-Default | Out-Host

而“`Out-Host`”是显示结果到显示器中

转换成HTML

只需要通过管道将结果传递给“ConvertTo-HTML”命令即可。该命令可以生成结构良好的、通用的HTML数据,并可以在任何Web浏览器中打开。但是这只是原始数据,如果需要美观,需要引用CSS(Cascading Style Sheet)文件定制样式。注意,该命令不需要文件名。

Get-Service | ConvertTo-Html | Out-File D:\services.html

PowerShell附带其他“`ConvertTo-`Cmdlets”,包括“`ConvertTo-CSV`”和“`ConvertTo-XML`”等。正如“`ConvertTo-HTML`”一样,这些命令都不在磁盘上创建文件,只是把命令的输出结果分别转换成CSV或XML。你需要用管道把它们和“`Out-File`”连接起来以便存储到磁盘上,但是它们比使用“`Export-CSV`”或“`Export-CliXML`”更简短。另外,它们能既转换又存储。

3.2、使用Cmdlets修改系统

终止进程和停止服务

Get-Process | Stop-Process

它会检索每一个进程,然后尝试逐个终止。该命令可能获取到关键进程,比如本地安全权限(Local Security Authority),你的电脑很可能进入蓝屏死机状态。

这个例子想说明的是带有相同名词(本例中的进程)的Cmdlets可以在彼此之间互传信息。通常情况下,你最好带上特定进程名称而不是终止全部进程:

Get-Process -name Notepad | Stop-Process

服务也是类似的,“`Get-Service`”命令的输出结果能和其他Cmdlets(如`Stop-Service`、`Start-Service`、`Set-Service`等)一起被管道传输。

Shell有一个相应的“`$ConfirmPreference`”设置,默认为“`High`”。

工作原理:当Cmdlet的内部影响级别大于等于Shell的“`$ConfirmPreference`”设置时,不管Cmdlet正准备做什么,Shell都会自动询问“你确定要这样做吗?(Are you sure?)”。当Cmdlet的内部影响级别小于Shell的“`$ConfirmPreference`”设置时,不会自动弹出这个提示。

如果你“喜欢”它总是弹出,可以使用下面的命令

Get-Service | Stop-Service –confirm

加了“`-confirm`”参数,对于某些被支持的用于修改系统的Cmdlet,会弹出提示

另外一个类似的参数是“`-whatif`”,可用于支持“`-confirm`”的Cmdlet。但是它并不默认触发,可以在你想用的时候使用。

get-process | stop-process -whatif

它会告诉你哪些Cmdlet会被执行,但是并不真正运行。这个功能为那些可能有潜在风险的Cmdlet的预览提供了很好的帮助,并且可以检查是否是你想要的结果。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值