导航到网页后,PowerShell IE9 ComObject具有所有空属性

导航到网页后,PowerShell IE9 ComObject具有所有空属性,powershell,internet-explorer-9,Powershell,Internet Explorer 9,我有一个PowerShell脚本,它可以导航到我们内部网上的一个(大概是)经典ASP页面,以停止服务器上运行的Windows服务,作为该服务部署过程的一部分(并在部署新文件后重新启动)。它运行良好,直到我们最近升级到IE9。这是剧本 # Open service page in IE $ie = new-object -comobject InternetExplorer.Application $ie.visible = $true $ie.navigate($serviceUrl) whil

我有一个PowerShell脚本,它可以导航到我们内部网上的一个(大概是)经典ASP页面,以停止服务器上运行的Windows服务,作为该服务部署过程的一部分(并在部署新文件后重新启动)。它运行良好,直到我们最近升级到IE9。这是剧本

# Open service page in IE
$ie = new-object -comobject InternetExplorer.Application
$ie.visible = $true
$ie.navigate($serviceUrl)
while($ie.busy) { start-sleep 1 }

# Stop service
$ie.Document.getElementById("dropDownActionList").value = "Stop"
$ie.Document.getElementById("buttonTakeAction").click()
while($ie.busy) { start-sleep 1 }
现在,当我运行脚本时,它成功启动IE,但抛出以下错误:

You cannot call a method on a null-valued expression.
At C:\Projects\ABC\Scripts\Deploy.ps1:85 char:28
+ $ie.Document.getElementById <<<< ("dropDownActionList").value = "Stop"
    + CategoryInfo          : InvalidOperation: (getElementById:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
不能对空值表达式调用方法。
在C:\Projects\ABC\Scripts\Deploy.ps1:85 char:28

+$ie.Document.getElementById我刚刚完成了这个。。某种程度上。在关闭IE中的保护模式之前,我一直看到相同的行为。这似乎与从一个安全区域提交到下一个安全区域有关。所以假设您的原始页面位于internet区域,并且启用了“保护”模式,您将提交到受信任区域或intranet或其他位置的页面,那么COM上下文似乎丢失了。可能是故意的。我将尝试修复区域,并保持保护模式打开

希望这有帮助

编辑:如果您在提升模式下运行powershell(以管理员身份运行),这也不是问题。此外:

此问题是由Internet Explorer 8之后的完整性级别引起的。 这也是应用程序以管理员身份运行良好的原因

由于IE-8在“低完整性”模式下运行,因此无法从脚本中自动执行IE。这是因为脚本以属于“中等完整性”模式的用户身份运行。安全设计是这样的,它可以从中到低完整性发送指令,但不能从低到中完整性接收数据

更新:下面是一个如何在不更改任何设置的情况下进行更新的工作示例。它会找回丢失的com对象

 function ConnectIExplorer() {
    param($HWND)

    $objShellApp = New-Object -ComObject Shell.Application 
    try {
      $EA = $ErrorActionPreference; $ErrorActionPreference = 'Stop'
      $objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
      $objNewIE.Visible = $true
    } catch {
      #it may happen, that the Shell.Application does not find the window in a timely-manner, therefore quick-sleep and try again
      Write-Host "Waiting for page to be loaded ..." 
      Start-Sleep -Milliseconds 500
      try {
        $objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
        $objNewIE.Visible = $true
      } catch {
        Write-Host "Could not retreive the -com Object InternetExplorer. Aborting." -ForegroundColor Red
        $objNewIE = $null
      }     
    } finally { 
      $ErrorActionPreference = $EA
      $objShellApp = $null
    }
    return $objNewIE
  } 




$HWND = ($objIE = New-Object -ComObject InternetExplorer.Application).HWND
$objIE.Navigate("https://www.google.com")
$objIE = ConnectIExplorer -HWND $HWND

哇,就是这样!在“设置”中的“安全”选项卡下为Internet区域打开“保护模式”就成功了。然而,由于我将把这个脚本放在其他人的存储库中,我可能不得不使用管理技巧。谢谢@JeffBridgman,你也可以把你想要的网站放在一个不同的,值得信任的区域。但只对我来说,不是对其他人来说,嗯?该站点位于已关闭保护模式的“我的intranet”区域中。看起来IE是在Internet区域启动的,并且启用了保护模式。我尝试将我的主页设置为内联网区域中的某个位置,但奇怪的是,脚本仍然失败。哇,你救了我的命!我以为我的代码中有错误,但正是这个解决方案帮了我的忙!谢谢你,先生:)我已经用解决这个问题的方法更新了我的答案。尝试了这个方法,但没有找到过程。另外,新流程有不同的HWND,因此我不知道如何找到正确的流程。嗯,对我来说,这很有效。你有哪个IE版本?我已经用上面的代码重新测试了它。当我在脚本之后打印出
$objIE
时,我得到了正确的对象。