在之前的一个技能中我们介绍了如何用 Get-Member 获取对象的属性。以下是另一个可以传入任何对象,将它转为一个包含排序属性的哈希表,然后排除所有空白属性的用例。
1 | # take an object... |
在之前的一个技能中我们介绍了如何用 Get-Member 获取对象的属性。以下是另一个可以传入任何对象,将它转为一个包含排序属性的哈希表,然后排除所有空白属性的用例。
1 | # take an object... |
In the previous tip we explained how you can dump all the legal values for a PowerShell attribute. Today we’ll take a look at the [Parameter()] attribute and its value DontShow. Take a look at this function:
在前一个技能中我们介绍了如何导出一个 PowerShell 属性的所有合法值。今天我们将关注 [Parameter()] 属性和它的值 DontShow。我们来看看这个函数:
1 | function Test-Something |
当您运行这个函数时,IntelliSense 只暴露 -Name 参数。-Internal switch 参数并没有显示,然而您仍然可以使用它。它只是一个隐藏的参数:
1 | PS> Test-Something -Name tobias |
PowerShell 技能连载 - 探索 PowerShell 属性值
您也许知道,您可以对变量和参数添加属性来更有针对性地定义它们。例如,以下代码定义了一个包含只允许三个字符串之一的必选参数的函数:
1 | function Test-Attribute |
如果您想知道这些属性有哪些选择,以下是实现方法。您所需要了解的是代表属性的真实名称。PowerShell 自身的属性都位于 System.Management.Automation 命名空间。以下是两个最常用的:
1 | [Parameter()] = [System.Management.Automation.ParameterAttribute] |
要查看某个指定属性的合法数值,只需要实例化一个制定类型的对象,并查看它的属性:
1 | [System.Management.Automation.ParameterAttribute]::new() | |
这将返回一个包含所有 [Parameter()] 属性所有合法属性值的列表:
DontShow
HelpMessage
HelpMessageBaseName
HelpMessageResourceId
Mandatory
ParameterSetName
Position
TypeId
ValueFromPipeline
ValueFromPipelineByPropertyName
ValueFromRemainingArguments
当您向每个值添加期望的数据类型时,该列表就更有用了:
1 | [System.Management.Automation.ParameterAttribute]::new() | |
现在它看起来类似这样:
1 | Name Type |
例如这是 [CmdletBinding()] 的列表:
1 | [System.Management.Automation.CmdletBindingAttribute]::new() | |
大多数 PowerShell 函数使用静态参数。它们是定义在 param() 代码块中的,并且始终存在。一个不太为人所知的情况是您也可以快速地编程添加动态参数。动态参数的最大优势是您可以完全控制它们什么时候可以出现,以及它们可以接受什么类型的数值。它的缺点是需要使用大量底层的代码来“编程”参数属性。
以下是一个示例函数。它只有一个名为 “Company“ 的静态参数。仅当您选择了一个公司,该函数才会添加一个名为 “Department“ 的新的动态参数。新的动态参数 -Department 根据选择的公司暴露出一个可用值的列表。实质上,根据选择的公司,-Department 参数被关联到一个独立的 ValidateSet 属性:
1 | function Test-Department |
请注意!当您在选择的编辑器中键入 Test-Department,初始情况下只有一个参数:Tbc-Company。当您选择了四个可用得公司之一,第二个参数 -Department 将变得可用,并且显示当前选中的公司可用的部门。
通常情况下,通过 PowerShell 的 Invoke-WebRequest 命令来获取原始的 HTML 网站内容是很常见的情况。脚本可以处理 HTML 内容并对它做任意操作,例如用正则表达式从中提取信息:
1 | $url = "www.tagesschau.de" |
然而,有些时候一个网站的内容是通过客户端脚本代码动态创建的。那么,Invoke-WebRequest` 并不能返回浏览器中所见的完整 HTML 内容。如果仍要获取 HTML 信息,您需要借助一个真实的 WEB 浏览器。一个简单的方法是使用内置的 Internet Explorer:
1 | $ie = New-Object -ComObject InternetExplorer.Application |
个别情况下,您可能会希望创建一个可以接受不同参数类型的函数。假设您希望用户既可以传入一个雇员姓名,也可以传入一个 Active Directory 对象。
在 PowerShell 中有一个固定的原则:变量不能在同一时刻有不同的数据类型。由于参数是变量,所以一个指定的参数只能有一个唯一的类型。
然而,您可以使用参数集来定义互斥的参数,这是一种解决多个输入类型的好方法。以下是一个既可以输入服务名,也可以输入服务对象的示例函数。这基本上是 Get-Service 内部的工作原理,以下示例展示了它的实现方式:
1 | function Get-MyService |
我们看看该函数的使用:
1 | PS> Get-MyService -Name spooler |
如您所见,用户可以传入一个服务名或是 Service 对象。Get-MyService 函数模仿 Get-Service 内部的实现机制,并且返回一个 Service 对象,无论输入什么类型。以下是上述函数的语法:
1 | **Syntax** |
PowerShell 技能连载 - 将 VBScript 翻译为 PowerShell
大多数旧的 VBS 脚本可以容易地翻译为 PowerShell。VBS 中关键的命令是 “CreateObject“。它能让您操作系统的库。PowerShell 将 “CreateObject“ 翻译为 “New-Object -ComObject“,而对象模型和成员名称保持相同:
当把这段代码保存为扩展名为 “.vbs” 的文本文件后,这段 VBS 脚本就可以发出语音:
1 | Set obj = CreateObject("Sapi.SpVoice") |
对应的 PowerShell 代码类似这样:
1 | $obj = New-Object -ComObject "Sapi.SpVoice" |
只有少量的 VBS 内置成员,例如 MsgBox 或 InputBox。要翻译这些代码,您需要引入 “Microsoft.VisualBasic.Interaction“ 类型。以下是调用 MsgBox 或 InputBox 的 PowerShell 代码:
1 | Add-Type -AssemblyName Microsoft.VisualBasic |
以下是支持的 Visual Basic 成员的完整列表:
1 | PS> [Microsoft.VisualBasic.Interaction] | Get-Member -Stati |
PowerShell 技能连载 - 通过 PowerShell 调用 Excel 宏
PowerShell 可以调用 Microsoft Excel 工作表,并执行其中的宏。由于这只对可见的 Excel 程序窗口有效,所以当您尝试进行安全敏感操作,例如宏时,最好保持 Excel 打开(参见以下代码)来查看警告信息:
1 | # file path to your XLA file with macros |
PowerShell 技能连载 - 编程列出所有 Cmdlet 或函数参数的列表
是否曾好奇如何列出一个函数或 cmdlet 暴露出的所有属性?以下是实现方法:
1 | Get-Help Get-Service -Parameter * | Select-Object -ExpandProperty name |
Get-Help 提供了一系列关于参数的有用的信息和元数据。如果您只希望转储支持管道输入的参数,以下是实现方法:
1 | Get-Help Get-Service -Parameter * | |
“pipelineInput“ 属性暴露了通过管道接收到的一个属性的类型。不幸的是,它包含了一个本地化的字符串,所以一个区分的好方法是取字符串的长度。
输出的结果类似这样,并且可以从管道上游的命令中接受管道的输入,以及接受数据类型:
1 | name pipelineInput parameterValue |
当您用 Import-Csv 将一个 CSV 列表导入 PowerShell,或用任何其它类型的对象来处理时:如何自动确定对象的属性?以下是一个简单的方法:
1 | # take any object, and dump a list of its properties |
为什么这种方法有用?有许多使用场景。例如,您可以检测一个注册表键的名称,支持用通配符转储所有的命令:
1 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" |