Worklet - Temporarily Elevate to Local Admin

  • 8 February 2022
  • 2 replies
  • 741 views

Userlevel 5
Badge +1

This worklet takes the logged in user from Win32_ComputerSystem username attribute and adds them to the local Administrators group. The worklet then creates two Scheduled tasks. One will run a rollback script in a set # of minutes post running worklet or when the computer starts up. The rollback script will remove the scheduled tasks and files associated with this worklet.

 

# Set rollback time (minutes)
$minutes = 240

# working directory
$workdir = 'C:\Windows\Temp'
IF((Test-Path $workdir) -eq $false){mkdir $workdir -Force | Out-Null}

# Cleanup Prior Run
Unregister-ScheduledTask -TaskName "LocalAdminGroup*" -Confirm:$false | Out-Null
Remove-Item $workdir\id.txt -ErrorAction SilentlyContinue | Out-Null
Remove-Item $workdir\LocalAdmin.ps1 -ErrorAction SilentlyContinue | Out-Null

# Add Local user to Admin Group
$user = (Get-WmiObject -Class Win32_ComputerSystem).UserName
Write-Output "Adding $user to local Administrators Group. "
$user | Out-File $workdir\id.txt
cmd /c net localgroup Administrators $user /add

# Schedule 4 hour rollback
Function Schedule-RollbackTask{
$TaskStartTime = [datetime]::Now.AddMinutes($minutes)
$SchedService = New-Object -ComObject Schedule.Service
$SchedService.Connect()
$Task = $SchedService.NewTask(0)
$Task.RegistrationInfo.Description = "Remove $user from Local Admin Group"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$Task.Settings.WakeToRun = $true
$trigger = $Task.triggers.Create(1) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create
$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.Enabled = $true
$action = $Task.Actions.Create(0)
$action.Path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$action.Arguments = "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $workdir\LocalAdmin.ps1 -Force"
$taskFolder = $SchedService.GetFolder('\')
$taskFolder.RegisterTaskDefinition("LocalAdminGroup", $Task , 6, 'SYSTEM', $null, 4) | out-null
}
Schedule-RollbackTask

# Just in case, schedule at boot
Function Schedule-RollbackTaskStartup{
$TaskStartTime = [datetime]::Now.AddMinutes(0) # Six hours
$SchedService = New-Object -ComObject Schedule.Service
$SchedService.Connect()
$Task = $SchedService.NewTask(0)
$Task.RegistrationInfo.Description = "Remove $user from Local Admin Group"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$trigger= $Task.triggers.Create(8) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create
$trigger.Enabled=$true
$trigger.Repetition.Interval="PT10M" # ten minutes
$trigger.Repetition.StopAtDurationEnd=$false # on to infinity
$trigger.Id="StartupTrigger"
$trigger.Enabled = $true
$action = $Task.Actions.Create(0)
$action.Path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$action.Arguments = "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $workdir\LocalAdmin.ps1 -Force"
$taskFolder = $SchedService.GetFolder('\')
$taskFolder.RegisterTaskDefinition("LocalAdminGroupStartup", $Task , 6, 'SYSTEM', $null, 4) | out-null
}
Schedule-RollbackTaskStartup

# Create Rollback Script
$ps1 = @"
# Get user from prior run. If that us unavailble grab logged on user.
`$user = Get-Content $workdir\id.txt
IF(!`$user){ `$user = (Get-WmiObject -Class Win32_ComputerSystem).UserName }

# Remove user from local admin group
cmd /c net localgroup Administrators `$user /delete

# Cleanup Scheduled task and Rollback Script
Unregister-ScheduledTask -TaskName "LocalAdminGroup*" -Confirm:`$false | Out-Null
Remove-Item $workdir\id.txt
Remove-Item $workdir\LocalAdmin.ps1
"@
New-Item -Path "$workdir" -Name "LocalAdmin.ps1" -ItemType "file" -Value $ps1 -force | Out-Null

 

 

 

 


2 replies

...

Userlevel 5
Badge +1

Huge shoutout to @Folarin_Abiola  for helping improve this worklet through feedback. The scheduled task was missing a few critical settings to maximize chances that it will run the rollback script as desired 

  • Disable “Start the task only if the computer is on AC power”
  • Disable “Stop if the computer switches to battery power”
  • Enabled “Run task as soon as possible after a scheduled start is missed
# Set rollback time (minutes)
$minutes = 240

# working directory
$workdir = 'C:\Windows\Temp'
IF((Test-Path $workdir) -eq $false){mkdir $workdir -Force | Out-Null}

# Cleanup Prior Run
Unregister-ScheduledTask -TaskName "LocalAdminGroup*" -Confirm:$false | Out-Null
Remove-Item $workdir\id.txt -ErrorAction SilentlyContinue | Out-Null
Remove-Item $workdir\LocalAdmin.ps1 -ErrorAction SilentlyContinue | Out-Null

# Add Local user to Admin Group
$user = (Get-WmiObject -Class Win32_ComputerSystem).UserName
Write-Output "Adding $user to local Administrators Group. "
$user | Out-File $workdir\id.txt
cmd /c net localgroup Administrators $user /add

# Schedule Removal of Admin Credenitals
Function Schedule-RollbackTask{
$TaskStartTime = [datetime]::Now.AddMinutes($minutes)
$SchedService = New-Object -ComObject Schedule.Service
$SchedService.Connect()
$Task = $SchedService.NewTask(0)
$Task.RegistrationInfo.Description = "Remove $user from Local Admin Group"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$Task.Settings.ExecutionTimeLimit = "PT10M"
$Task.Settings.DisallowStartIfOnBatteries = $false # Start the task only if the computer is on AC power
$Task.Settings.StopIfGoingOnBatteries = $false # Stop if the computer switches to battery power
$Task.Settings.WakeToRun = $true
$trigger = $Task.triggers.Create(1) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create
$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$Task.Settings.StartWhenAvailable = $true # Run task as soon as possible after a scheduled start is missed
#$trigger.Repetition.Interval="PT10M" # Run every ten minutes
#$trigger.Repetition.StopAtDurationEnd=$false # on to infinity
$trigger.Enabled = $true
$action = $Task.Actions.Create(0)
$action.Path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$action.Arguments = "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $workdir\LocalAdmin.ps1 -Force"
$taskFolder = $SchedService.GetFolder('\')
$taskFolder.RegisterTaskDefinition("LocalAdminGroup", $Task , 6, 'SYSTEM', $null, 4) | out-null
}
Schedule-RollbackTask

# Just in case, schedule at boot
Function Schedule-RollbackTaskStartup{
$SchedService = New-Object -ComObject Schedule.Service
$SchedService.Connect()
$Task = $SchedService.NewTask(0)
$Task.RegistrationInfo.Description = "Remove $user from Local Admin Group"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$trigger= $Task.triggers.Create(8) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create
$trigger.Enabled=$true
$trigger.Repetition.Interval="PT10M" # ten minutes
$trigger.Repetition.StopAtDurationEnd=$false # on to infinity
$trigger.Id="StartupTrigger"
$trigger.Enabled = $true
$action = $Task.Actions.Create(0)
$action.Path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$action.Arguments = "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $workdir\LocalAdmin.ps1 -Force"
$taskFolder = $SchedService.GetFolder('\')
$taskFolder.RegisterTaskDefinition("LocalAdminGroupStartup", $Task , 6, 'SYSTEM', $null, 4) | out-null
}
Schedule-RollbackTaskStartup

# Create Rollback Script
$ps1 = @"
# Get user from prior run. If that us unavailble grab logged on user.
`$user = Get-Content $workdir\id.txt
IF(!`$user){ `$user = (Get-WmiObject -Class Win32_ComputerSystem).UserName }

# Remove user from local admin group
cmd /c net localgroup Administrators `$user /delete

# Cleanup Scheduled task and Rollback Script
Unregister-ScheduledTask -TaskName "LocalAdminGroup*" -Confirm:`$false | Out-Null
Remove-Item $workdir\id.txt
Remove-Item $workdir\LocalAdmin.ps1
"@
New-Item -Path "$workdir" -Name "LocalAdmin.ps1" -ItemType "file" -Value $ps1 -force | Out-Null

 

Reply