Created
January 18, 2024 13:23
-
-
Save figueroadavid/8505b6d555d7db68c2feedaae622eb50 to your computer and use it in GitHub Desktop.
Get-ValidatedCredential - retrieves a credential object, but also validates that it is correct
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Function Get-ValidatedCredential { | |
| <# | |
| .SYNOPSIS | |
| Retrieves a credential from the user with the standard Windows dialog, and | |
| then it validates that the password is correct for the account. | |
| .DESCRIPTION | |
| Uses the standard dialog with the option to customize the title, the prompt text, and | |
| to prefill a domain name and user name. The credential is then tested against the domain | |
| to validate that the password is correct. If it is not, the user is prompted again. | |
| The user does have the option to click Cancel and exit this function. | |
| .PARAMETER DomainName | |
| The domain name of the user to validate; by default it will use the domain of the person running the script | |
| .PARAMETER DomainUser | |
| The username (sAMAccountName) of the user to validate; by default it will use the current user's account name | |
| .PARAMETER DialogTitle | |
| The title of the dialog presented to request credentials | |
| .PARAMETER DialogPrompt | |
| The prompt of the dialog presented to request credentials | |
| .PARAMETER LockoutWarningCount | |
| The number of attempts to get a valid credential before warning a user that they will lock out the account. | |
| The default is 0, which indicates no warning. | |
| .EXAMPLE | |
| PS C:\> Get-ValidatedCredential -DomainName $env:USERDOMAIN -DomainUser MyServiceAccount -DialogTitle 'Enter credentials' -DialogPrompt 'Enter the credentials for the service account to use' | |
| This prompts the user to input the credentials for MyServiceAccount out of the user's domain | |
| .EXAMPLE | |
| PS C:\> $CredentialParams = @{ | |
| DomainName = $env:USERDOMAIN | |
| DomainUser = MyServiceAccount | |
| DialogTitle = 'Enter credentials' | |
| DialogPrompt = 'Enter the credentials for the service account to use' | |
| LockoutWarningCount = 3 | |
| } | |
| PS C:\> Get-ValidatedCredential @CredentialParams | |
| This prompts the user to input the credentials for MyServiceAccount out of the user's domain, however, on the third attempt, the user is warned that they are about to lock out the account | |
| .NOTES | |
| Uses the System.DirectoryServices.AccountManagement module from .Net 3.5 | |
| .INPUTS | |
| System.String | |
| #> | |
| [OutputType([System.Management.Automation.PSCredential])] | |
| [cmdletbinding()] | |
| param( | |
| [parameter(ValueFromPipelineByPropertyName = $true)] | |
| [string]$DomainName = $env:USERDOMAIN, | |
| [parameter(ValueFromPipelineByPropertyName = $true)] | |
| [string]$DomainUser = $env:USERNAME, | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [string]$DialogTitle = 'Enter Credentials', | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [string]$DialogPrompt = 'Enter the credentials to be validated', | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [int]$LockoutCountWarning = 0 | |
| ) | |
| $MyName = $MyInvocation.InvocationName | |
| Write-Verbose -Message ('[{0}] Starting {1}' -f [DateTime]::Now, $MyName) | |
| Add-Type -AssemblyName System.DirectoryServices.AccountManagement | |
| if ($LockoutCountWarning -gt 0) { | |
| $ShouldWarn = $true | |
| } | |
| $CurrentCount = 0 | |
| $HaveValidCredentials = $false | |
| do { | |
| $CurrentCount++ | |
| if ($ShouldWarn -and $CurrentCount -eq $LockoutCountWarning) { | |
| $MB_Prompt = 'If you fail this validation, the account will be locked out' | |
| $MB_Button = [System.Windows.MessageBoxButton]::OK | |
| $MB_Icon = [System.Windows.MessageBoxImage]::Warning | |
| $MB_Title = 'Lockout Warning' | |
| [System.Windows.MessageBox]::Show($MB_Prompt, $MB_Title, $MB_Button, $MB_Icon) | |
| } | |
| $Credential = $Host.UI.PromptForCredential($DialogTitle, $DialogPrompt, ('{0}\{1}' -f $DomainName, $DomainUser), $DomainName) | |
| if ($null -eq $Credential) { | |
| #Throw 'User clicked cancel, exiting the script' | |
| Write-Verbose -Message ('[{0}] Cancel was clicked, exiting this function quietly' -f $MyName) | |
| if (Test-Path -Path variable:\Context) { | |
| $Context.Dispose() | |
| } | |
| return $null | |
| } | |
| $ContextParams = @{ | |
| TypeName = [System.DirectoryServices.AccountManagement.PrincipalContext] | |
| ArgumentList = [System.DirectoryServices.AccountManagement.ContextType]::Domain, $DomainName | |
| } | |
| $Context = New-Object @ContextParams | |
| if ($Context.ValidateCredentials($DomainUser, $Credential.GetNetworkCredential().Password)) { | |
| $HaveValidCredentials = $true | |
| Write-Verbose -Message ('[{0}] Current provided credentials are valid, and password is correct, continuing with the installation' -f $MyName) | |
| } | |
| } until ($HaveValidCredentials) | |
| $Context.Dispose() | |
| $Credential | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment