PowerShell / PSDscResources

MIT License
129 stars 53 forks source link

User: Test-DscResource fails for user that is disabled by resource #203

Open General-Fault opened 3 years ago

General-Fault commented 3 years ago

Details of the scenario you tried and the problem that is occurring

if a new user is created with Disabled=$true, the Test-TargetResource method of the User resource fails.

The error given is:

PowerShell DSC resource MSFT_UserResource failed to execute Test-TargetResource functionality with error message: System.InvalidOperationException: There could be a possible multiple matches exception while trying to use the System.DirectoryServices API's.Exception calling "ValidateCredentials" with "2" argument(s): "This user can't sign in because this account is currently disabled.

The Test-TargetResource attempts to test the user credentials even when the user is specifically disabled.

See also case #151

Verbose logs showing the problem

[DSCTEST]: LCM: [ Start Test ] [[User]TestUser] TaskSequencePSHost [DSCTEST]: [[User]TestUser] A user with the name SecurityScan exists. [DSCTEST]: LCM: [ End Test ] [[User]TestUser] False in 2.2500 seconds. [DSCTEST]: LCM: [ FAILEDCompare ] Completed processing compare operation. The operation returned False. PowerShell DSC resource MSFT_UserResource failed to execute Test-TargetResource functionality with error message: System.InvalidOperationException: There could be a possible multiple matches exception while trying to use the System.DirectoryServices API's.Exception calling "ValidateCredentials" with "2" argument(s): "This user can't sign in because this account is currently disabled."

Suggested solution to the issue

The Test-TargetResourceOnFullSKU and Test-TargetResourceOnNanoServer functions should only test the credentials if the "Disabled" parameter is false.

if ($PSBoundParameters.ContainsKey('Password')) 

should be something like:

if ($PSBoundParameters.ContainsKey('Password') -and -not ($PSBoundParameters.ContainsKey('Disabled') -and $Disabled) 

or perhaps a warning is in order?

if ($PSBoundParameters.ContainsKey('Password')) 
{
    if ($PSBoundParameters.ContainsKey('Disabled') -and $Disabled) 
    {
        Write-Warning "Unable to test the password for user $UserName. User is disabled."
    }
    else 
    { 
        #password test here
    }

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Configuration UserExample
{
    param (
        [System.Management.Automation.PSCredential]
        $PasswordCredential
    )

    Import-DscResource -ModuleName PSDscResources

    User UserExample
    {
        Ensure = 'Present'  # To ensure the user account does not exist, set Ensure to "Absent"
        UserName = 'SomeUserName'
        Password = $PasswordCredential # This needs to be a credential object
        Disabled = $true
    }
}

Perhaps an easier way to test this is with Invoke-DscResource

#create the disabled user
$cred = Get-Credential TestUser
Invoke-DscResource -ModuleName PSDscResources -Name User -Method Set -Property @{
 UserName = 'TestUser'
 Password = $cred
 Disabled = $true
 Ensure = 'Present'
 }

#test the user
Invoke-DscResource -ModuleName PSDscResources -Name User -Method Test -Property @{
 UserName = 'TestUser'
 Password = $cred
 Disabled = $true
 Ensure = 'Present'
 }

The operating system the target node is running

OsName : Microsoft Windows 10 Enterprise LTSC OsOperatingSystemSKU : 125 OsArchitecture : 64-bit WindowsVersion : 1809 WindowsBuildLabEx : 17763.1.amd64fre.rs5_release.180914-1434 OsLanguage : en-US OsMuiLanguages : {en-US}

Version and build of PowerShell the target node is running

Name Value
PSVersion 5.1.17763.1971
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1971
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

Version of the DSC module that was used ('dev' if using current dev branch)

2.12.0.0