如何调查 powershell 中的未知方法?

How to investigate an unknown method in powershell?

我正在自学 Powershell。关于最常见的事情有大量的信息,但是当我遇到一个稍微过于具体的事情时,我要么按照别人之前的步骤,要么我迷路了。例如,我不知道如何获得特定方法的帮助。我会以我目前的情况为例,但是问题是关于任何情况,而不仅仅是这个。

我正在尝试自动执行某些 Internet Explorer 浏览,为此我正在使用 this 指南。 但是,它仅显示 GetElementsByTagName 上的示例。我已经知道如何使用 Get-Member所以我按照他的代码是这样的:

$ie = new-object -ComObject "InternetExplorer.Application"
$ie.silent = $true
$ie.navigate($requestUri)
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
$doc = $ie.Document

之后我使用 Get-Member -InputObject $doc,所以我知道所有可能的方法,并且我看到了我需要的方法:GetElementByID。我尝试这样使用它:

PS C:\Users\Myuser> $main=$doc.getElementById("main")

Cannot find an overload for "getElementById" and the argument count: "1".
At line:1 char:1
+ $main=$doc.getElementById("main")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest

我知道它需要不止一个参数,但我不知道如何获取或找到有关它的任何文档。

如果您想知道 function/method 做什么以及它期望什么,您会怎么做?

对于 cmdlet,我查找了 cmdlet 在线文档(您可以查看 https://docs.microsoft.com 或 google 它)。获取大多数 cmdlet 的联机文档的快捷方式是使用 Get-Help cmdlet -Online。例如:

Get-Help Start-Process -Online

如果您愿意,您也可以使用 help 别名代替 Get-Help

对于 .NET classes 我也使用 https://docs.microsoft.com,但为了确保您获得正确的 class 和成员,我将搜索全名包括命名空间 (您可以在将对象通过管道传输到 Get-Member 时看到这一点。从 class 文档中,您可以导航到该 class 的成员文档。

对于 WMI classes,我还再次查看了 https://docs.microsoft.com,搜索 WMI class 名称,并导航到归因于该名称的任何成员属性或函数 class.

当然,这一切都假设您正在寻找有关 Microsoft 构造的信息。如果您要查找第三方库文档,则需要参考该第三方的文档。

一般来说,如果您不太确定在哪里可以找到关于某事的 API 文档,尝试通过任何搜索引擎进行搜索的一个好方法是 "LIBRARYNAME api documentation",其中 LIBRARYNAME可以是您要为其查找文档的库或 class。通常您会在前几次点击中找到相关内容。

PowerShell 提供了一种非常方便的方法来检查方法甚至构造函数签名(重载):

只需访问不带括号的方法名称,PowerShell 就会显示为此方法定义的所有重载(签名); .例如:

# Method 
PS> 'foo'.ToUpper  # Inspect the .ToUpper() method - NO () at the end.

OverloadDefinitions
-------------------
string ToUpper()
string ToUpper(cultureinfo culture)

# Constructors, via a type literal (`[...]`) and its pseudo static new() method:
PS> [xml]::new  # Constructors for [xml] (System.Xml.XmlDocument)

OverloadDefinitions
-------------------
xml new()
xml new(System.Xml.XmlNameTable nt)

此技术通常也适用于 COM 对象,例如您的情况:

$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate('http://example.org')
$ie.Document.getElementById  # Get signatures for .getElementById()

在 Windows PowerShell v5.1 on Windows 10 中产生(删节):


OverloadDefinitions                                                                                                                                                                
-------------------                                                                                                                                                                
mshtml.IHTMLElement ... getElementById(string v)                                               
mshtml.IHTMLElement ... DispHTMLDocument.getElementById(string v)                              
mshtml.IHTMLElement ... IHTMLDocument3.getElementById(string v)                                                                                                                                                                                                                   

警告:对于一些 COM 对象签名是在之前的 PowerShell Core v7版本中列出没有参数名称,这可以使它更难理解它的作用。

例如,COM 自动化服务器 WScript.Shell 受到影响:

Windows PowerShell 和 PowerShell 核心 6.x:

PS> (New-Object -ComObject WScript.Shell).Popup

OverloadDefinitions
-------------------
int Popup (string, Variant, Variant, Variant)  # !! No parameter names.

在 PowerShell Core 7.0(预览版 5)中:

PS> (New-Object -ComObject WScript.Shell).Popup

OverloadDefinitions
-------------------
int Popup (string Text, Variant SecondsToWait, Variant Title, Variant Type) # OK