private/ConvertFrom-KPObject.ps1
Function ConvertFrom-KPObject { <# .SYNOPSIS Convert one or more PwEntry or PWGroup objects into a readable PSCustomObject .DESCRIPTION Convert one or more PwEntry or PWGroup objects into a readable PSCustomObject. By default only four columns are shown in a table, but there are 27 values for PwEntry and 21 for PwGroup .PARAMETER KeePassDatabase Specifies the KeePass database object to search .PARAMETER KeePassDatabase Specifies the KeePass database object to search .PARAMETER KeePassEntry Specifies one or more PwEntry objects to convert .PARAMETER KeePassGroup Specifies one or more PwGroup objects to convert .PARAMETER WithCredential If specifying a PwEntry, also return the username and password as a PowerShell credential object .PARAMETER AsPlainText If specifying a PwEntry, also return the password as plain text .PARAMETER ReplaceColumn Used internally. Replace a default shown column with the specified one .EXAMPLE ConvertFrom-KPObject -KeePassDatabase $KeePassDatabase -KeePassEntry $KeePassEntry -WithCredential -AsPlainText .NOTES For additional information please see my GitHub wiki page .LINK https://github.com/My-Random-Thoughts/PowerShellKeePass #> [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Scope = 'Function')] Param ( [Parameter(Mandatory = $true)] [KeePassLib.PwDatabase]$KeePassDatabase, [Parameter(ParameterSetName = 'Entry', Mandatory = $true)] [KeePassLib.PwEntry[]]$KeePassEntry, [Parameter(ParameterSetName = 'Group', Mandatory = $true)] [KeePassLib.PwGroup[]]$KeePassGroup, [Parameter(ParameterSetName = 'Entry')] [switch]$WithCredential, [Parameter(ParameterSetName = 'Entry')] [switch]$AsPlainText, [Parameter(DontShow)] [string]$ReplaceColumn ) Begin { # Set default object property display If ($PSCmdlet.ParameterSetName -eq 'Entry') { $defaultSet = @('Title', 'UserName', 'Url', 'LastModified') } Else { $defaultSet = @('Name', 'FullPath', 'EntryCount', 'GroupCount') } If (-not [string]::IsNullOrEmpty($ReplaceColumn)) { $del, $add = $ReplaceColumn.Split('>') $defaultSet.SetValue($add, $defaultSet.IndexOf($del)) } $defaultPropertySet = (New-Object -TypeName 'System.Management.Automation.PSPropertySet'('DefaultDisplayPropertySet', [string[]]$defaultSet)) $PSMemberInfo = [System.Management.Automation.PSMemberInfo[]]@($defaultPropertySet) } Process { If ($PSCmdlet.ParameterSetName -eq 'Entry') { ForEach ($entry In $KeePassEntry) { [string]$username = $($entry.Strings.ReadSafe('UserName')) [string]$clrPassW = $($entry.Strings.ReadSafe('Password')) [string]$passQual = ([KeePassLib.Cryptography.QualityEstimation]::EstimatePasswordBits($clrPassW)) If ($entry.Strings.GetSafe('Password').IsEmpty -eq $true) { [string]$password = '(none)' [string]$passQual = '(n/a)' } Else { [string]$password = '********' If ($AsPlainText.IsPresent) { $password = $clrPassW } If ($WithCredential.IsPresent) { If ([string]::IsNullOrEmpty($username)) { $username = '(none)' } $entryCredential = (New-Object -TypeName 'pscredential' -ArgumentList @( $username, $clrPassW | ConvertTo-SecureString -AsPlainText -Force)) } } $keePassObject = ([pscustomobject][ordered]@{ 'Uuid' = $entry.Uuid.ToHexString() 'Title' = $entry.Strings.ReadSafe('Title') 'UserName' = $entry.Strings.ReadSafe('UserName') 'Password' = $password 'PasswordQuality' = $passQual # Also set below 'Url' = $entry.Strings.ReadSafe('URL') 'Notes' = $entry.Strings.ReadSafe('Notes') 'FullPath' = $entry.ParentGroup.GetFullPath('/', $true) 'Icon' = '' # Set below 'CustomIcon' = '' # Set below 'Created' = $entry.CreationTime 'LastAccessed' = $entry.LastAccessTime 'LastModified' = $entry.LastModificationTime 'Expiry' = '' # Set below 'LocationChanged' = $entry.LocationChanged 'Touched' = $entry.Touched 'UsageCount' = $entry.UsageCount 'Fields' = @() # Set below 'Binaries' = @($entry.Binaries) 'SizeKB' = $(($entry.GetSize() / 1KB) -as [int]) 'Foreground' = $entry.ForegroundColor 'Background' = $entry.BackgroundColor 'Tags' = $entry.Tags 'OverrideUrl' = $entry.OverrideUrl 'AutoType' = $entry.AutoType 'Credential' = $entryCredential 'KeePassObject' = $entry }) # PASSWORD QUALITY # Table from: https://keepass.info/help/kb/pw_quality_est.html#trl If ($passQual -ne '(n/a)') { [float]$Quality = $(([math]::Min([float]$passQual, [double]128) / [float]128.0)) If ($Quality -le 0.2) { $keePassObject.PasswordQuality = "Very Weak ($passQual bits)" } ElseIf ($Quality -le 0.4) { $keePassObject.PasswordQuality = "Weak ($passQual bits)" } ElseIf ($Quality -le 0.6) { $keePassObject.PasswordQuality = "Moderate ($passQual bits)" } ElseIf ($Quality -le 0.8) { $keePassObject.PasswordQuality = "Strong ($passQual bits)" } Else { $keePassObject.PasswordQuality = "Very Strong ($passQual bits)" } } # ICON / CUSTOMICON If ($entry.CustomIconUuid -ne ([KeePassLib.PwUuid]::Zero)) { $keePassObject.Icon = '' $keePassObject.CustomIcon = $KeePassDatabase.GetCustomIconIndex($entry.CustomIconUuid) } Else { $keePassObject.Icon = $entry.IconId $keePassObject.CustomIcon = '' } # EXPIRY If ($entry.Expires -eq 'True') { $keePassObject.Expiry = $entry.ExpiryTime } Else { $keePassObject.Expiry = 'N/A' } # FIELDS $entry.Strings | ` Where-Object { $_.Key -notmatch 'Notes|Password|Title|Url|UserName' } | ` ForEach-Object { $keePassObject.Fields += [pscustomobject]@{ Name = $_.Key Value = $entry.Strings.ReadSafe($_.key) } } $keePassObject.PSObject.TypeNames.Insert(0, 'KeePassEntry.Output') $keePassObject | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSMemberInfo Write-Output $keePassObject } } Else { ForEach ($group In $KeePassGroup) { $keePassObject = ([pscustomobject][ordered]@{ 'Uuid' = $group.Uuid.ToHexString() 'Name' = $group.Name 'Notes' = $group.Notes 'FullPath' = $group.GetFullPath('/', $true) 'IconId' = $group.IconId 'CustomIconIndex' = $KeePassDatabase.GetCustomIconIndex($group.CustomIconUuid) 'Groups' = $group.Groups 'GroupCount' = $group.Groups.UCount 'Entries' = $group.Entries 'EntryCount' = $group.Entries.UCount 'Created' = $group.CreationTime 'LastAccessed' = $group.LastAccessTime 'LastModified' = $group.LastModificationTime 'Expiry' = '' # Set below 'LocationChanged' = $group.LocationChanged 'Touched' = $group.Touched 'UsageCount' = $group.UsageCount 'EnableAutoType' = '' # Set below 'EnableSearching' = '' # Set below 'DefaultAutoTypeSequence' = '' # Set below 'KeePassObject' = $group }) If ($group.Expires -eq 'False') { $keePassObject.Expiry = $group.ExpiryTime } Else { $keePassObject.Expiry = 'N/A' } @('EnableAutoType','EnableSearching','DefaultAutoTypeSequence') | ForEach-Object { If ($($group.$_.Length) -eq 0) { $keePassObject.$_ = 'Inherited' } Else { $keePassObject.$_ = $($group.$_) } } $keePassObject.PSObject.TypeNames.Insert(0, 'KeePassEntry.Output') $keePassObject | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSMemberInfo Write-Output $keePassObject } } } End { } } |