Updating User GPOs using Run Script in ConfigMgr

Run Scripts on Configuration Manager is one of the coolest things in a long time. I have a long list of scripts to write/blog here is the first. Update the logged on users GPOs. Then challenge with this is that the script is executed in System Context and we want to be in the users context to be be able to update the Users GPOs.

I didn’t want to copy any files so that means that that running a Powershell script in the users context is out the window as it will always flash by the console window and that is not acceptable. Solution, a PowerShell script that will create a local vbscript, yes vbscript you read it correct as we can run it completely silent without a window popping up.
It creates a Schedule Task that runs in the logged in users context which we initiate from System context to be able to trigger the update in user context.

# Script to update User GPO from System context using a Schedule Task
# Written by Jörgen Nilsson
# ccmexec.com

# Creates a local vbscript, which will run GPUpdate without displaying anything for the end user
$VBScript = @"
Set objShell = WScript.CreateObject("WScript.Shell")
Result = objShell.Run ("cmd /c echo n | gpupdate /target:user /force",0,true)
Wscript.quit(Result)
"@
 
$VBScript | Out-File -FilePath "$env:Windir\RunUserGPO.vbs" -Force 

# Gets the logged on user
$computer = $env:COMPUTERNAME
$computerSystem = Get-WMIObject -class Win32_ComputerSystem -ComputerName $computer
$LoggedUser = $computerSystem.UserName
If ($LoggedUser -eq $null) {
    Write-output "No user logged on"
    Exit 1
}
# Creates and run a Schedule Task as the logged on user
$TaskName= "GPupdateUser"
$Action = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "$env:Windir\RunUserGPO.vbs /NoLogo"
$Principal = New-ScheduledTaskPrincipal "$loggedUser"
$Settings = New-ScheduledTaskSettingsSet
 
$Task = New-ScheduledTask -Action $Action -Principal $Principal -Settings $Settings
Register-ScheduledTask $TaskName -InputObject $Task | out-null
Start-ScheduledTask $TaskName | out-null

# Wait for Schedule task to complete 
$Counter = 200 # 40 s
while ((Get-ScheduledTask -TaskName $TaskName).State -ne 'Ready' -and $Counter-- -gt 0) {
    Start-Sleep -Milliseconds 200
}

if ($Counter -lt 0) {
    Write-Output "Timeout waiting for Scheduled Task"
    exit 1
}

# Verify Result
$St = Get-ScheduledTask -TaskName $TaskName
$Result = (Get-ScheduledTaskInfo -InputObject $St).LastTaskResult
if ($Result -eq 0) {
    Write-Output "Completed Succesfully"
}
else {
     Write-Output "Error running Schedule task, error code = $('0x{0:x}' -f $Result)"
}

# Cleaning up 
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
Remove-Item -Path "$env:Windir\RunUserGPO.vbs" -Force

We simply add the content to a Run Script in Configuration Manager which we then can trigger for one or multiple clients.

The result will look like this in the console as an example:

And on the client we can see that the User Group Polices where processed.

I hope you will find it useful!

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.