文章目录
介绍
PowerShell
作为Windows
系统中的默认脚本,其实在开发中,我们用的很少。接下来的几篇文章都将PowerShell
的相关知识,在上一章中我们介绍了PowerShell
基本的知识,本章我们将深入了解其相关知识。
Windows管理规范
简单介绍
在最顶层,Windows
管理规范(Windows Management Instrumentation
,WMI)被组织成命名空间(nampespace
)。可以把命名空间想象为关联到特定产品或技术的一个文件夹。比如,“root\CIMv2
”,该命名空间包含了所有Windows
操作系统和计算机硬件信息。而“root\MicrosoftDNS
”命名空间包含了所有关于DNS
服务器的信息。在客户端计算机上,“root\SecurityCenter2
”包含了关于防火墙、杀毒软件和反流氓软件等工具的信息。
在命名空间中,WMI
被分成一系列的类,每个类都是可用于WMI
查询的管理单元。下面看一个从“root\SecurityCenter2
”中查询“AntiSpywareProduct
”的例子。
Get-CimInstance -Namespace root\SecurityCenter2 -ClassName AntiSpywareProduct
要想很好的了解WMI
,可以通过一个叫WMI explorer
的工具来查看,下载地址为https://powershell.org/2013/03/wmi-explorer/。通过此工具可以方便的查看各个命名空间下的类,具体的属性等等。
选择你的武器:WMI或CIM
而在PowerShell v3
及以后的版本中,有两种与WMI
交互的方式。
- 所谓的“
WMI Cmdlets
”,例如“Get-WmiObject
”与“Invoke-WmiMethod
”——这些都是遗留命令,意味着它们依旧能工作,但是微软不会对它们进行后续的开发投入。 - 新版的“
WMI Cmdlets
”,例如“Get-CimInstance
”与“Invoke-CimMethod
”——它们或多或少等价于旧版本的“WMI Cmdlets
”,但是它们通过WS-MAN
(由Windows
远程管理服务实现)交互,替代原有的RPCs
。执行“Get-Command -noun CIM*
”可显示很多微软提供的这些命令
使用Get-WmiObject
通过“Get-WmiObject
”命令(别名是Gwmi
),你可以指定一个命名空间、一个类名称甚至远程计算机的名称以及备用凭据名。如果需要,还可以从指定计算机中查询该类的所有实例。下面的语法获取一个命名空间的类列表。
Get-WmiObject -namespace root\cimv2 -list
注意:命名空间名称中使用的是反斜杠,不是斜杠
也可以通过指定命名空间和类型查询一个类。
Get-WmiObject -namespace root\cimv2 -list -class win32_desktop
Get-WmiObject win32_desktop
注意:“
root\cimv2
”命名空间是默认命名空间,“-class
”是位置参数,所以上面两个命令结果一样
另外,“-filter
”参数允许你通过指定的规则查询特定的实例。
Get-WmiObject win32_operatingsystem | gm
gwmi -class win32_desktop -filter "name='NT AUTHORITY\\SYSTEM'"
对于该命令和输出结果,需要注意下面事项。
筛选条件通常被引号包住
筛选操作符并不使用PowerShell
的常规操作符“-eq
”和“-like
”,而使用更加传统、更加编程化的操作符,比如=
、>
、<
、<=
、>=
和<>
。可以使用关键字“LIKE
”作为操作符,但在匹配值时必须使用“%
”作为字符通配符,如“NAME LIKE '%administrator%'
”。注意,这里不能像PowerShell
的其他地方一样使用“*
”作为通配符
字符串匹配是以单引号包住,这也是筛选表达式的最外面的引号是双引号的原因
避免在WMI
中使用反斜杠。如必须使用则使用两个反斜杠代替
Gwmi
的输出结果总会包含大量系统属性,PowerShell
的默认显示配置通常因此这些属性,系统属性名称以双下划线开始
一旦你查询到一个WMI
实例的集合后,就可以把它们通过管道连接到任何以“-Object
” Cmdlet
、“Format
” Cmdlet
或“Out-
”、“Export-
”、“ConvertTo-
”开头的Cmdlet
中。
gwmi -Class win32_bios -ComputerName DESKTOP-GT96S5L,localhost |
Format-Table @{ label='ComputerName'; expression={$_.__SERVER}},
@{ label='BIOSSerial'; expression={$_.SerialNumber}},
@{ label='OSBuild'; expression={
gwmi -Class win32_operatingsystem -ComputerName $_.__SERVER |
Select-Object -ExpandProperty BuildNumber}
} -AutoSize
使用Get-CimInstance
Get-CimInstance
的PowerShell v3
引入的新命令,与“Get-WmiObject
”有很多相似的地方,但是也由几个语法上的差异。
你需要使用“
-ClassName
”代替“-Class
”
没有用于列出命名空间中所有类的“-List
”参数。而是使用“Get-CimClass
”并搭配“-Namespace
”参数获取类列表
没有“-Credential
”参数;如果你需要从远程计算机查询并被要求提供代替凭据,需要通过“Invoke-Command
”发送“Get-CimInstance
”
Get-CimInstance -ClassName Win32_LogicalDisk
Invoke-Command -ScriptBlock { Get-CimInstance -ClassName Win32_Proccess } -ComputerName win8 -Credential DOMAIN\Administrator
多任务后台作业
介绍
PowerShell
的后台作业功能可以将一个命令移至另一个独立的后台线程(一个独立的,Powerhell
后台进程)。该功能使得命令以后台模式运行,这样你就可以使用PowerShell
处理其他任务。
同步和异步执行命令的区别。
- 当在同步模式下运行命令时,可以相应输入请求;当使用后台模式运行命令时,根本就没有机会看到输入请求——实际上,当遇到输入请求时,会停止执行该命令
- 在同步模式下,如果遇到错误,命令会立即返回错误信息;后台模式执行的命令也会产生错误信息,但是你无法立即查看这些信息。如果需要,你必须通过一些机制来获取这些信息
- 在同步模式下,如果忽略了某个的必要参数,PowerShell会提示对应的缺失信息;如果是后台执行的命令,无法提示缺失信息,所有命令会执行失败
- 在同步模式下,当命令开始产生执行结果时,就会立即返回;但是当命令处于后台模式时,你必须等待命令执行结束,才能获取缓存的执行结果
创建本地作业
为了创建这种类型的作业,你需要使用Start-Job
命令。参数-ScriptBlock
使得你可以指定需要执行的命令(一个或多个)。PowerShell
会自动使用默认的作业名称(Job1
、Job2
等)。你可以使用-Name
参数指定特定的作业名称,可以使用-Crendential
参数接收一个域名\用户名(DOMAIN\UserName
)的凭证,同时该参数也会使得提示输入密码。如果没有指定脚本块,可以使用-FilePath
参数来使得作业执行包含多个命令的完整脚本文件。
Start-Job -ScriptBlock { Dir }
Start-Job -ScriptBlock { Get-EventLog Security -ComputerName Server-R2 }
注意:尽管本地作业是在本地运行的,但是它们也需要使用
PowerShell
的远程处理系统架构,所以如果你没有启用远程处理,那么将无法创建本地作业
WMI作业和远程处理作业
创建作业的另一种方法是使用Get-WMIObject
命令。为了将命令置为后台运行模式,像往常一样执行Get-WMIObject
命令,但是需要加上-AsJob
参数。此时,你不能指定一个自定义的作业名称,只能使用PowerShell
指定的默认作业名称。
Get-WMIObject Win32_OperatingSystem -ComputerName( Get-Content allservers.txt) -AsJob
同样的,使用-AsJob
参数添加到Invoke-Command
命令中也可实现作业的创建,但是通过此命令的-JobName
参数可以指定一个特定的作业名称。
Invoke-Command -Command { Get-Process } -ComputerName ( Get-Content .\allservers.txt ) -AsJob -JobName myRemoteJob
获取作业执行结果
Get-Job
这个Cmdlet
可以获取在系统中定义的所有作业,并返回其状态。而使用Receive-Job
命令可以获取一个作业的执行结果。
- 你必须指定希望获取返回结果的对应作业。可以通过作业
ID
、作业名称,或者通过Get-Job
命令获取作业列表后,通过管道传递给Receive-Job
命令 - 如果你获取了父作业的返回结果,那么该结果会包含所有子作业的输出结果。当然,你也可以获取一个或多个子作业执行结果
- 正常情况下,获取一个作业的返回结果后,会自动在作业的输出缓存中清除对应的数据,这样你不能再次获取它们。可以通过
-Keep
参数在内存中保留输出结果的一份拷贝。或者如果你希望保存一份拷贝以作它用,也可以将结果输出到CliXML
中 - 作业的返回结果可以是反序列化的对象,即返回的结果是它们产生时的一个快照,它们可能不会包含可以执行的任何方法。但是如果需要,你可以直接将作业的返回结果通过管道传递给一些
Cmdlet
,比如Sort-Object
、Format-List
、Exprot-CSV
、ConvertTo-HTML
、Out-File
等
Get-Job
# 格式化输出结果
Get-Job -id 1 | Format-List *
Receive-Job -ID 1
# 将结果缓存
Receive-Job -ID 3 -Keep
Receive-Job -Name MyRemoteJob | Sort-Object PSComputerName | Format-Table -GroupBy PSComputerName
注意:当某个作业的输出结果没有被缓存时,对应的
HasMoreData
列为False
以下演示了如何获取子作业。
对应包含多个子作业的情况,可以使用以下命令获取其子命令。
Get-Job -ID 3 | Select-Object -Expand ChildJobs
针对作业,还有另外3
个命令。
- Remove-Job——该命令会移除一个作业,包括从内存中移除该作业缓存的所有输出结果
- Stop-Job——如果某个作业看起来卡住了,你可以通执行该命令停止它。但是仍然可以获取截至到该时刻产生的结果
- Wait-Job——该命令在下面场景中比较有用:当使用一段脚本开启一个作业,同时希望该脚本在作业运行完毕之后继续执行。该命令会使得
PowerShell
停止并等待作业执行,在作业执行结束后,运行PowerShell
继续执行
调度作业
术语调度作业(scheduled jobs
)和调度任务(scheduled tasks
)并不同——前一种是与PowerShell
相关的,后一种是你经常使用的传统作业。
你通过创建一个触发器(New-JobTrigger
)开启一个调度作业,该触发器主要用于定义任务的运行时间。同时,你也可以使用New-ScheduledTaskOption
命令设置作业的选项。之后你使用Register-ScheduledJob
命令将该作业注册到计划任务程序中。该命令采用集合任务程序中的XML
格式来创建任务的定义,之后在磁盘上新建一个层级结构的文件夹存放每次作业运行的结果。
# 每天凌晨2点值Get-Process命令,如果必须则唤醒计算机,同时要求作业运行在高级权限下
Register-ScheduledJob -Name DailyProcList -ScriptBlock { Get-Process } -Trigger ( New-JobTrigger -Daly -At 2am ) -ScheduledJobOption ( New-ScheduledJobOption -WaketoRun -RunElevated)
当移除这些作业,对应的结果也会从磁盘上移除。可以通过Register-ScheduledJob
命令的-MaxResultCount
参数控制存放结果数量。
同时处理多个对象
首先方法:“批处理” Cmdlet
很多PowerShell Cmdlet
可以接收批量对象,或者称之为对象集合。下面是一个使用批处理管理的示例。
Get-Service | Stop-Service
在本例中,Stop-Service
专门被设计用于从管道接收一个或多个服务对象,并停止服务。这就是所谓的“batch Cmdlets
”(这是我们对它的命名,不是官方术语),也是我们批量管理的首先方式。
Get-Service -Name BITS -ComputerName Serv1,Serv2,Serv3 | Start-Service -PassThru | Out-File NewServiceStatus.txt
该命令从三台计算机列表中获取指定服务,然后通过管道将这些服务传递给Start-Service
。该命令不仅会启动服务,而且会将涉及的服务对象打印在屏幕上。然后这些服务对象将会通过管道传递给Out-File
存储到文本文件中。
-PassThru参数用于打印出该命令所接收的对象
CIM\WMI方式:调用方法
不幸的是,总有一些任务无法通过调用Cmdlet
完成。而且有一些我们可以通过Windows管理规范
(WMI)可以操控的条目。
比如WMI
中的Win32_NetworkAdapterConfiguration
类。该类代表与网卡绑定的配置信息,我们想通过命令启用DHCP
,查看下面的示例。
Gwmi Win32_NetworkAdapterConfiguration -Filter "description like '%intel%'" | gm
Gwmi Win32_NetworkAdapterConfiguration -Filter "description like '%intel%'" | EnabledDHCP()
不幸的是,这是无效的。EnabledDHCP
并不是PowerShell
的Cmdlet
,而是直接附加在配置对象自身的行为。但是我们可以使用Invoke-WmiMethod
这个通用的Cmdlet
。
Gwmi Win32_NetworkAdapterConfiguration -Filter "description like '%intel%'" | Invoke-WmiMethod -Name EnabledDHCP
你需要记住以下几点。
- 方法名称后无需加括号
- 方法名称不区分大小写
Invoke-WmiMethod
一次只能接收一种类型的WMI
对象。- 你可以针对
Invoke-WmiMethod
方法加上-WhatIf
和-Confirm
参数。但直接由对象调用方法时,无法使用这些参数
当你由一个WMI
对象包含可执行的方法时,大多可以使用Invoke-WmiMethod
。该命令对远程计算机通用有效。同样的,我们可以使用Invoke-CimMethod
进行替代,并且我们更加建议使用Invoke-CimMethod
命令。
后备计划:枚举对象
总是会有些情况,我们只能通过枚举的方式一个个的处理。PowerShell
提供了两种方法:第一种是使用Cmdlet
,另一种是使用脚本结构。
我们使用Win32_Service
这个WMI
类作为示例。更详细的说是使用Change()
方法。具体示例如下。
Gwmi Win32_Service -Filter "name='BITS'" | Foreach-Object -Process { $_.change($null,$null,$null,$null,$null,$null,$null,"P@ssw0rd")}
让我们把示例中的代码分解说明。
- 首先,你将看到
Cmdlet
名称,ForEach-Object
- 接下来,使用
-Process
参数指定脚本段。其是位置参数,也可以不写,但建议明确写出 ForEach-Object
将会对每个通过管道传输给ForEach-Object
的对象执行脚本段。每次脚本段执行后,下一个通过管道传输进来的对象都会被置于特殊的$_
容器- 通过在
$_
后输入一个“.
”,告诉Shell
我们需要访问当前对象的属性或方法
接下来我们看一下下面的例子,它通过多种方式实现停止某个指定条件下的服务。
# 批处理Cmdlet
Get-Service -Name *B* | Stop-Service
# ForEach-Object
Get-Service -Name *B* | ForEach-Object { $_.Stop() }
# WMI
Get-WmiObject Win32_Service -Filter "name like '%B%'" | Invoke-WmiMethod -Name StopService
# WMI 和 ForEach-Object
Get-WmiObject Win32_Service -Filter "name like '%B%'" | ForEach-Object { $_.Stop() }
# Stop-Service
Stop-Service -Name *B*
从上面的例子中我们也可以看出Cmdlet
和WMI
的重要区别。
- 原生
Cmdlet
过滤条件通常使用“*
”作为通配符,而WMI
过滤使用百分比符号(%
)——请不要将百分比符号和ForEach-Ojbect
别名搞混。这个百分比符号封装在Get-WmiObject
的-Filter
参数内,并不是一个别名 - 原生对象通常和
WMI
有相同的功能,但是语法或许会有不同 - 原生过滤通常使用原生的比较操作符,比如说
-eq
;WMI
使用类似编程语言风格的操作符,比如说=
或者like
那么,何时该使用WMI
方法或者Cmdlet
来完成一个任务呢?这个选择十分简单。
- 如果你通过
Get-WmiObject
获取对象,你将需要通过使用WMI
方法来执行行为。你可以使用Invoke-WmiMethod
或ForEach-Object
方式执行方法 - 如果你通过非
Get-WmiObject
的方式获取对象,你将需要对获取到对象使用原生Cmdlet
。除非你获取到的对象只有方法而没有能够完成任务所需的Cmdlet,你可能会使用ForEach-Object
方式执行方法
注意:到这里的最低标准是
ForEach-Object
:它的语法或许是最难的,但你可以使用它完成几乎所有你需要完成的工作
无论何时都无法将任何对象通过管道传递给一个方法。你只能利用管道将一个Cmdlet
产生的对象传递给另一个Cmdlet
。如果完成任务所需的Cmdlet
不存在,但存在这样的方法,那么你就可以将其通过管道传递给ForEach-Object
并执行对象的方法。
请记住,通过管道将对象传递给Get-Member
,可以查看对象包含的方法。
如图,请重点关注TypeName
,在本例中是Sytem.Service Process.ServcieController
。在搜索引擎中搜索完整的类型名称,你通常可以找到完整的官方开发文档,并可以根据文档找出你所需要的特定方法的文档。
最后,我们来分享一下ForEach-Object
的一些小技巧。
- 多使用
ForEach-Object
的完整名称,而不是使用%
或ForEach
这样的别名。完整名称更易于阅读。如果你使用别人写的示例,请将别名替换为完整名称 - 花括号内的代码段对于每一个通过管道传入的对象执行一次
- 在代码段内,
$_
代表通过管道传入的对象之一 - 使用
$_
本身控制所有通过管道传入的对象;使用$_
后的加“.
”控制单独的方法或属性 - 即使方法不需要任何参数,方法名称之后也总是跟随圆括号。当需要参数时,通过逗号将参数分割放在括号内
安全警报
Windows PowerShell
的安全目标是:
PowerShell
不会给被处理的对象任何额外的权限PowerShell
无法绕过既有的权限PowerShell
的安全并不是针对恶意软件的防护
下面我们具体看有哪些安全措施来实现PowerShell
的安全。
执行策略设置
默认设置是Restricted
,该策略会阻止正常脚本的运行。也就是说,你默认情况下你可以使用PowerShell
进行交互式执行命令,但是不能执行脚本。
你可以通过运行Get-ExecutionPolicy
命令来查看当前执行策略。如果你想修改当前执行策略,可以采用下面3中方式之一。
- 运行
Set-ExecutionPolicy
命令。该命令会修改Windows
注册表中的HKEY_LOCAL_MACHINE
部分,但是需要在管理员权限下才能执行该命令 - 使用组策略对象(GPO)。如下图,我们可以在
“本地计算机策略”=>用户配置=>管理模板=>Windows组件=>Windows PowerShell
中找到相应的设置内容
- 通过手动运行
PowerShell.exe
,并给出-ExecutionPolicy
的命令行开关参数。采用这种方式,那么命令中指定的执行策略会覆盖本地任何设置和组策略中的设置值
你可以执行策略设置为5
种值(请注意:组策略对象中包含下面列表中的3
个选项)。
- Restricted——默认选项,除微软提供的一部分配置
PowerShell
的默认选项脚本外,不允许执行其他任何脚本。这些脚本有微软的数字签名,如果修改了数字签名则也无法执行这些脚本了 - AllSigned——经过受信任的证书颁发机构(
CA
)设计的数字证书签名之后的任意脚本,PowerShell
均可执行 - RemotedSigned——
PowerShell
可以运行本地任何脚本,同时也可以执行受信任的CA
签发的数字证书前面之后的远程脚本 - Unrestricted——可以运行所有脚本,此选项并不建议使用
- Bypass——这个特殊的设定主要是针对应用程序开发任意,他们会将
PowerShell
嵌入到他们的应用程序中。这个设定值会忽略已经配置的执行策略,应当仅在主机应用程序提供了自身的脚本安全层时才使用该选项
微软强烈建议在执行脚本时使用RemoteSigned
执行策略,并且仅在需要执行脚本的机器上采用该策略。
数字代码签名
数字代码签名,简称为代码签名,是指将一个密码签名应用到一个文本文件的过程,签名会显示在文件末端。签名包含了两部分重要信息:一是列出了对脚本签名的公司或组织;二是包含了对脚本的加密副本,并且PowerShell
可以解密该副本。在创建一个签名之前,你需要拥有一个代码签名的证书,该证书也被称为第三方证书,一般由商业CA签发。
一旦你拥有了第三方证书并安装后,可以使用PowerShell
的Set-AuthenticodeSignature
Cmdlet
将该数字签名应用到一段脚本。签名不仅会提供脚本作者的身份信息,也会确保在作者对脚本签名后,不会被他人更改。原理如下:
- 脚本作者持有一个数字证书,该密钥包含两个密钥:一个公钥、一个私钥
- 当对脚本进行签名时,该签名会被私钥加密。私钥仅能被脚本开发者访问,同时仅有公钥能对该脚本进行解密。在签名中会包含脚本的副本
- 当
PowerShell
运行该脚本时,它会使用作者的公钥(包含在签名中)解密该签名。如果解密失败,则说明签名被篡改,那么该脚本就无法被运行。如果签名中的脚本副本与明文文本不吻合,那么该签名就会识别为损坏,该脚本也无法被运行
其他安全措施
首先,Windows
不会将PS1
文件扩展名是为可执行文件类型。双击PS1
文件,默认使用记事本打开进行编辑,不会被执行。其次,在Shell
中不能通过键入脚本名称执行该脚本,Shell
不会在当前目录中搜索脚本。只有通过绝对路径或者相对路径来运行脚本文件,这样做的目的是为了防止称为“命令劫持”的攻击类型。在攻击中,它会将一个脚本文件放入到文件夹中,然后将它命名为某些内置的命令名,如:dir
。
扩展命令
扩展:找到并添加插件
PowerShell
存在两种类型的扩展:模块和管理单元。首先讲述管理单元。
一个合适管理单元PowerShell
的名称是PSSnapin
,用于区别这些来自管理单元的图形MMS
。一个PSSnapin
通常包含一个或多个DLL
文件,同时包含配置XML
文件和帮助文档。PSSnapin
必须先安装并注册,然后PowerShell
才能识别它的存在。
了解:通常PSSnapin的相关命令有——
Get-PSSnapin
、Add-PSSnapin
等
PSSnapin的概念逐渐被微软移除了,将来可能会越来越少。在内部,微软的重点是提供扩展模块。
扩展:找到并添加模块
PowerShell v2
之后提供了模块。模块被设计的更加独立,因此更容易分发,但是它的工作原理类似与PSSnapin
。模块不需要复制的注册。PowerShell
会自动在一个特定的目录下查找模块。PSModulePath
这个关键变量定义了PowerShell
期望存放模块的路径。对于新的模块路径,可以考虑添加到此变量中。当然也可以考虑使用Import-Module
命令并指定完整的模块路径进行添加。
Get-Content env:PSModulePath
可以通过
Get-Module
命令查看当前计算机上已经存在的模块
PowerShell
会在磁盘中几个默认位置搜索模块,不同种类的模块位于不同的位置。
-
系统模块:
PowerShell
默认安装的模块大部分位于C:\Windows\System32\WindowsPowerShell\v1.0\Modules
文件夹中。这个路径通常是PowerShell
内部模块装用的。虽然可以将自己些的模块放到这个里面,但是不建议。 -
所有用户模块:此部分的文件夹位置是
C:\Program Files\WindowsPowerShell\Modules
。这个路径中的模块针对所有用户,如果想让计算机上的所有用户使用,可以将模块放在此文件夹中。 -
当前用户模块:此部分文件夹位置是
C:\Users\<loggedInUsers>\Documents\WindowsPowerShell\Modules
。不管是自己些的还是下载的,放在此文件夹就只有当前登录的用户可用,对于多个计算机用户来说,有一定的隔离作用。
PowerShell模块的构成
-
.psm1
格式文件:此扩展名的文件都可以是PowerShell
模块。当然,文件中需要定义函数。通常,一个文件中的函数都是围绕一个主题了。 -
模块清单文件(
module manifest
):扩展名称为.psd1
,此文件不是必须的,但是建议提供。这是使用PowerShell
哈希表格式编写的文本文件,哈希表中的元素用于描述模块的元数据。
此文件可以手动创建,也可以使用New-ModuleManifest
命令生成模板
New-ModuleManifest 'e:\so.psd1' -Author 'Adam Bertram' -RootModule so.psm1 -Description 'This module helps in deploying software.'
生成内容如下。
#
# 模块“so”的模块清单
#
# 生成者: Adam Bertram
#
# 生成时间: 2024/1/4
#
@{
# 与此清单关联的脚本模块或二进制模块文件。
RootModule = 'so.psm1'
# 此模块的版本号。
ModuleVersion = '1.0'
# 支持的 PSEditions
# CompatiblePSEditions = @()
# 用于唯一标识此模块的 ID
GUID = '6adb5eb0-68e5-47a4-a8cc-6ba81131933c'
# 此模块的作者
Author = 'Adam Bertram'
# 此模块所属的公司或供应商
CompanyName = '未知'
# 此模块的版权声明
Copyright = '(c) 2024 Adam Bertram。保留所有权利。'
# 此模块所提供功能的说明
Description = 'This module helps in deploying software.'
# 此模块要求的 Windows PowerShell 引擎的最低版本
# PowerShellVersion = ''
# 此模块要求的 Windows PowerShell 主机的名称
# PowerShellHostName = ''
# 此模块要求的 Windows PowerShell 主机的最低版本
# PowerShellHostVersion = ''
# 此模块要求使用的最低 Microsoft .NET Framework 版本。此先决条件仅对 PowerShell Desktop 版本有效。
# DotNetFrameworkVersion = ''
# 此模块要求使用的最低公共语言运行时(CLR)版本。此先决条件仅对 PowerShell Desktop 版本有效。
# CLRVersion = ''
# 此模块要求的处理器体系结构(无、X86、Amd64)
# ProcessorArchitecture = ''
# 必须在导入此模块之前先导入全局环境中的模块
# RequiredModules = @()
# 导入此模块之前必须加载的程序集
# RequiredAssemblies = @()
# 导入此模块之前运行在调用方环境中的脚本文件(.ps1)。
# ScriptsToProcess = @()
# 导入此模块时要加载的类型文件(.ps1xml)
# TypesToProcess = @()
# 导入此模块时要加载的格式文件(.ps1xml)
# FormatsToProcess = @()
# 将作为 RootModule/ModuleToProcess 中所指定模块的嵌套模块导入的模块
# NestedModules = @()
# 要从此模块中导出的函数。为了获得最佳性能,请不要使用通配符,不要删除该条目。如果没有要导出的函数,请使用空数组。
FunctionsToExport = '*'
# 要从此模块中导出的 cmdlet。为了获得最佳性能,请不要使用通配符,不要删除该条目。如果没有要导出的 cmdlet,请使用空数组。
CmdletsToExport = '*'
# 要从此模块中导出的变量
VariablesToExport = '*'
# 要从此模块中导出的别名。为了获得最佳性能,请不要使用通配符,不要删除该条目。如果没有要导出的别名,请使用空数组。
AliasesToExport = '*'
# 要从此模块导出的 DSC 资源
# DscResourcesToExport = @()
# 与此模块一起打包的所有模块的列表
# ModuleList = @()
# 与此模块一起打包的所有文件的列表
# FileList = @()
# 要传递到 RootModule/ModuleToProcess 中指定的模块的专用数据。这还可能包含 PSData 哈希表以及 PowerShell 使用的其他模块元数据。
PrivateData = @{
PSData = @{
# 应用于此模块的标记。这些标记有助于在联机库中执行模块发现。
# Tags = @()
# 指向此模块的许可证的 URL。
# LicenseUri = ''
# 指向此项目的主网站的 URL。
# ProjectUri = ''
# 指向表示此模块的图标的 URL。
# IconUri = ''
# 此模块的 ReleaseNotes
# ReleaseNotes = ''
} # PSData 哈希表末尾
} # PrivateData 哈希表末尾
# 此模块的 HelpInfo URI
# HelpInfoURI = ''
# 从此模块中导出的命令的默认前缀。可以使用 Import-Module -Prefix 覆盖默认前缀。
# DefaultCommandPrefix = ''
}
从Internet获取模块
微软引入了一个名称为PowerShellGet
的模块,这使得从在线仓库中搜索、下载、安装、升级模块变的容易。微软甚至还维护了一个在线源,称为PowerShell Gallery(http://powershellgallery.com)。
使用步骤:
-
运行
Register-PSReporsitory
添加要给源的URL
。默认如上 -
使用
Find-Module
在源中查找模块。你可以在名称、特定标签等列中使用通配符缩写搜索范围 -
找到所需模块后,使用
Install-Module
下载与安装 -
使用
Update-Module
确保你的模块的副本是最新的,如不是则下载更新并安装 -
使用
Remove-Module
删除模块,使用Uninstall-Module
命令从磁盘中卸载/删除模块
# 查看
Get-Command -Module PowerShellGet
# 查找
Find-Module -Name *VMware*
# 安装
Find-Module -Name VMware.PowerCLI | Install-Module
最后,如果要创建我们自己的模块。记住,PowerShell模块通常由文件夹(模块容器)、 .psm1文件(模块)和.psd1文件(模块清单文件)构成。其中,模块文件夹的名称必须和模块本身的名称相同。放在上面介绍的三个位置的任意一个地方,使用Get-Module
命令即可查看到自定义的模块及相应的命令。
总结
以上是对PowerShell
基本知识的深入介绍,在接下来的章节中我们将介绍PowerShell
的远程部分。