Skip to content

Instantly share code, notes, and snippets.

@figueroadavid
Created January 18, 2024 13:23
Show Gist options
  • Select an option

  • Save figueroadavid/8505b6d555d7db68c2feedaae622eb50 to your computer and use it in GitHub Desktop.

Select an option

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
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