1 # A global variable that contains localized messages.
5 ConvertFrom-StringData @'
10 ConfigurationStarted=Configuration of user {0} started.
11 ConfigurationCompleted=Configuration of user {0} completed successfully.
12 UserCreated=User {0} created successfully.
13 UserUpdated=User {0} properties updated successfully.
14 UserRemoved=User {0} removed successfully.
15 NoConfigurationRequired=User {0} exists on this node with the desired properties. No action required.
16 NoConfigurationRequiredUserDoesNotExist=User {0} does not exist on this node. No action required.
17 InvalidUserName=The name {0} cannot be used. Names may not consist entirely of periods and/or spaces, or contain these characters: {1}
18 UserExists=A user with the name {0} exists.
19 UserDoesNotExist=A user with the name {0} does not exist.
20 PropertyMismatch=The value of the {0} property is expected to be {1} but it is {2}.
21 PasswordPropertyMismatch=The value of the {0} property does not match.
22 AllUserPropertisMatch=All {0} {1} properties match.
23 ConnectionError = There could be a possible connection error while trying to use the System.DirectoryServices API's.
24 MultipleMatches = There could be a possible multiple matches exception while trying to use the System.DirectoryServices API's.
28 Import-LocalizedData LocalizedData -FileName MSFT_UserResource.strings.psd1
30 Import-Module "$PSScriptRoot\..\DSCResourceHelper.psm1"
32 if (-not (IsNanoServer))
34 Add-Type -AssemblyName 'System.DirectoryServices.AccountManagement'
39 The Get-TargetResource cmdlet.
41 function Get-TargetResource
45 [parameter(Mandatory = $true)]
46 [ValidateNotNullOrEmpty()]
53 Get-TargetResourceOnNanoServer @PSBoundParameters
57 Get-TargetResourceOnFullSKU @PSBoundParameters
63 The Set-TargetResource cmdlet.
65 function Set-TargetResource
67 [CmdletBInding(SupportsShouldProcess=$true)]
70 [parameter(Mandatory = $true)]
71 [ValidateNotNullOrEmpty()]
75 [ValidateSet("Present", "Absent")]
85 [ValidateNotNullOrEmpty()]
86 [System.Management.Automation.PSCredential]
93 $PasswordNeverExpires,
96 $PasswordChangeRequired,
99 $PasswordChangeNotAllowed
104 Set-TargetResourceOnNanoServer @PSBoundParameters
108 Set-TargetResourceOnFullSKU @PSBoundParameters
114 The Test-TargetResource cmdlet is used to validate if the resource is in a state as expected in the instance document.
116 function Test-TargetResource
120 [parameter(Mandatory = $true)]
121 [ValidateNotNullOrEmpty()]
125 [ValidateSet("Present", "Absent")]
135 [ValidateNotNullOrEmpty()]
136 [System.Management.Automation.PSCredential]
143 $PasswordNeverExpires,
146 $PasswordChangeRequired,
149 $PasswordChangeNotAllowed
154 Test-TargetResourceOnNanoServer @PSBoundParameters
158 Test-TargetResourceOnFullSKU @PSBoundParameters
165 The Get-TargetResource cmdlet.
167 function Get-TargetResourceOnFullSKU
171 [parameter(Mandatory = $true)]
172 [ValidateNotNullOrEmpty()]
177 Set-StrictMode -Version Latest
179 ValidateUserName -UserName $UserName
181 # Try to find a user by a name.
182 $principalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Machine)
186 $user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($principalContext, $UserName);
189 # The user is found. Return all user properties and Ensure="Present".
191 UserName = $user.Name;
193 FullName = $user.DisplayName;
194 Description = $user.Description;
195 Disabled = -not $user.Enabled;
196 PasswordNeverExpires = $user.PasswordNeverExpires;
197 PasswordChangeRequired = $null;
198 PasswordChangeNotAllowed = $user.UserCannotChangePassword;
204 # The user is not found. Return Ensure=Absent.
206 UserName = $UserName;
212 ThrowExceptionDueToDirectoryServicesError -ErrorId "MultipleMatches" -ErrorMessage ($LocalizedData.MultipleMatches + $_)
221 $principalContext.Dispose();
227 The Set-TargetResource cmdlet.
229 function Set-TargetResourceOnFullSKU
231 [CmdletBInding(SupportsShouldProcess=$true)]
234 [parameter(Mandatory = $true)]
235 [ValidateNotNullOrEmpty()]
239 [ValidateSet("Present", "Absent")]
249 [ValidateNotNullOrEmpty()]
250 [System.Management.Automation.PSCredential]
257 $PasswordNeverExpires,
260 $PasswordChangeRequired,
263 $PasswordChangeNotAllowed
266 Set-StrictMode -Version Latest
268 Write-Verbose -Message ($LocalizedData.ConfigurationStarted -f $UserName)
270 ValidateUserName -UserName $UserName
273 # Try to find a user by a name.
274 $principalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Machine)
278 $user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($principalContext, $UserName);
279 if($Ensure -eq "Present")
281 # Ensure is set to "Present".
283 $whatIfShouldProcess = $true;
284 $userExists = $false;
285 $saveChanges = $false;
289 # A user does not exist. Check WhatIf for adding a user.
290 $whatIfShouldProcess = $pscmdlet.ShouldProcess($LocalizedData.UserWithName -f $UserName, $LocalizedData.AddOperation);
297 # Check WhatIf for setting a user.
298 $whatIfShouldProcess = $pscmdlet.ShouldProcess($LocalizedData.UserWithName -f $UserName, $LocalizedData.SetOperation);
301 if($whatIfShouldProcess)
305 # The user with the provided name does not exist. Add a new user.
306 $user = New-Object System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList $principalContext
307 $user.Name = $UserName;
308 $saveChanges = $true;
311 # Set user properties.
312 if($PSBoundParameters.ContainsKey('FullName') -and (-not $userExists -or $FullName -ne $user.DisplayName))
314 $user.DisplayName = $FullName;
315 $saveChanges = $true;
321 # For a newly created user, set the DisplayName property to an empty string. By default DisplayName is set to user's name.
322 $user.DisplayName = [String]::Empty;
326 if($PSBoundParameters.ContainsKey('Description') -and (-not $userExists -or $Description -ne $user.Description))
328 $user.Description = $Description;
329 $saveChanges = $true;
332 # Password. Set the password regardless of the state of the user.
333 if($PSBoundParameters.ContainsKey('Password'))
335 $user.SetPassword($Password.GetNetworkCredential().Password);
336 $saveChanges = $true;
339 if($PSBoundParameters.ContainsKey('Disabled') -and (-not $userExists -or $Disabled -eq $user.Enabled))
341 $user.Enabled = -not $Disabled;
342 $saveChanges = $true;
345 if($PSBoundParameters.ContainsKey('PasswordNeverExpires') -and (-not $userExists -or $PasswordNeverExpires -ne $user.PasswordNeverExpires))
347 $user.PasswordNeverExpires = $PasswordNeverExpires;
348 $saveChanges = $true;
351 if($PSBoundParameters.ContainsKey('PasswordChangeRequired'))
353 if($PasswordChangeRequired)
355 # Expire the password. This will force the user to change the password at the next logon.
356 $user.ExpirePasswordNow();
357 $saveChanges = $true;
361 if($PSBoundParameters.ContainsKey('PasswordChangeNotAllowed') -and (-not $userExists -or $PasswordChangeNotAllowed -ne $user.UserCannotChangePassword))
363 $user.UserCannotChangePassword = $PasswordChangeNotAllowed;
364 $saveChanges = $true;
372 # Send an operation success verbose message.
375 Write-Verbose -Message ($LocalizedData.UserUpdated -f $UserName)
379 Write-Verbose -Message ($LocalizedData.UserCreated -f $UserName)
384 Write-Verbose -Message ($LocalizedData.NoConfigurationRequired -f $UserName)
390 # Ensure is set to "Absent".
394 if($pscmdlet.ShouldProcess($LocalizedData.UserWithName -f $UserName, $LocalizedData.RemoveOperation))
396 # Remove the user by the provided name.
400 Write-Verbose -Message ($LocalizedData.UserRemoved -f $UserName)
404 Write-Verbose -Message ($LocalizedData.NoConfigurationRequiredUserDoesNotExist -f $UserName)
410 ThrowExceptionDueToDirectoryServicesError -ErrorId "MultipleMatches" -ErrorMessage ($LocalizedData.MultipleMatches + $_)
419 $principalContext.Dispose();
422 Write-Verbose -Message ($LocalizedData.ConfigurationCompleted -f $UserName)
427 The Test-TargetResource cmdlet is used to validate if the resource is in a state as expected in the instance document.
429 function Test-TargetResourceOnFullSKU
433 [parameter(Mandatory = $true)]
434 [ValidateNotNullOrEmpty()]
438 [ValidateSet("Present", "Absent")]
448 [ValidateNotNullOrEmpty()]
449 [System.Management.Automation.PSCredential]
456 $PasswordNeverExpires,
459 $PasswordChangeRequired,
462 $PasswordChangeNotAllowed
465 Set-StrictMode -Version Latest
467 ValidateUserName -UserName $UserName
469 # Try to find a user by a name.
470 $principalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Machine)
474 $user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($principalContext, $UserName);
477 # A user with the provided name does not exist.
478 Write-Log -Message ($LocalizedData.UserDoesNotExist -f $UserName)
480 if($Ensure -eq "Absent")
490 # A user with the provided name exists.
491 Write-Log -Message ($LocalizedData.UserExists -f $UserName)
493 # Validate separate properties.
494 if($Ensure -eq "Absent")
496 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Ensure", "Absent", "Present")
497 return $false; # The Ensure property does not match. Return $false;
500 if($PSBoundParameters.ContainsKey('FullName') -and $FullName -ne $user.DisplayName)
502 Write-Log -Message ($LocalizedData.PropertyMismatch -f "FullName", $FullName, $user.DisplayName)
503 return $false; # The FullName property does not match. Return $false;
506 if($PSBoundParameters.ContainsKey('Description') -and $Description -ne $user.Description)
508 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Description", $Description, $user.Description)
509 return $false; # The Description property does not match. Return $false;
513 if($PSBoundParameters.ContainsKey('Password'))
515 if(-not $principalContext.ValidateCredentials($UserName, $Password.GetNetworkCredential().Password))
517 Write-Log -Message ($LocalizedData.PasswordPropertyMismatch -f "Password")
518 return $false; # The Password property does not match. Return $false;
522 if($PSBoundParameters.ContainsKey('Disabled') -and $Disabled -eq $user.Enabled)
524 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Disabled", $Disabled, $user.Enabled)
525 return $false; # The Disabled property does not match. Return $false;
528 if($PSBoundParameters.ContainsKey('PasswordNeverExpires') -and $PasswordNeverExpires -ne $user.PasswordNeverExpires)
530 Write-Log -Message ($LocalizedData.PropertyMismatch -f "PasswordNeverExpires", $PasswordNeverExpires, $user.PasswordNeverExpires)
531 return $false; # The PasswordNeverExpires property does not match. Return $false;
534 if($PSBoundParameters.ContainsKey('PasswordChangeNotAllowed') -and $PasswordChangeNotAllowed -ne $user.UserCannotChangePassword)
536 Write-Log -Message ($LocalizedData.PropertyMismatch -f "PasswordChangeNotAllowed", $PasswordChangeNotAllowed, $user.UserCannotChangePassword)
537 return $false; # The PasswordChangeNotAllowed property does not match. Return $false;
542 ThrowExceptionDueToDirectoryServicesError -ErrorId "ConnectionError" -ErrorMessage ($LocalizedData.ConnectionError + $_)
552 $principalContext.Dispose();
556 # All properties match. Return $true.
557 Write-Log -Message ($LocalizedData.AllUserPropertisMatch -f "User", $UserName)
564 The Get-TargetResource cmdlet.
566 function Get-TargetResourceOnNanoServer
570 [parameter(Mandatory = $true)]
571 [ValidateNotNullOrEmpty()]
576 Set-StrictMode -Version Latest
578 ValidateUserName -UserName $UserName
580 # Try to find a user by a name.
583 [Microsoft.PowerShell.Commands.LocalUser] $user = Get-LocalUser -Name $UserName -ErrorAction Stop
585 catch [System.Exception]
587 if ($_.CategoryInfo.ToString().Contains('UserNotFoundException'))
589 # The user is not found. Return Ensure=Absent.
591 UserName = $UserName;
595 Throw-TerminatingError -ErrorRecord $_
598 # The user is found. Return all user properties and Ensure="Present".
600 UserName = $user.Name;
602 FullName = $user.FullName;
603 Description = $user.Description;
604 Disabled = -not $user.Enabled;
605 PasswordChangeRequired = $null;
606 PasswordChangeNotAllowed = -not $user.UserMayChangePassword;
609 if ($user.PasswordExpires)
611 $returnValue.Add('PasswordNeverExpires', $false)
615 $returnValue.Add('PasswordNeverExpires', $true)
623 The Set-TargetResource cmdlet.
625 function Set-TargetResourceOnNanoServer
627 [CmdletBInding(SupportsShouldProcess=$true)]
630 [parameter(Mandatory = $true)]
631 [ValidateNotNullOrEmpty()]
635 [ValidateSet("Present", "Absent")]
645 [ValidateNotNullOrEmpty()]
646 [System.Management.Automation.PSCredential]
653 $PasswordNeverExpires,
656 $PasswordChangeRequired,
659 $PasswordChangeNotAllowed
662 Set-StrictMode -Version Latest
664 Write-Verbose -Message ($LocalizedData.ConfigurationStarted -f $UserName)
666 ValidateUserName -UserName $UserName
668 ## Try to find a user by a name.
669 [bool] $userExists = $false
672 [Microsoft.PowerShell.Commands.LocalUser] $user = Get-LocalUser -Name $UserName -ErrorAction Stop
675 catch [System.Exception]
677 if ($_.CategoryInfo.ToString().Contains('UserNotFoundException'))
679 # The user is not found.
680 Write-Log -Message ($LocalizedData.UserDoesNotExist -f $UserName)
684 Throw-TerminatingError -ErrorRecord $_
688 if($Ensure -eq "Present")
690 # Ensure is set to "Present".
694 # The user with the provided name does not exist. Add a new user.
695 New-LocalUser -Name $UserName -NoPassword
696 Write-Verbose -Message ($LocalizedData.UserCreated -f $UserName)
699 # Set user properties.
700 if($PSBoundParameters.ContainsKey('FullName'))
702 if (-not $userExists -or $FullName -ne $user.FullName)
704 if ($FullName -eq $null)
706 Set-LocalUser -Name $UserName -FullName ([String]::Empty)
710 Set-LocalUser -Name $UserName -FullName $FullName
716 if (-not $userExists)
718 # For a newly created user, set the DisplayName property to an empty string. By default DisplayName is set to user's name.
719 Set-LocalUser -Name $UserName -FullName ([String]::Empty)
723 if($PSBoundParameters.ContainsKey('Description') -and (-not $userExists -or $Description -ne $user.Description))
725 if ($Description -eq $null)
727 Set-LocalUser -Name $UserName -Description ([String]::Empty)
731 Set-LocalUser -Name $UserName -Description $Description
735 # Password. Set the password regardless of the state of the user.
736 if($PSBoundParameters.ContainsKey('Password'))
738 Set-LocalUser -Name $UserName -Password $Password.Password
741 if($PSBoundParameters.ContainsKey('Disabled') -and (-not $userExists -or $Disabled -eq $user.Enabled))
745 Disable-LocalUser -Name $UserName
749 Enable-LocalUser -Name $UserName
753 $existingUserPasswordNeverExpires = (($userExists) -and ($user.PasswordExpires -eq $null))
754 if($PSBoundParameters.ContainsKey('PasswordNeverExpires') -and (-not $userExists -or ($PasswordNeverExpires -ne $existingUserPasswordNeverExpires)))
756 Set-LocalUser -Name $UserName -PasswordNeverExpires:$passwordNeverExpires
759 # NOTE: The parameter name and the property name have opposite meaning.
760 [bool] $expected = -not $PasswordChangeNotAllowed
761 [bool] $actual = $expected
763 $actual = $user.UserMayChangePassword
765 if($PSBoundParameters.ContainsKey('PasswordChangeNotAllowed') -and (-not $userExists -or $expected -ne $actual))
767 Set-LocalUser -Name $UserName -UserMayChangePassword $expected
772 # Ensure is set to "Absent".
776 Remove-LocalUser -Name $UserName
778 Write-Verbose -Message ($LocalizedData.UserRemoved -f $UserName)
782 Write-Verbose -Message ($LocalizedData.NoConfigurationRequiredUserDoesNotExist -f $UserName)
787 Write-Verbose -Message ($LocalizedData.ConfigurationCompleted -f $UserName)
792 The Test-TargetResource cmdlet is used to validate if the resource is in a state as expected in the instance document.
794 function Test-TargetResourceOnNanoServer
798 [parameter(Mandatory = $true)]
799 [ValidateNotNullOrEmpty()]
803 [ValidateSet("Present", "Absent")]
813 [ValidateNotNullOrEmpty()]
814 [System.Management.Automation.PSCredential]
821 $PasswordNeverExpires,
824 $PasswordChangeRequired,
827 $PasswordChangeNotAllowed
830 Set-StrictMode -Version Latest
832 ValidateUserName -UserName $UserName
834 # Try to find a user by a name.
837 [Microsoft.PowerShell.Commands.LocalUser] $user = Get-LocalUser -Name $UserName -ErrorAction Stop
839 catch [System.Exception]
841 if ($_.CategoryInfo.ToString().Contains('UserNotFoundException'))
843 # The user is not found. Return Ensure=Absent.
844 if($Ensure -eq "Absent")
853 Throw-TerminatingError -ErrorRecord $_
856 # A user with the provided name exists.
857 Write-Log -Message ($LocalizedData.UserExists -f $UserName)
859 # Validate separate properties.
860 if($Ensure -eq "Absent")
862 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Ensure", "Absent", "Present")
863 return $false; # The Ensure property does not match. Return $false;
866 if($PSBoundParameters.ContainsKey('FullName') -and $FullName -ne $user.FullName)
868 Write-Log -Message ($LocalizedData.PropertyMismatch -f "FullName", $FullName, $user.FullName)
869 return $false; # The FullName property does not match. Return $false;
872 if($PSBoundParameters.ContainsKey('Description') -and $Description -ne $user.Description)
874 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Description", $Description, $user.Description)
875 return $false; # The Description property does not match. Return $false;
878 if($PSBoundParameters.ContainsKey('Password'))
880 if(-not (ValidateCredentialsOnNanoServer -UserName $UserName -Password $Password.Password))
882 Write-Log -Message ($LocalizedData.PasswordPropertyMismatch -f "Password")
883 return $false; # The Password property does not match. Return $false;
887 if($PSBoundParameters.ContainsKey('Disabled') -and $Disabled -eq $user.Enabled)
889 Write-Log -Message ($LocalizedData.PropertyMismatch -f "Disabled", $Disabled, $user.Enabled)
890 return $false; # The Disabled property does not match. Return $false;
893 $existingUserPasswordNeverExpires = ($user.PasswordExpires -eq $null)
894 if($PSBoundParameters.ContainsKey('PasswordNeverExpires') -and $PasswordNeverExpires -ne $existingUserPasswordNeverExpires)
896 Write-Log -Message ($LocalizedData.PropertyMismatch -f "PasswordNeverExpires", $PasswordNeverExpires, $existingUserPasswordNeverExpires)
897 return $false; # The PasswordNeverExpires property does not match. Return $false;
900 if($PSBoundParameters.ContainsKey('PasswordChangeNotAllowed') -and $PasswordChangeNotAllowed -ne (-not $user.UserMayChangePassword))
902 Write-Log -Message ($LocalizedData.PropertyMismatch -f "PasswordChangeNotAllowed", $PasswordChangeNotAllowed, (-not $user.UserMayChangePassword))
903 return $false; # The PasswordChangeNotAllowed property does not match. Return $false;
906 # All properties match. Return $true.
907 Write-Log -Message ($LocalizedData.AllUserPropertisMatch -f "User", $UserName)
913 Validates the User name for invalid charecters.
915 function ValidateUserName
919 [parameter(Mandatory = $true)]
920 [ValidateNotNullOrEmpty()]
925 # Check if the name consists of only periods and/or white spaces.
927 for($i = 0; $i -lt $UserName.Length; $i++)
929 if(-not [Char]::IsWhiteSpace($UserName, $i) -and $UserName[$i] -ne '.')
936 $invalidChars = @('\','/','"','[',']',':','|','<','>','+','=',';',',','?','*','@')
940 ThrowInvalidArgumentError -ErrorId "UserNameHasOnlyWhiteSpacesAndDots" -ErrorMessage ($LocalizedData.InvalidUserName -f $UserName, [string]::Join(" ", $invalidChars))
943 if($UserName.IndexOfAny($invalidChars) -ne -1)
945 ThrowInvalidArgumentError -ErrorId "UserNameHasInvalidCharachter" -ErrorMessage ($LocalizedData.InvalidUserName -f $UserName, [string]::Join(" ", $invalidChars))
951 Throws an argument error.
953 function ThrowInvalidArgumentError
959 [parameter(Mandatory = $true)]
960 [ValidateNotNullOrEmpty()]
964 [parameter(Mandatory = $true)]
965 [ValidateNotNullOrEmpty()]
970 $errorCategory=[System.Management.Automation.ErrorCategory]::InvalidArgument
971 $exception = New-Object System.ArgumentException $ErrorMessage;
972 $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $errorCategory, $null
976 function ThrowExceptionDueToDirectoryServicesError
981 [parameter(Mandatory = $true)]
982 [ValidateNotNullOrEmpty()]
986 [parameter(Mandatory = $true)]
987 [ValidateNotNullOrEmpty()]
992 $errorCategory = [System.Management.Automation.ErrorCategory]::ConnectionError
993 $exception = New-Object System.ArgumentException $ErrorMessage
994 $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $errorCategory, $null
998 Function Throw-TerminatingError
1002 [System.Management.Automation.ErrorRecord] $ErrorRecord
1006 if ($ErrorRecord -ne $null)
1008 $exception = new-object "System.InvalidOperationException" $Message,$ErrorRecord.Exception
1012 $exception = new-object "System.InvalidOperationException" $Message
1014 $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception,"MachineStateIncorrect","InvalidOperation",$null
1020 Writes either to Verbose or ShouldProcess channel.
1024 [CmdletBinding(SupportsShouldProcess=$true)]
1027 [parameter(Mandatory = $true)]
1028 [ValidateNotNullOrEmpty()]
1033 if ($PSCmdlet.ShouldProcess($Message, $null, $null))
1035 Write-Verbose $Message
1041 Validates the local user's credentials on the local machine.
1043 Function ValidateCredentialsOnNanoServer
1047 [parameter(Mandatory = $true)]
1048 [ValidateNotNullOrEmpty()]
1052 [ValidateNotNullOrEmpty()]
1059 private enum LogonType
1061 Logon32LogonInteractive = 2,
1062 Logon32LogonNetwork,
1064 Logon32LogonService,
1066 Logon32LogonNetworkCleartext,
1067 Logon32LogonNewCredentials
1071 private enum LogonProvider
1073 Logon32ProviderDefault = 0,
1074 Logon32ProviderWinnt35,
1075 Logon32ProviderWinnt40,
1076 Logon32ProviderWinnt50
1079 [DllImport("api-ms-win-security-logon-l1-1-1.dll", CharSet = CharSet.Unicode, SetLastError = true)]
1080 private static extern Boolean LogonUser(
1081 String lpszUserName,
1083 IntPtr lpszPassword,
1084 LogonType dwLogonType,
1085 LogonProvider dwLogonProvider,
1090 [DllImport("api-ms-win-core-handle-l1-1-0.dll",
1091 EntryPoint = "CloseHandle", SetLastError = true,
1092 CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
1093 internal static extern bool CloseHandle(IntPtr handle);
1095 public static bool ValidateCredentials(string username, SecureString password)
1097 IntPtr tokenHandle = IntPtr.Zero;
1098 IntPtr unmanagedPassword = IntPtr.Zero;
1100 unmanagedPassword = SecureStringMarshal.SecureStringToCoTaskMemUnicode(password);
1108 LogonType.Logon32LogonInteractive,
1109 LogonProvider.Logon32ProviderDefault,
1118 if (tokenHandle != IntPtr.Zero)
1120 CloseHandle(tokenHandle);
1122 if (unmanagedPassword != IntPtr.Zero) {
1123 Marshal.ZeroFreeCoTaskMemUnicode(unmanagedPassword);
1125 unmanagedPassword = IntPtr.Zero;
1130 Add-Type -PassThru -Namespace Microsoft.Windows.DesiredStateConfiguration.NanoServer.UserResource `
1131 -Name CredentialsValidationTool -MemberDefinition $source -Using System.Security -ReferencedAssemblies System.Security.SecureString.dll | Out-Null
1132 return [Microsoft.Windows.DesiredStateConfiguration.NanoServer.UserResource.CredentialsValidationTool]::ValidateCredentials($UserName, $Password)
1136 Export-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource