web-dev-qa-db-ja.com

システムコンテキストでgpupdateを実行するとメモリにスタックします

ConfigMgr(SCCM)クライアントを介してスクリプトを介してPowerShellを実行する際に興味深い問題が発生しました。 SCCM Current Branchの比較的新しい機能の1つは、SCCMエージェントを介してターゲットノードでPowerShellスクリプトをリアルタイムで実行する機能です。このエージェントは、 SYSTEMコンテキストと私は、複数のマシンのSCCM管理コンソールから同時に実行できるユーティリティスクリプトをいくつか作成しました。

現在開発中のPSスクリプトは、コンピューターとログオンユーザーの両方のGPOをGPUpdateすることになっています。ポリシーのコンピューター部分は、SYSTEMコンテキストを通じて正常に機能します。ただし、GPOのユーザー部分をgpupdateするには、タスクスケジューラコードを使用して、ログオンユーザーとして実行します。

期待どおりに動作しますがユーザーのGPUpdateプロセスは引き続きメモリに残ります。これは、理由を理解するのに苦労していました

次に、ユーザーがGPUpdateの最後にcmdコンソールに表示するログオフプロンプト(クライアント側GPO拡張処理を完了するため))が原因である可能性があることに気付きました。手動で実行します。少なくともこの段階での私の仮説ですが、深く掘り下げる方法がわかりません。

私のスクリプトはこのSCCMエージェント「サンドボックス」内で実行されており、ユーザーコンテキストGPupdateを実行する別のPowershellが起動するため、「いいえ」の答えが得られる方法があるかどうかわかりません。 gpupdateのログオフプロンプトに提供されますか?

何か案は?

以下は、システムコンテキストでターゲットマシン上で実行される完全なPowerShellスクリプトです。

#
cmd /c gpupdate /target:computer /force | Out-Null

$ExplorerProcess = Get-WmiObject win32_process | Where-Object { $_.name -Match 'Explorer'}

$LoggedOnUser = if($ExplorerProcess.getowner().user.count -gt 1){ $ExplorerProcess.getowner().user[0] }else{ $ExplorerProcess.getowner().user }

If($LoggedOnUser.trim() -eq "") { "Computer GPUpdate Successful. No active user session" Return }

$TaskName = "Run User GPUpdate - $((Get-Date).ToString('dd-MM-yyyy-HH-mm-ss'))" $ShedService = New-Object -comobject 'Schedule.Service' $ShedService.Connect()

$Task = $ShedService.NewTask(0) $Task.RegistrationInfo.Description = 'Upser GPUpdate Description' $Task.Settings.Enabled = $true $Task.Settings.AllowDemandStart = $true $Task.Settings.DeleteExpiredTaskAfter = 'PT0S' $Task.Settings.StartWhenAvailable = $True

$trigger = $task.triggers.Create(1) $trigger.StartBoundary = [DateTime]::Now.AddSeconds(5).ToString("yyyy-MM-dd'T'HH:mm:ss") $trigger.EndBoundary = [DateTime]::Now.AddSeconds(30).ToString("yyyy-MM-dd'T'HH:mm:ss") $trigger.Enabled = $true

$ScriptCode = """ cmd /c gpupdate.exe /target:user /force """ $PwshArgument = "-ExecutionPolicy ByPass -NoProfile -WindowStyle Hidden -command $ScriptCode"

$action = $Task.Actions.Create(0) $action.Path = 'Powershell.exe' $action.Arguments = $PwshArgument $taskFolder = $ShedService.GetFolder("\")

try{ $taskFolder.RegisterTaskDefinition($TaskName, $Task , 6, 'Users' , $null, 4) | Out-Null "Computer GPO and User $LoggedOnUser GPO update Successful" } Catch { "GPUpdate Failed - $($_.Exception.Message)" }

#
1
Steve

Gpupdateプロンプトを抑制します

/wait:0パラメーターと値をgpupdateコマンドに組み込むことを検討してください。これにより、確認のプロンプトが抑制され、GPが処理を続行できるようになりますが、最初に完了するのを「待つ」必要なしに、さらにスクリプトロジックを続行できます。

過去にgpupdate /force /wait:0などを使用して成功しましたが、gpupdate /target:computer /force /wait:0またはgpupdate /target:user /force /wait:0を実行して、どのポリシー部分をマシンやユーザーにプッシュするかを指定しても問題はありません。

gpupdate(Microsoft)

  • / wait:

    コマンドプロンプトに戻る前に、ポリシー処理が終了するのを待機する秒数を設定します。制限時間を超えると、コマンドプロンプトが表示されますが、ポリシー処理は続行されます。デフォルト値は600秒です。値0は待機しないことを意味します。値-1は無期限に待機することを意味します。

    スクリプトでは、制限時間を指定してこのコマンドを使用することにより、gpupdateを実行し、gpupdateの完了に依存しないコマンドを続行できます。または、時間制限を指定せずにこのコマンドを使用して、それに依存する他のコマンドが実行される前にgpupdateの実行を終了させることもできます。

GPUPDATE(SS64)

  • / Wait:

    ポリシーの処理を待機する秒数。

    • default =600(10分)
    • 0 =待たない
    • -1 =無期限に待つ

    制限時間を超えると、コマンドプロンプトが返されますが、ポリシー処理は続行されます。

1
Pimp Juice IT