From 9d4f60e0641d8b388a48c5131bbe443b815f3359 Mon Sep 17 00:00:00 2001 From: Simon Heather Date: Fri, 14 Jun 2019 21:16:46 +0100 Subject: [PATCH 1/3] xADUser add additional parameters --- DSCResources/MSFT_xADUser/MSFT_xADUser.psm1 | 170 ++++++++++++++++++ .../MSFT_xADUser/MSFT_xADUser.schema.mof | 8 + Tests/Unit/MSFT_xADUser.Tests.ps1 | 8 +- 3 files changed, 184 insertions(+), 2 deletions(-) diff --git a/DSCResources/MSFT_xADUser/MSFT_xADUser.psm1 b/DSCResources/MSFT_xADUser/MSFT_xADUser.psm1 index da2cc86a3..94a059445 100644 --- a/DSCResources/MSFT_xADUser/MSFT_xADUser.psm1 +++ b/DSCResources/MSFT_xADUser/MSFT_xADUser.psm1 @@ -136,6 +136,12 @@ $adPropertyMap = @( @{ Parameter = 'Manager' } + @{ + Parameter = 'Organization' + } + @{ + Parameter = 'OtherName' + } @{ Parameter = 'PasswordNeverExpires' UseCmdletParameter = $true @@ -153,6 +159,26 @@ $adPropertyMap = @( Parameter = 'TrustedForDelegation' UseCmdletParameter = $true } + @{ + Parameter = 'AccountNotDelegated' + UseCmdletParameter = $true + } + @{ + Parameter = 'AllowReversiblePasswordEncryption' + UseCmdletParameter = $true + } + @{ + Parameter = 'CompoundIdentitySupported' + UseCmdletParameter = $true + } + @{ + Parameter = 'PasswordNotRequired' + UseCmdletParameter = $true + } + @{ + Parameter = 'SmartcardLogonRequired' + UseCmdletParameter = $true + } @{ Parameter = 'ServicePrincipalNames' } @@ -397,6 +423,24 @@ function Get-TargetResource [System.String] $Manager, + # Specifies the computers that the user can access. (ldapDisplayName 'userWorkStations') + [Parameter()] + [ValidateNotNull()] + [System.String] + $LogonWorkstations, + + # Specifies the user's organization (ldapDisplayName 'o') + [Parameter()] + [ValidateNotNull()] + [System.String] + $Organization, + + # Specifies a name in addition to a user's given name and surname (ldaDisplayName 'middleName') + [Parameter()] + [ValidateNotNull()] + [System.String] + $OtherName, + # Specifies if the account is enabled (default True) [Parameter()] [ValidateNotNull()] @@ -427,6 +471,36 @@ function Get-TargetResource [System.Boolean] $TrustedForDelegation, + # Indicates whether the security context of the user is delegated to a service. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AccountNotDelegated, + + # Indicates whether reversible password encryption is allowed for the account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AllowReversiblePasswordEncryption, + + # Specifies whether an account supports Kerberos service tickets which includes the authorization data for the user's device. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $CompoundIdentitySupported, + + # Specifies whether the account requires a password. A password is not required for a new account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $PasswordNotRequired, + + # Specifies whether a smart card is required to logon. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $SmartcardLogonRequired, + # Specifies the Active Directory Domain Services instance to use to perform the task. [Parameter()] [ValidateNotNull()] @@ -795,6 +869,24 @@ function Test-TargetResource [System.String] $Manager, + # Specifies the computers that the user can access. (ldapDisplayName 'userWorkStations') + [Parameter()] + [ValidateNotNull()] + [System.String] + $LogonWorkstations, + + # Specifies the user's organization (ldapDisplayName 'o') + [Parameter()] + [ValidateNotNull()] + [System.String] + $Organization, + + # Specifies a name in addition to a user's given name and surname (ldaDisplayName 'middleName') + [Parameter()] + [ValidateNotNull()] + [System.String] + $OtherName, + # Specifies if the account is enabled (default True) [Parameter()] [ValidateNotNull()] @@ -825,6 +917,36 @@ function Test-TargetResource [System.Boolean] $TrustedForDelegation, + # Indicates whether the security context of the user is delegated to a service. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AccountNotDelegated, + + # Indicates whether reversible password encryption is allowed for the account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AllowReversiblePasswordEncryption, + + # Specifies whether an account supports Kerberos service tickets which includes the authorization data for the user's device. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $CompoundIdentitySupported, + + # Specifies whether the account requires a password. A password is not required for a new account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $PasswordNotRequired, + + # Specifies whether a smart card is required to logon. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $SmartcardLogonRequired, + # Specifies the Active Directory Domain Services instance to use to perform the task. [Parameter()] [ValidateNotNull()] @@ -1181,6 +1303,24 @@ function Set-TargetResource [System.String] $Manager, + # Specifies the computers that the user can access. (ldapDisplayName 'userWorkStations') + [Parameter()] + [ValidateNotNull()] + [System.String] + $LogonWorkstations, + + # Specifies the user's organization (ldapDisplayName 'o') + [Parameter()] + [ValidateNotNull()] + [System.String] + $Organization, + + # Specifies a name in addition to a user's given name and surname (ldaDisplayName 'middleName') + [Parameter()] + [ValidateNotNull()] + [System.String] + $OtherName, + # Specifies if the account is enabled (default True) [Parameter()] [ValidateNotNull()] @@ -1211,6 +1351,36 @@ function Set-TargetResource [System.Boolean] $TrustedForDelegation, + # Indicates whether the security context of the user is delegated to a service. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AccountNotDelegated, + + # Indicates whether reversible password encryption is allowed for the account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $AllowReversiblePasswordEncryption, + + # Specifies whether an account supports Kerberos service tickets which includes the authorization data for the user's device. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $CompoundIdentitySupported, + + # Specifies whether the account requires a password. A password is not required for a new account. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $PasswordNotRequired, + + # Specifies whether a smart card is required to logon. + [Parameter()] + [ValidateNotNull()] + [System.Boolean] + $SmartcardLogonRequired, + # Specifies the Active Directory Domain Services instance to use to perform the task. [Parameter()] [ValidateNotNull()] diff --git a/DSCResources/MSFT_xADUser/MSFT_xADUser.schema.mof b/DSCResources/MSFT_xADUser/MSFT_xADUser.schema.mof index 1d0f7aaab..04bc8db1a 100644 --- a/DSCResources/MSFT_xADUser/MSFT_xADUser.schema.mof +++ b/DSCResources/MSFT_xADUser/MSFT_xADUser.schema.mof @@ -40,6 +40,9 @@ class MSFT_xADUser : OMI_BaseResource [Write, Description("Specifies the user's pager number (ldapDisplayName 'pager')")] String Pager; [Write, Description("Specifies the user's IP telephony phone number (ldapDisplayName 'ipPhone')")] String IPPhone; [Write, Description("Specifies the user's manager specified as a Distinguished Name (ldapDisplayName 'manager')")] String Manager; + [Write, Description("Specifies the computers that the user can access. To specify more than one computer, create a single comma-separated list. You can identify a computer by using the Security Account Manager (SAM) account name (sAMAccountName) or the DNS host name of the computer. The SAM account name is the same as the NetBIOS name of the computer. The LDAP display name (ldapDisplayName) for this property is userWorkStations.")] String LogonWorkstations; + [Write, Description("Specifies the user's organization. This parameter sets the Organization property of a user object. The LDAP display name (ldapDisplayName) of this property is o.")] String Organization; + [Write, Description("Specifies a name in addition to a user's given name and surname, such as the user's middle name. This parameter sets the OtherName property of a user object. The LDAP display name (ldapDisplayName) of this property is middleName.")] String OtherName; [Write, Description("Specifies if the account is enabled (default True)")] Boolean Enabled; [Write, Description("Specifies whether the account password can be changed")] Boolean CannotChangePassword; [Write, Description("Specifies whether the account password must be changed during the next logon attempt. This cannot be set to true if the PasswordNeverExpires property is also set to true")] Boolean ChangePasswordAtLogon; @@ -51,5 +54,10 @@ class MSFT_xADUser : OMI_BaseResource [Write, Description("Specifies whether an account is trusted for Kerberos delegation (default $false)")] Boolean TrustedForDelegation; [Write, Description("Try to restore the user object from the recycle bin before creating a new one.")] Boolean RestoreFromRecycleBin; [Write, Description("Specifies the service principal names for the user account.")] String ServicePrincipalNames[]; + [Write, Description("Indicates whether the security context of the user is delegated to a service. When this parameter is set to true, the security context of the account is not delegated to a service even when the service account is set as trusted for Kerberos delegation. This parameter sets the AccountNotDelegated property for an Active Directory account. This parameter also sets the ADS_UF_NOT_DELEGATED flag of the Active Directory User Account Control (UAC) attribute.")] Boolean AccountNotDelegated; + [Write, Description("Indicates whether reversible password encryption is allowed for the account. This parameter sets the AllowReversiblePasswordEncryption property of the account. This parameter also sets the ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED flag of the Active Directory User Account Control (UAC) attribute.")] Boolean AllowReversiblePasswordEncryption; + [Write, Description("Specifies whether an account supports Kerberos service tickets which includes the authorization data for the user's device. This value sets the compound identity supported flag of the Active Directory msDS-SupportedEncryptionTypes attribute.")] Boolean CompoundIdentitySupported; + [Write, Description("Specifies whether the account requires a password. A password is not required for a new account. This parameter sets the PasswordNotRequired property of an account object.")] Boolean PasswordNotRequired; + [Write, Description("Specifies whether a smart card is required to logon. This parameter sets the SmartCardLoginRequired property for a user object. This parameter also sets the ADS_UF_SMARTCARD_REQUIRED flag of the Active Directory User Account Control attribute.")] Boolean SmartcardLogonRequired; [Read, Description("Returns the X.500 path of the object")] String DistinguishedName; }; diff --git a/Tests/Unit/MSFT_xADUser.Tests.ps1 b/Tests/Unit/MSFT_xADUser.Tests.ps1 index 05e83dd2d..1864838d2 100644 --- a/Tests/Unit/MSFT_xADUser.Tests.ps1 +++ b/Tests/Unit/MSFT_xADUser.Tests.ps1 @@ -63,9 +63,13 @@ try 'UserPrincipalName', 'DisplayName', 'Path', 'GivenName', 'Initials', 'Surname', 'Description', 'StreetAddress', 'POBox', 'City', 'State', 'PostalCode', 'Country', 'Department', 'Division', 'Company', 'Office', 'JobTitle', 'EmailAddress', 'EmployeeID', 'EmployeeNumber', 'HomeDirectory', 'HomeDrive', 'HomePage', 'ProfilePath', - 'LogonScript', 'Notes', 'OfficePhone', 'MobilePhone', 'Fax', 'Pager', 'IPPhone', 'HomePhone', 'CommonName' + 'LogonScript', 'Notes', 'OfficePhone', 'MobilePhone', 'Fax', 'Pager', 'IPPhone', 'HomePhone', 'CommonName', + 'Manager', 'LogonWorkstations', 'Organization', 'OtherName' ) - $testBooleanProperties = @('PasswordNeverExpires', 'CannotChangePassword', 'ChangePasswordAtLogon', 'TrustedForDelegation', 'Enabled') + $testBooleanProperties = @( + 'PasswordNeverExpires', 'CannotChangePassword', 'TrustedForDelegation', 'Enabled','AccountNotDelegated', + 'AllowReversiblePasswordEncryption', 'CompoundIdentitySupported', 'PasswordNotRequired', 'SmartcardLogonRequired' + ) $testArrayProperties = @('ServicePrincipalNames') #region Function Get-TargetResource From 76c000e02325a7771a4f41eacc22eb568d581045 Mon Sep 17 00:00:00 2001 From: Simon Heather Date: Fri, 14 Jun 2019 21:37:03 +0100 Subject: [PATCH 2/3] Update CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 476a2bab6..e5fc4eb63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,14 @@ - Added ServicePrincipalNames property ([issue #153](https://github.com/PowerShell/xActiveDirectory/issues/153)). - Added ChangePasswordAtLogon property ([issue #246](https://github.com/PowerShell/xActiveDirectory/issues/246)). - Code cleanup. + - Added LogonWorkstations property + - Added Organization property + - Added OtherName property + - Added AccountNotDelegated property + - Added AllowReversiblePasswordEncryption property + - Added CompoundIdentitySupported property + - Added PasswordNotRequired property + - Added SmartcardLogonRequired property - Changes to xADDomainController - Change the `#Requires` statement in the Examples to require the correct module. From 53102f67398210b6a0f2b3d5863d7f63de7e5d5f Mon Sep 17 00:00:00 2001 From: Simon Heather Date: Sun, 16 Jun 2019 13:19:40 +0100 Subject: [PATCH 3/3] Add missing ChangePasswordAtLogon tests --- Tests/Unit/MSFT_xADUser.Tests.ps1 | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Tests/Unit/MSFT_xADUser.Tests.ps1 b/Tests/Unit/MSFT_xADUser.Tests.ps1 index 1864838d2..fe670f643 100644 --- a/Tests/Unit/MSFT_xADUser.Tests.ps1 +++ b/Tests/Unit/MSFT_xADUser.Tests.ps1 @@ -67,7 +67,7 @@ try 'Manager', 'LogonWorkstations', 'Organization', 'OtherName' ) $testBooleanProperties = @( - 'PasswordNeverExpires', 'CannotChangePassword', 'TrustedForDelegation', 'Enabled','AccountNotDelegated', + 'PasswordNeverExpires', 'CannotChangePassword', 'ChangePasswordAtLogon', 'TrustedForDelegation', 'Enabled','AccountNotDelegated', 'AllowReversiblePasswordEncryption', 'CompoundIdentitySupported', 'PasswordNotRequired', 'SmartcardLogonRequired' ) $testArrayProperties = @('ServicePrincipalNames') @@ -113,12 +113,35 @@ try Assert-MockCalled -CommandName Get-ADUser -ParameterFilter { $Credential -eq $testCredential } -Scope It } + It "Should return correct ServicePrincipalNames" { Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $fakeADUser } $adUser = Get-TargetResource @testPresentParams -DomainAdministratorCredential $testCredential $adUser.ServicePrincipalNames | Should -Be $fakeADUser.ServicePrincipalNames } + + It "Should return the correct value of 'ChangePassswordAtLogon' if it is true" { + $mockADUser = $fakeADUser.Clone() + $mockADUser['pwdLastSet'] = 0 + $mockPresentParams = $testPresentParams.Clone() + $mockPresentParams['ChangePasswordAtLogon'] = $true + Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $mockADUser } + + $adUser = Get-TargetResource @mockPresentParams + $adUser.ChangePasswordAtLogon | Should -Be $true + } + + It "Should return the correct value of 'ChangePassswordAtLogon' if it is false" { + $mockADUser = $fakeADUser.Clone() + $mockADUser['pwdLastSet'] = 12345678 + $mockPresentParams = $testPresentParams.Clone() + $mockPresentParams['ChangePasswordAtLogon'] = $true + Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $mockADUser } + + $adUser = Get-TargetResource @mockPresentParams + $adUser.ChangePasswordAtLogon | Should -Be $false + } } #endregion