Wednesday, March 15, 2017

How to create a new KeePass entry with powershell and/or wfa

For a customer this week, I had to create a WFA command (PowerShell) that was able to generate a new password and then store it into KeePass.  This command is assuming that we use a "MasterKey" (=password).  You can also work with a key file, windows user and combination of those.  But this command is just with a MasterKey.  Adoption to work with the keyfile is minimal.




Download the dar

Prerequisites:

You need to install the module "PoShKeePass".  You can find it on github.
https://github.com/PSKeePass/PoShKeePass

Input

General Input:


  • KeePass database profile : This works with a profile.  first it's created and I've added a switch so you can recreate to profile if needed.
  • KeePass group path : the internal path, within the keepass database (use '/' to go deeper).  The root path is auto detected.  if you leave blank, the root is used.  Do not include the root in this path.
  • KeePass db path
  • MasterKey Name : the name of the WFA credential to fetch (this is how we get the master password)
  • Force Remove Config : recreates the database profile

Password Input:

  • Length
  • Use Upper
  • Use Lower
  • Use Digits
  • User special chars
  • Notes

Entry Input:

  • Title
  • URL (optional)
  • Username
  • Password

Here is the powershell code


param(
 
    [Parameter(Mandatory=$false,HelpMessage="KeePass Database Profile")]
    [string]$DatabaseProfileName = "wfa_keepass",
 
    [Parameter(Mandatory=$false,HelpMessage="KeePass Group Path (relative from root)")]
    [string]$GroupPath"",
 
    [Parameter(Mandatory=$true,HelpMessage="KeePass Database Path")]
    [ValidatePattern(“^.*\.kdbx$”)]
    [string]$DatabasePath,
 
    [Parameter(Mandatory=$false,HelpMessage="MasterKey Credential Name")]
    [string]$MasterKeyName = "KeePass",
 
    [Parameter(Mandatory=$false,HelpMessage="Password Length")]
    [int]$Length = 12,
 
    [Parameter(HelpMessage="Password use uppercase")]
    [bool]$UseUpper = $true,
 
    [Parameter(HelpMessage="Password use lowercase")]
    [bool]$UseLower = $true,
 
    [Parameter(HelpMessage="Password use digits")]
    [bool]$UseDigits = $true,
 
    [Parameter(HelpMessage="Password use special characters")]
    [bool]$UseSpecial = $false,
 
    [Parameter(Mandatory=$false,HelpMessage="Entry URL - optional")]
    [string]$Url,
 
    [Parameter(Mandatory=$true,HelpMessage="Entry Title")]
    [string]$Title,
 
    [Parameter(Mandatory=$true,HelpMessage="Entry UserName")]
    [string]$UserName,
 
    [Parameter(Mandatory=$false,HelpMessage="Entry Notes")]
    [string]$Notes = "entry created by wfa",
 
    [Parameter(Mandatory=$false,HelpMessage="Force remove config")]
    [bool]$ForceRemoveConfig
)
 
Import-Module PoShKeePass
 
# function to verify and create groups
function createKeePassPath($path){
    $path = $path.Trim("/")
    $GroupPaths = $path -split "/"
    $rootPath = (Get-KeePassGroup -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword | ?{-not $_.ParentGroup}).Name
    Get-WFALogger -Info -Message "Root path : $rootPath"
    $tmppath = $rootPath

    if($path){
        foreach($g in $GroupPaths){
            $group = Get-KeePassGroup "$tmppath/$g" -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword
            if($group){
                # exists
            }else{
                Get-WFALogger -Info -Message "creating group $tmppath/$g"
                New-KeePassGroup -KeePassGroupParentPath "$tmppath" -KeePassGroupName "$g" -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword
            }
            $tmppath = "$tmppath/$g"        
        }
    }
    return $tmppath
}

$masterCred = Get-WfaCredentials $MasterKeyName
$masterPassword=$masterCred.Password
 
Get-WfaLogger -info -message "Open connection to keepass db"
$conn = New-KPConnection -Database $DatabasePath -MasterKey $masterPassword
 
Get-WfaLogger -info -message "Getting keypass profile"
$config = Get-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName
if($config -and $ForceRemoveConfig){
    Get-WfaLogger -info -message "Removing keypass profile"
    Remove-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName
}
if(-not $config){
    Get-WfaLogger -info -message "Creating keypass profile"
    New-KeePassDatabaseConfiguration -DatabaseProfileName $DatabaseProfileName -DatabasePath $DatabasePath -UseMasterKey
}
 
# create correct path, including root
$GroupPath = createKeePassPath -path $GroupPath

Get-WfaLogger -info -message "Check if entry exists"
$entries = Get-KeePassEntry -KeePassEntryGroupPath $GroupPath -AsPlainText -DatabaseProfileName $DatabaseProfileName -MasterKey $masterPassword
$entry = $entries | ?{$_.Title -eq $Title -and $_.UserName -eq $UserName}
 
if($entry){
 Get-WfaLogger -warn -message "Entry already exists"
}else{
 
 Get-WfaLogger -info -message "Generating new password"
 $newpass = New-KeePassPassword -UpperCase:$UseUpper -LowerCase:$UseLower -Digits:$UseDigits -SpecialCharacters:$UseSpecial -Length $Length
 
 Get-WfaLogger -info -message "Adding entry $UserName"
 if($Url){
     New-KeePassEntry -DatabaseProfileName $DatabaseProfileName -KeePassEntryGroupPath $GroupPath -Title $Title -UserName $UserName -KeePassPassword $newpass -Notes $Notes -MasterKey $masterPassword -URL $Url
 }else{
     New-KeePassEntry -DatabaseProfileName $DatabaseProfileName -KeePassEntryGroupPath $GroupPath -Title $Title -UserName $UserName -KeePassPassword $newpass -Notes $Notes -MasterKey $masterPassword
 }
}

1 comment :