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)" }
#
/wait:0
パラメーターと値をgpupdate
コマンドに組み込むことを検討してください。これにより、確認のプロンプトが抑制され、GPが処理を続行できるようになりますが、最初に完了するのを「待つ」必要なしに、さらにスクリプトロジックを続行できます。
過去にgpupdate /force /wait:0
などを使用して成功しましたが、gpupdate /target:computer /force /wait:0
またはgpupdate /target:user /force /wait:0
を実行して、どのポリシー部分をマシンやユーザーにプッシュするかを指定しても問題はありません。
/ wait:
コマンドプロンプトに戻る前に、ポリシー処理が終了するのを待機する秒数を設定します。制限時間を超えると、コマンドプロンプトが表示されますが、ポリシー処理は続行されます。デフォルト値は600秒です。値
0
は待機しないことを意味します。値-1
は無期限に待機することを意味します。スクリプトでは、制限時間を指定してこのコマンドを使用することにより、gpupdateを実行し、gpupdateの完了に依存しないコマンドを続行できます。または、時間制限を指定せずにこのコマンドを使用して、それに依存する他のコマンドが実行される前にgpupdateの実行を終了させることもできます。
/ Wait:
ポリシーの処理を待機する秒数。
default
=600(10分)0
=待たない-1
=無期限に待つ制限時間を超えると、コマンドプロンプトが返されますが、ポリシー処理は続行されます。