Разрешить пользователю без прав администратора запускать запланированное задание в Windows Server 2016

В предыдущих версиях Windows мы могли разрешить пользователю выполнять запланированное задание, предоставляя разрешения на чтение + выполнение файла в WINDOWS\SYSTEM32\Tasks.

Это больше не работает в Windows 2016. Я попытался предоставить Полный доступ к файлу MyTask для всех. Но все же я получаю:

schtasks.exe /Run /TN "MyTask"
ERROR: Access is denied.

Кто-нибудь разобрался, как заставить это работать в Windows 2016?

РЕДАКТИРОВАТЬ: я предоставил SeBatchLogonRight для учетной записи с ntrights, но это не имело никакого значения.

3 ответа

В этом потоке есть сценарий PowerShell, который предоставит аутентифицированным пользователям разрешения на чтение и выполнение задачи:

https://social.technet.microsoft.com/Forums/windows/en-US/6b9b7ac3-41cd-419e-ac25-c15c45766c8e/scheduled-task-that-any-user-can-run?forum=win10itprogeneral

Ссылка от Владимира кажется решением. Поскольку ссылки на Microsoft со временем всегда исчезают, я скопировал сюда полное решение. Сценарий powershell предоставлен пользователем MotoX80 на сайтеsocial.technet.microsoft.com.

MotoX80 написал:

Некоторое время назад я исследовал это и не смог заставить изменения разрешений файлов работать так, как вы обнаружили.

На этот раз я копнул немного глубже и обнаружил значение реестра SD. Смотрите комментарии в коде. Я создал сценарий Powershell, который назвал UnlockScheduledTask.ps1. У меня это сработало на Win10Pro. Просто создайте задачу, а затем разблокируйте ее.

Попробуйте и посмотрите, сработает ли это для вас.

      <#

.SYNOPSIS
This Powershell script updates the security descriptor for scheduled tasks so that any user can run the task. 

Version 1.0 of this script only displays tasks in the root folder. I want to make sure that works first. 

.DESCRIPTION
Earlier versions of Windows apparently used file permissions on C:\Windows\System32\Tasks files to manage security.
Windows now uses the SD value on tasks under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree to accomplish that. 

By default, this script will display the SDDL on all tasks. If a taskname is passed as a parameter, this script will grant Authenticated users read and execute permissions to the task. 

This script accepts 1 parameters.
-taskname   The name of a scheduled task. 

.EXAMPLE
./UnlockScheduledTask.ps1 
./UnlockScheduledTask.ps1 -taskname "My task"  

.NOTES
Author: Dave K. aka MotoX80 on the MS Technet forums. (I do not profess to be an expert in anything. I do claim to be dangerous with everything.)



.LINK
http://www.google.com

#>

param (
    [string]$taskname = ""   
 )

 'UnlockScheduledTask.ps1  Version 1.0'
 if ($taskname -eq '') {
    ''
    'No task name specified.'
    'SDDL for all tasks will be displayed.'
    ''
 } else {
    $batFile = "$env:TEMP\Set-A-Task-Free.bat"           # if you don't like my names, you can change them here. 
    $updateTaskName = 'Set-A-Task-Free'
    ''
    "SDDL for $taskname will be updated via $batfile"
    ''
 }
 $wmisdh = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper 
 $subkeys = Get-childitem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree"
 foreach ($key in $subkeys) {
    if ($taskname -eq '') {              # if blank, show SDDL for all tasks 
        ''
        $key.PSChildName
        $task = Get-ItemProperty $($key.name).replace("HKEY_LOCAL_MACHINE","HKLM:")
        $sddl = $wmisdh.BinarySDToSDDL( $task.SD ) 
        $sddl['SDDL']        
    
    } else {
        if ($key.PSChildName -eq $taskname) {
            ""
            $key.PSChildName
            $task = Get-ItemProperty $($key.name).replace("HKEY_LOCAL_MACHINE","HKLM:")
            $sddl = $wmisdh.BinarySDToSDDL( $task.SD ) 
            $sddl['SDDL']
            ''
            'New SDDL'
            $newSD = $sddl['SDDL'] +  '(A;ID;0x1301bf;;;AU)'          # add authenticated users read and execute
            $newSD                                                    # Note: cacls /s will display the SDDL for a file. 
            $newBin = $wmisdh.SDDLToBinarySD( $newsd )
            [string]$newBinStr =  $([System.BitConverter]::ToString($newBin['BinarySD'])).replace('-','') 
            
            # Administrators only have read permissions to the registry vlaue that needs to be updated.
            # We will create a bat file with a reg.exe command to set the new SD.
            # The bat file will be invoked by a scheduled task that runs as the system account.
            # The bat file can also be reused if the task is deployed to other machines. 
            ''
            "reg add ""HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{0}"" /f /v SD /t REG_BINARY /d {1}" -f $key.PSChildName, $newBinStr
            "reg add ""HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{0}"" /f /v SD /t REG_BINARY /d {1}" -f $key.PSChildName, $newBinStr  | out-file -Encoding ascii $batfile  
            ''

            SCHTASKS /Create /f /tn "$updateTaskName" /sc onstart  /tr "cmd.exe /c $batfile" /ru system 
            SCHTASKS /run /tn "$updateTaskName"
            $count = 0
            while ($count -lt 5) {
                start-sleep 5
                $count++
                $(Get-ScheduledTask -TaskName $updateTaskName).State
                if ($(Get-ScheduledTask -TaskName $updateTaskName).State -eq 'Ready') {
                    $count = 99            # it's ok to procees
                }
            }
            if ($count -ne 99) {
                "Error! The $updateTaskName task is still running. "
                'It should have ended by now.'
                'Please investigate.'
                return
            }
            SCHTASKS /delete /f /tn "$updateTaskName"
            ''
            'Security has been updated. Test it.'
        }
    }      
 }

Magic Code по-прежнему требует, чтобы PSExec повысил права доступа к "Системной учетной записи", потому что иначе ключи реестра изменить нельзя:

.\psexec.exe -s -i powershell.exe

Затем нам нужно получить Sid учетной записи соответствующего объекта.

get-aduser USERNAME | select sid   #Plenty of other ways to accomplish this

# Then we Get SDDL from existing task, to ensure that we maintain the proper owner and creator ID’s
$PathToTask = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\TASKYOUWISHTOALLOWTOBETRIGGERED"
$SDBin =  ( (get-itemProperty $PathToTask).SD )
# the $existingSDDL is the string we will actually be modifying (which is technically of the parent object that we are going to apply the new value to)
$existingSDDL = ([wmiclass]"Win32_SecurityDescriptorHelper").BinarySDToSDDL($SDBin).SDDL
# The result returned below is the interpretation of it in English
$secEnglish = ConvertFrom-SddlString ([wmiclass]"Win32_SecurityDescriptorHelper").BinarySDToSDDL($SDBin).SDDL
$sec.DiscretionaryAcl

# The $existingSDDL will look something akin to the $p1 value
$p1 = 'O:BAG:DUD:(A;ID;0x1f019f;;;BA)(A;ID;0x1f019f;;;SY)(A;ID;FA;;;BA)(A;;FR;;;S-1-5-21-0000000000-111111111-2222222222-3333)'
# We then need to add the appropriate DACL for the account/SID we want to grant permissions to and the FA (File Full Access) permission to the string
$p2 = 'O:BAG:DUD:(A;ID;0x1f019f;;;BA)(A;ID;0x1f019f;;;SY)(A;ID;FA;;;BA)(A;;FR;;;S-1-5-21-0000000000-111111111-2222222222-3333)(A;;FR;;;S-1-5-21-0000000000-111111111-2222222222-9999)'

# We then need to convert the DACL into a binary Value to be applied to the SD (REG_BINARY) ****Value****, not the security of the object but the actual value of the SD Key
$p2BinVal = ([wmiclass]"Win32_SecurityDescriptorHelper").SDDLToBinarySD($p2).BinarySD

# Как только у нас есть правильное двоичное значение, мы можем обновить значение ключа Set-ItemProperty -Path $PathToTask -Name SD -Value (byte[])

# Если ключ неправильно настроен на другой тип данных по пути, вы можете удалить его повторно создать remove-itemproperty -path $ PathToTask -name "SD" New-ItemProperty -Path $PathToTask -Name SD -PropertyType Binary -Value ([byte[]]$p2BinVal)

DACL/SACL Примечания: Заголовок D: = DACL S: = SACL G: = Основная группа O: = Владелец DACL и SACL представляют собой комбинацию записей ACE, заключенных в () 6 полей Тип ACE (разрешить / запретить / аудит), флаги ACE (наследование и параметры аудита), Разрешения (список дополнительных разрешений), Тип объекта (GUID), Тип наследуемого объекта (GUID) и Доверенное лицо (SID)https://itconnect.uw.edu/wares/msinf/other-help/understanding-sddl-syntax/

Другие вопросы по тегам