PowerShell IE9 ComObject имеет все нулевые свойства после перехода на веб-страницу

У меня есть сценарий 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

Когда я исследую в PowerShell, я обнаруживаю, что если я создаю IE ComObject, он сначала имеет допустимые свойства, но как только я перехожу на страницу управления сервисом, все свойства становятся нулевыми (почти как если бы ComObject исчез?). Например, перед HWND свойство имело допустимое значение, но теперь оно равно нулю ($ie.hwnd -eq $null возвращает истину). При переходе на страницу не отображается ошибка в PowerShell.

Я посмотрел на некоторые похожие вопросы, но первый не соответствует моим обстоятельствам (Document свойство равно нулю в моем случае), а что касается последнего, IE9 по умолчанию работает в режиме совместимости для сайтов интрасети. Я сохранил страницу ASP и запустил ее через валидатор w3c, и он выдал некоторые ошибки (хотя ни один из них не связан с элементами, с которыми я пытаюсь разобраться). К сожалению, я не могу это исправить. Другие сайты, похоже, не имеют этой проблемы. Есть какие-то подозрения в том, что проблема может быть и рекомендации по обходным путям?

2 ответа

Решение

Я просто работал через это.. вроде. Я видел такое же поведение, пока не отключил защищенный режим в IE. Похоже, это как-то связано с отправкой из одной зоны безопасности в другую. Итак... при условии, что ваша исходная страница находится в зоне интернета с включенным защищенным режимом, вы отправляете страницу в доверенную зону или интранет или что-то еще, кажется, что контекст COM потерян. Вероятно, намеренный. Я собираюсь попробовать исправить зоны и оставить защищенный режим включенным.

Надеюсь это поможет.

РЕДАКТИРОВАТЬ: Это также не проблема, если вы запускаете PowerShell в режиме повышенных прав (запуск от имени администратора)

Кроме того: http://msdn.microsoft.com/en-us/library/bb625962.aspx

Эта проблема вызвана уровнями целостности начиная с Internet Explorer 8. Это также причина, почему приложение работает хорошо как администратор.

Поскольку IE-8 работает в режиме "низкой целостности", автоматизировать IE из скрипта невозможно. Это потому, что скрипт запускается как пользователь, который относится к режиму "средней целостности". Конструкция безопасности такова, что она может отправлять инструкции от средней до низкой целостности, но не может принимать данные от низкой до средней целостности.

Обновление: вот рабочий пример, как это сделать без изменения каких-либо настроек. Возвращает потерянный ком-объект.

 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
Другие вопросы по тегам