|
#Requires -Version 3 |
|
|
|
#Credential file path |
|
$script:CredentialsFile = Join-Path $env:TEMP "SavedCredentials\Credentials.xml" |
|
|
|
function Set-SavedCredential() |
|
{ |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] |
|
$Id, |
|
[Parameter(Mandatory)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] |
|
$UserName, |
|
[Parameter(Mandatory)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] |
|
$Password, |
|
[switch] $Validate |
|
) |
|
#Validate credential |
|
if($Validate) |
|
{ |
|
if($UserName.StartsWith("localhost\")){ |
|
$validationContext = "Machine" |
|
}else{ |
|
$validationContext = "Domain" |
|
} |
|
$isValid = Test-Credential -UserName $UserName -Password $Password -Context $validationContext |
|
|
|
if(!$isValid){ |
|
Write-Error ("Credential Validation Failed: {0}({1})" -f $Id, $UserName) |
|
} |
|
} |
|
|
|
#Convert password to SecureString plain text |
|
$securePassword = $Password | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString |
|
|
|
#Get saved credential if exists |
|
$credentials= @{} |
|
if(Test-Path $CredentialsFile){ |
|
$credentials = Import-Clixml -Path $CredentialsFile |
|
} |
|
else{ |
|
#Ensure output directory exists |
|
$baseDir = [IO.Path]::GetDirectoryName($CredentialsFile) |
|
New-Item -Type Directory -Path $baseDir -ErrorAction Ignore | Out-Null |
|
} |
|
|
|
#add/edit credential |
|
$credentials[$Id] = @{UserName=$UserName;Password=$securePassword} |
|
|
|
#Save Credentials as CliXml Format |
|
$credentials | Export-Clixml -Path $CredentialsFile -Encoding UTF8 -Force |
|
} |
|
|
|
function Get-SavedCredential |
|
{ |
|
[CmdletBinding()] |
|
[OutputType([Management.Automation.PsCredential])] |
|
param( |
|
[Parameter(Mandatory,Position=0)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] $Id, |
|
[switch] $Validate |
|
) |
|
$credentials = Import-Clixml -Path $CredentialsFile -ErrorAction Ignore |
|
if(($credentials -eq $null) -or !($credentials.ContainsKey($Id))) |
|
{ |
|
return Get-Credential -Message "Enter Credential for $Id" #Don't save credential for temporary use. |
|
} |
|
|
|
#Get saved credential |
|
$result = $credentials[$Id] |
|
|
|
#Convert to PSCredential |
|
[string]$userName = $result.UserName |
|
$securePassword = ConvertTo-SecureString $result.Password |
|
$cred = New-Object System.Management.Automation.PsCredential($userName, $securePassword) |
|
|
|
#Validate Credential |
|
if($Validate){ |
|
if($cred.GetNetworkCredential().Domain -eq "localhost"){ |
|
$validationContext = "Machine" |
|
} |
|
else{ |
|
$validationContext = "Domain" |
|
} |
|
$isValid = Test-Credential -UserName $cred.UserName -Password $cred.GetNetworkCredential().Password -Context $validationContext |
|
|
|
if(!$isValid){ |
|
Write-Error ("Credential Validation Failed: {0}({1})" -f $Id, $userName) |
|
} |
|
} |
|
return $cred |
|
} |
|
|
|
function Clear-SavedCredential |
|
{ |
|
[CmdletBinding()] |
|
param() |
|
if(Test-Path $CredentialsFile){ |
|
#Remove credential file |
|
Remove-Item $CredentialsFile -Force |
|
} |
|
} |
|
|
|
function Show-SavedCredential |
|
{ |
|
[CmdletBinding()] |
|
[OutputType([hashtable])] |
|
param() |
|
if(!(Test-Path $CredentialsFile)){ |
|
Write-Error "Credential file not found!" |
|
} |
|
$result = Import-Clixml -Path $CredentialsFile -ErrorAction Ignore |
|
return $result |
|
} |
|
|
|
function Test-Credential |
|
{ |
|
[CmdletBinding()] |
|
[OutputType([bool])] |
|
param( |
|
[Parameter(Mandatory=$true)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] $UserName, |
|
[Parameter(Mandatory=$true)] |
|
[ValidateNotNullOrEmpty()] |
|
[string] $Password, |
|
[ValidateSet("Domain","Machine")] |
|
[string] $Context = "Domain" |
|
) |
|
begin { |
|
Add-Type -AssemblyName System.DirectoryServices.AccountManagement |
|
$ctx = New-Object DirectoryServices.AccountManagement.PrincipalContext($context) |
|
} |
|
process { |
|
return $ctx.ValidateCredentials($userName, $password) |
|
} |
|
end{ |
|
$ctx.Dispose() |
|
} |
|
} |