ScheduledTask: Get-TargetResource returns wrong account for BuiltInAccount parameter
Problem description
The ScheduledTask resource parameter BuiltInAccount must be one of the following: ('SYSTEM', 'LOCAL SERVICE', 'NETWORK SERVICE'), but Get-TargetResource returns BuiltInAccount as NT SERVICE\SYSTEM.
Verbose logs
: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = Resourceget,'className' = MSFT_DSCLocalConfigurationManager,'n
amespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer IAD3DRND-D09-1 with user sid S-1-5-21-2851708077-3393195298-855477758-112710.
VERBOSE: [IAD3DRND-D09-1]: [[ScheduledTask]DirectResourceAccess] Getting scheduled task 'Cleanup_DSC_ConfigurationStatus_Fol
der' in '\'.
VERBOSE: [IAD3DRND-D09-1]: [[ScheduledTask]DirectResourceAccess] Getting current scheduled task values for task 'Cleanup_DSC
_ConfigurationStatus_Folder' in '\'.
VERBOSE: [IAD3DRND-D09-1]: [[ScheduledTask]DirectResourceAccess] Task 'Cleanup_DSC_ConfigurationStatus_Folder' found in '\'.
Retrieving settings, first action, first trigger and repetition settings.
VERBOSE: [IAD3DRND-D09-1]: [[ScheduledTask]DirectResourceAccess] Detected schedule type 'Daily' for first trigger.
VERBOSE: [IAD3DRND-D09-1]: [[ScheduledTask]DirectResourceAccess] Current scheduled task values for task 'Cleanup_DSC_Configu
rationStatus_Folder' in '\' retrieved.
VERBOSE: [IAD3DRND-D09-1]: LCM: [ End Get ] [[ScheduledTask]DirectResourceAccess] in 0.8790 seconds.
VERBOSE: [IAD3DRND-D09-1]: LCM: [ End Set ] in 1.5740 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 1.711 seconds
PS C:\Windows\system32> $result
ConfigurationName :
DependsOn :
ModuleName : c:/puppet-dsc/sdk/computermanagementdsc/lib/puppet_x/computermanagementdsc/dsc_resources/ComputerManagementDsc/Compu
terManagementDsc.psd1
ModuleVersion : 8.4.0
PsDscRunAsCredential :
ResourceId :
SourceInfo :
ActionArguments : /c "del /q /s c:\windows\system32\configuration\configurationstatus\* > nul"
ActionExecutable : cmd.exe
ActionWorkingPath :
AllowStartIfOnBatteries : False
BuiltInAccount : SYSTEM
Compatibility : Win7
DaysInterval : 1
DaysOfWeek : {}
Delay : 00:00:00
Description :
DisallowDemandStart : False
DisallowHardTerminate : False
DisallowStartOnRemoteAppSession : False
DontStopIfGoingOnBatteries : False
DontStopOnIdleEnd : False
Enable : True
Ensure : Present
EventSubscription :
ExecuteAsCredential : MSFT_Credential
ExecuteAsGMSA : SYSTEM
ExecutionTimeLimit : 00:20:00
Hidden : False
IdleDuration : 01:00:00
IdleWaitTimeout : 02:00:00
LogonType : ServiceAccount
MultipleInstances : Queue
NetworkName :
Priority : 7
RandomDelay : 00:00:00
RepeatInterval : 00:00:00
RepetitionDuration : Indefinitely
RestartCount : 0
RestartInterval : 00:00:00
RestartOnIdle : False
RunLevel : Limited
RunOnlyIfIdle : False
RunOnlyIfNetworkAvailable : False
ScheduleType : Daily
StartTime : 4/27/2022 4:00:00 AM
StartWhenAvailable : False
SynchronizeAcrossTimeZone : False
TaskName : Cleanup_DSC_ConfigurationStatus_Folder
TaskPath : \
User : NT AUTHORITY\SYSTEM
WakeToRun : False
WeeksInterval : 0
PSComputerName : localhost
DSC configuration
$InvokeParams = @{
Name = 'ScheduledTask';
Method = 'get';
Property = @{
taskname = 'Cleanup_DSC_ConfigurationStatus_Folder'};
ModuleName = @{ModuleName = 'c:/puppet-dsc/sdk/computermanagementdsc/lib/puppet_x/computermanagementdsc/dsc_resources/ComputerManagementDsc/ComputerManagementDsc.psd1';
RequiredVersion = '8.4.0'
}
}
$Result = Invoke-DscResource @InvokeParams
Suggested solution
Update Get-CurrentResource function to not prepend the DomainName NT AUTHORITY, or update the valid set for BuiltInAccount to include NT Authority\SYSTEM
L1888 of Get-CurrentResource :
if (($result.ContainsKey('LogonType')) -and ($result['LogonType'] -ieq 'ServiceAccount'))
{
# $builtInAccount = Set-DomainNameInAccountName -AccountName $task.Principal.UserId -DomainName 'NT AUTHORITY'
# $result.Add('BuiltInAccount', $builtInAccount)
$result.Add('BuiltInAccount', $task.Principal.UserId)
}
Operating system the target node is running
OsName : Microsoft Windows Server 2019 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture : 64-bit
WindowsVersion : 1809
WindowsBuildLabEx : 17763.1.amd64fre.rs5_release.180914-1434
OsLanguage : en-US
OsMuiLanguages : {en-US}
PowerShell version and build the target node is running
PS C:\Windows\system32> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.17763.2268
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.2268
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
ComputerManagementDsc version
8.4.0
Okay, I think I've determined the issue. The user property and BuiltInAccount param are being conflated. The *-ScheduledTask cmdlets have a user parameter that takes domain\username, where in the case of a BuiltInAccount, it should be NT Authority\$BuiltInAccount. The Get-CurrentResource function conflates the two (setting BuiltInAccount to NT Authority\$BuiltInAccount, and the Test-CurrentResource when building $currentValues and $desiredValues hashes to compare with Test-DSCParameterState does the same as well.
tl;dr, I think Get-CurrentResource should have$result.user be $domain\$username or NT Authority\$BuiltInAccount and the $currentValues and $desiredValues hashes should be similarly structured. I'll try and spin up a PR for this shortly.
I am also interested in seeing this fixed.
We use Puppet's automated generated modules that wrap around this code and the MOF schema does not match what is returned by the resource. Resource returns NT AUTHORITY\SYSTEM but the MOF schema specifies SYSTEM.
https://forge.puppet.com/modules/dsc/computermanagementdsc/readme
Provider returned data that does not match the Type Schema
Value type mismatch:
* dsc_builtinaccount: NT AUTHORITY\SYSTEM
From memory, we've actually faced something similar before (or even this exact issue), except it was because different versions of Windows Server (or different versions of the ScheduledTask module) returns this value in different formats. So, we had some code in place to try and deal with this for some scenarios on Windows Server 2016 and earlier.
Doing a bit of searching we did deal with something similar in these issues:
https://github.com/dsccommunity/ComputerManagementDsc/issues/317 https://github.com/dsccommunity/ComputerManagementDsc/issues/328
We may need to implement a transformation function to ensure the output is in the correct format regardless of OS.
I'll try and spin up a 2016 OS and test out the version of ComputerManagementDsc my PR builds. is it safe to assume similar results from 2016 and earlier, and 2019 and beyond?
Seems my fix in pull 387 works on 2016 as well:
OsOperatingSystemSKU : 80
OsArchitecture : 64-bit
WindowsBuildLabEx : 14393.693.amd64fre.rs1_release.161220-1747
OsLanguage : en-US
OsMuiLanguages : {en-US}
I omitted irrelevant lines:
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = roo
t/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer WIN-BV2V52GQAID with user sid S-1-5-21-153152377-2724529306-532032198-500.
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ Start Set ]
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ Start Resource ] [[ScheduledTask]ScheduledTaskOnceAdd]
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ Start Test ] [[ScheduledTask]ScheduledTaskOnceAdd]
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] Testing scheduled task 'Test task Once' in '\MyTasks\'.
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] Getting current scheduled task values for task 'Test task Once' in '\MyTasks\'.
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] Task 'Test task Once' found in '\MyTasks\'. Retrieving settings, first action, first tri
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] MATCH: Value (type 'System.String') for property 'LogonType' does match. Current state i
s 'ServiceAccount' and desired state is 'ServiceAccount'. (DRC0020)
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] MATCH: Value (type 'System.String') for property 'User' does match. Current state is 'NT
AUTHORITY\SYSTEM' and desired state is 'NT AUTHORITY\SYSTEM'. (DRC0020)
VERBOSE: [WIN-BV2V52GQAID]: [[ScheduledTask]ScheduledTaskOnceAdd] MATCH: Value (type 'System.String') for property 'BuiltInAccount' does match. Current st
ate is 'SYSTEM' and desired state is 'SYSTEM'. (DRC0020)
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ End Test ] [[ScheduledTask]ScheduledTaskOnceAdd] in 1.3240 seconds.
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ Skip Set ] [[ScheduledTask]ScheduledTaskOnceAdd]
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ End Resource ] [[ScheduledTask]ScheduledTaskOnceAdd]
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ End Set ]
VERBOSE: [WIN-BV2V52GQAID]: LCM: [ End Set ] in 2.6050 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 3.253 seconds
Config used:
{
Import-DscResource -ModuleName ComputerManagementDsc
Node localhost
{
ScheduledTask ScheduledTaskOnceAdd
{
TaskName = 'Test task Once'
TaskPath = '\MyTasks'
ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
ScheduleType = 'Once'
RepeatInterval = '00:15:00'
RepetitionDuration = '08:00:00'
ExecutionTimeLimit = '00:00:00'
ActionWorkingPath = (Get-Location).Path
Enable = $true
RandomDelay = '01:00:00'
DisallowHardTerminate = $true
RunOnlyIfIdle = $false
Priority = 9
BuiltInACcount = 'SYSTEM'
}
}
}
. ScheduledTask_CreateScheduledTaskOnce_Config
I had some time and was able to test on Win2012r2 and 2019, with the same results as 2016. I believe the previous fixes were not respecting user and builtinaccount as seperate resources and were just swapping them causing the flapping in os behavior. My PR treats them as unique so the fix is os agnostic.