Назад | Перейти на главную страницу

Как заставить PowerShell обновлять кешированные данные? Результаты Get-ChildItem для PSDrive не актуальны

Import-Module WebAdministration
$pool = "ChannelServices"
$wp = Get-ChildItem "IIS:\AppPools\$pool\WorkerProcesses"
Get-Process -Id $wp.processId
Restart-WebAppPool $pool
sleep 5
Get-ChildItem "IIS:\AppPools\$pool\WorkerProcesses"
Get-Process -Id $wp.processId

Поэтому, когда я выполняю Get-ChildItem для рабочих процессов определенного пула приложений, а затем перезапускаю этот пул приложений, я должен получить новый PID, что я и делаю. Однако при повторном запуске Get-ChildItem по-прежнему отображается старый PID. Если я закрою Powershell и снова открою, он не покажет правильный новый PID.

Как я могу заставить Powershell очистить кеш или что-то еще, что хранит эту неверную информацию ...

ОБНОВИТЬ Чтобы быть ясным, мой вопрос: как очистить локальный кеш при использовании IIS PSDrive.

Я заметил TypeName: Microsoft.IIs.PowerShell.Framework.ConfigurationElement # workerProcesses # workerProcess

Имеет метод: Имя MemberType Определение
---- ---------- ----------
ClearLocalData Method void ClearLocalData ()

Но на самом деле это не сработало для меня ... Как кто-то сказал ниже, это может быть просто ошибкой.

Ниже я вижу ответы о том, как использовать WMI, о которых я знаю.

@theJasonHelmick предоставил хороший вариант:

GWMI win32_process -filter "name='w3wp.exe'" | Select Name, ProcessId, @{n='AppPool';e={$_.GetOwner().user}}

Это дает мне имя пользователя, под которым работает AppPool. Я немного изменил это, чтобы извлечь фактическое имя пула приложений из CommandLine:

Get-WmiObject -Class win32_process -filter "name='w3wp.exe'" | Select Name, ProcessId, @{n='AppPool';e={($_.CommandLine).Split("`"")[1]}}

Я мог бы воспроизвести это поведение на IIS 8.5, мне это кажется ошибкой.

Использование WMI сработало для меня в том же сеансе PowerShell, где Get-ChildItem вернул устаревший PID

(gwmi -NS 'root\WebAdministration' -class 'WorkerProcess' | ? AppPoolName -eq $pool | Select -First 1).ProcessId

Это вернуло правильный pid для первого WorkerProcess

Если вам нужно обновить кеш рабочих процессов, вы можете просто удалить и снова импортировать модуль веб-администрирования.

Remove-Module WebAdministration
Import-Module WebAdministration

Вероятно, не лучшее решение, чем то, которое использует WMI, но если по какой-то причине у вас нет доступа к объектам IIS WMI или вы не можете их установить, это сработает.

Если я чего-то полностью не упустил, я предполагаю, что вы сохраняете первый процесс получения в переменной $wp тогда повторная ссылка на переменную вернет старые данные?

Что делать, если вы выполните одно из:

  • второй раз работает get-childitem снова хранить в $wp (перезаписывая значение)?
  • удалите переменную перед ее повторным использованием:

    удалить переменную wp

  • хранить второй get-childitem в переменной с совершенно другим именем?

Я большой поклонник remove-variable я, поскольку старые ценности действительно могут вызвать неожиданные странности.


[РЕДАКТИРОВАТЬ] Ответ Питера Хандорфа кажется альтернативой, одобренной Microsoft, хотя сейчас я потерял ссылку для этого. Но поскольку причина такого поведения действительно кажется возможной ошибкой, я просто дополню следующее:

Этот парень похоже, решила проблему утилизации пулов приложений наиболее эффективным образом с помощью C #. Если скорость имеет существенное значение (WMI обычно требует много времени), например, если нужно выполнить большое количество циклов за короткий промежуток времени, на это стоит обратить внимание.

Перенести решение на Powershell не так уж сложно, если просто загрузить %WinDir%\system32\Inetsrv\Microsoft.Web.Administration.dll сначала в оболочку, чтобы получить доступ к пространству имен.

Исходная точка отсчета для кода, похоже, исходит от Microsoft. Вот.

Отвечаю на старый вопрос, так как это главное в поиске Google моей проблемы и не имеет моего решения.

Я просматриваю файл на предмет обновлений и использую Get-ChildItem, чтобы получить ссылку на него.

$output = Get-ChildItem -Path $path -File $file | Where-Object -FilterScript {($_.LastWriteTime -gt $DateNow)}

Я просто повторяю строку выше каждый раз, когда хочу обновить $ output

Хотя я знаю, что размер файла увеличивается, $ output.length останется. Было бы хорошо, если бы я нажал F5 в каталоге.

Использование $ output.refresh обновляет объект без необходимости его повторного назначения.