web-dev-qa-db-ja.com

powershellにキャッシュデータを強制的に更新させる方法は? PSDriveのGet-ChildItemの結果が最新ではありません

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

したがって、特定のAppPoolのWorkerProcessesに対してGet-ChildItemを実行してから、そのAppPoolを再起動すると、新しいPIDを取得する必要があります。ただし、Get-ChildItemを再実行しても、古いPIDが表示されます。 Powershellを閉じて再度開くと、正しい新しいPIDが表示されません。

どうすればPowershellにキャッシュ、またはその誤った情報を保持しているものを強制的にクリアさせることができますか...

Shows how Get-ChildItem is not updating with the new PID.

[〜#〜] update [〜#〜]明確にするために、IIS PSDriveを使用しているときにローカルキャッシュをクリアするにはどうすればよいですか?.

TypeNameに気づきました:Microsoft.IIs.PowerShell.Framework.ConfigurationElement#workerProcesses#workerProcess

メソッドがあります:名前MemberType定義
---- ---------- ----------
ClearLocalDataメソッド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]}}
3
Jim March

この動作をIIS 8.5で再現できました。バグのようです。

Get-ChildItemが古いPIDを返したのと同じPowerShellセッションで、WMIを使用するとうまくいきました

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

これは最初のWorkerProcessの正しいPIDを返しました

3
Peter Hahndorf

これは私の問題に対するGoogle検索の最上位であり、私の解決策がないため、古い質問に答えます。

ファイルの更新を監視しており、Get-ChildItemを使用してファイルへの参照を取得しています。

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

$ outputを更新するたびに、上の行を繰り返すだけです

ファイルのサイズが大きくなっていることはわかっていますが、$ output.lengthが残ります。ディレクトリでF5キーを押しても問題ありません。

$ output.refreshを使用すると、オブジェクトを再割り当てする必要なしにオブジェクトが更新されました。

1
Paul Allen

ワーカープロセスのキャッシュを更新する必要がある場合は、Web管理モジュールを削除して再度インポートするだけです。

Remove-Module WebAdministration
Import-Module WebAdministration

おそらく、WMIを使用するソリューションとしては最適ではありませんが、何らかの理由でIIS WMIオブジェクトにアクセスできないか、それらをインストールできない場合、これは機能します。

1
maomoa

私が完全に何かを見落としているのでなければ、最初のget-processを変数$wpに格納してから、変数を再度参照すると古いデータが返されると思いますか?

次のいずれかを実行するとどうなりますか?

  • 2回目の実行でget-childitemが再び$wpに格納されます(値を上書きします)?
  • 変数を再度使用する前に消去します。

    変数の削除wp

  • 2番目のget-childitemを完全に異なる名前の変数に保存しますか?

私はremove-variableの大ファンです。古い値は本当に予期しない奇妙さを引き起こす可能性があるからです。


[編集]ピーターハーンドルフの答えは、Microsoftが承認した代替案のようですが、リンクを誤って配置しました。しかし、動作の原因は確かにバグの可能性があるように思われるため、以下を補足します。

この男 は、C#を使用して最も効率的な方法でアプリケーションプールをリサイクルする問題を解決したようです。短時間で大量のリサイクルを行わなければならない場合など、速度が重要な場合(WMIは通常、時間のかかる側です)、これは一見の価値があります。

最初に%WinDir%\system32\Inetsrv\Microsoft.Web.Administration.dllをシェルにロードして名前空間にアクセスするだけの場合、ソリューションをPowershellに移植することはそれほど難しくありません。

コードの元の参照ポイントはMicrosoft here から来ているようです。

1
ErikE