11# requires -Version 5.1
22
3+ class KeeperRecordListItem {
4+ [string ]$RecordUid
5+ [string ]$Name
6+ [string ]$Type
7+ [string ]$Category
8+ [string ]$Description
9+ [int ]$Version
10+ [long ]$Revision
11+ [bool ]$Shared
12+ }
13+
14+ function Get-KeeperRecordListItems {
15+ Param (
16+ [Parameter (Mandatory = $true )][KeeperSecurity.Vault.VaultOnline ] $Vault ,
17+ [Parameter ()][switch ] $ClassicOnly
18+ )
19+
20+ if (-not $Vault ) {
21+ Write-Error - Message " Not connected to Keeper. Please run Connect-Keeper first."
22+ return [System.Collections.Generic.List [KeeperRecordListItem ]]::new()
23+ }
24+
25+ $records = [System.Collections.Generic.List [KeeperRecordListItem ]]::new()
26+
27+ if (-not $ClassicOnly.IsPresent ) {
28+ foreach ($record in $Vault.KeeperNSFRecordEntries ) {
29+ $name = if ($record.Title ) { $record.Title } else { ' ' }
30+ $type = if ($record.Type ) { $record.Type } else { ' Unknown' }
31+ if (Get-Command Get-KdRecordTypeAndTitle - ErrorAction SilentlyContinue) {
32+ $meta = Get-KdRecordTypeAndTitle $record
33+ $type = $meta.Type
34+ if (-not $name ) { $name = $meta.Title }
35+ }
36+
37+ $item = [KeeperRecordListItem ]::new()
38+ $item.RecordUid = $record.RecordUid
39+ $item.Name = $name
40+ $item.Type = $type
41+ $item.Category = ' nested'
42+ $item.Description = if ($record.Notes ) { $record.Notes.Trim () } else { ' ' }
43+ $item.Version = $record.Version
44+ $item.Revision = $record.Revision
45+ $item.Shared = $record.Shared
46+ $records.Add ($item ) | Out-Null
47+ }
48+ }
49+
50+ foreach ($record in $Vault.KeeperRecords ) {
51+ if ($record.Version -ne 2 -and $record.Version -ne 3 ) { continue }
52+
53+ $item = [KeeperRecordListItem ]::new()
54+ $item.RecordUid = $record.Uid
55+ $item.Name = if ($record.Title ) { $record.Title } else { ' ' }
56+ $item.Type = [KeeperSecurity.Utils.RecordTypesUtils ]::KeeperRecordType($record )
57+ $item.Category = ' classic'
58+ $item.Description = if ($record.Notes ) { $record.Notes.Trim () } else { ' ' }
59+ $item.Version = $record.Version
60+ $item.Revision = $record.Revision
61+ $item.Shared = $record.Shared
62+ $records.Add ($item ) | Out-Null
63+ }
64+
65+ return $records
66+ }
67+
68+ function Test-KeeperRecordFormattedListOutput {
69+ Param (
70+ [Parameter (Mandatory = $true )][System.Management.Automation.InvocationInfo ] $Invocation
71+ )
72+
73+ if ([Console ]::IsOutputRedirected) { return $false }
74+
75+ $line = $Invocation.Line
76+ if ([string ]::IsNullOrWhiteSpace($line )) { return $true }
77+
78+ if ($line -match ' (?<![\w-])(kr|Get-KeeperRecord)\b[^;\r\n]*\|\s*\S' ) { return $false }
79+ if ($line -match ' =\s*(kr\b|Get-KeeperRecord\b)' ) { return $false }
80+
81+ return $true
82+ }
83+
384function Get-KeeperRecord {
485 <#
586 . Synopsis
687 Get Keeper Records
788
89+ . Description
90+ Lists classic and nested records with Category and Description.
91+
892 . Parameter Uid
993 Record UID
1094
1195 . Parameter Filter
12- Return matching records only
96+ Return matching classic records only as KeeperRecord objects
97+
98+ . Parameter AsObject
99+ Return unified list rows (KeeperRecordListItem) for scripting
100+
101+ . Parameter ClassicOnly
102+ Exclude nested shared (NSF) records from the interactive list
13103#>
14104 [CmdletBinding ()]
15105 [OutputType ([KeeperSecurity.Vault.KeeperRecord []])]
16106 Param (
17107 [string ] $Uid ,
18- [string ] $Filter
108+ [string ] $Filter ,
109+ [Parameter ()][switch ] $AsObject ,
110+ [Parameter ()][switch ] $ClassicOnly
19111 )
20112
21113 [KeeperSecurity.Vault.VaultOnline ]$vault = getVault
@@ -28,14 +120,57 @@ function Get-KeeperRecord {
28120 Get-KeeperNSFRecord - Uid $Uid
29121 }
30122 }
31- else {
123+ elseif ( $Filter ) {
32124 foreach ($record in $vault.KeeperRecords ) {
33- if ($Filter ) {
34- $match = $ ($record.Uid , $record.TypeName , $record.Title , $record.Notes ) | Select-String $Filter | Select-Object - First 1
35- if (-not $match ) {
36- continue
125+ $match = $ ($record.Uid , $record.TypeName , $record.Title , $record.Notes ) | Select-String $Filter | Select-Object - First 1
126+ if (-not $match ) {
127+ continue
128+ }
129+ $record
130+ }
131+ }
132+ else {
133+ $useListOutput = $AsObject.IsPresent -or (Test-KeeperRecordFormattedListOutput - Invocation $MyInvocation )
134+ if ($useListOutput ) {
135+ $items = [System.Collections.Generic.List [KeeperRecordListItem ]]::new()
136+ foreach ($item in (Get-KeeperRecordListItems - Vault $vault - ClassicOnly:$ClassicOnly.IsPresent | Sort-Object - Property Name)) {
137+ $items.Add ($item ) | Out-Null
138+ }
139+
140+ if (-not $AsObject.IsPresent ) {
141+ if ($items.Count -eq 0 ) {
142+ Write-Host " No records found."
143+ return
144+ }
145+
146+ Write-Host " "
147+ Write-Host " Found $ ( $items.Count ) record(s)" - ForegroundColor Green
148+ Write-Host " "
149+
150+ $rows = foreach ($item in $items ) {
151+ $desc = $item.Description
152+ if (-not [string ]::IsNullOrEmpty($desc )) {
153+ $desc = ($desc -replace ' \s+' , ' ' ).Trim()
154+ if ($desc.Length -gt 36 ) { $desc = $desc.Substring (0 , 33 ) + ' ...' }
155+ }
156+ [PSCustomObject ]@ {
157+ UID = $item.RecordUid
158+ Name = $item.Name
159+ Type = $item.Type
160+ Category = $item.Category
161+ Description = $desc
162+ Version = $item.Version
163+ Revision = $item.Revision
164+ Shared = $item.Shared
165+ }
37166 }
167+ return $rows
38168 }
169+
170+ return $items
171+ }
172+
173+ foreach ($record in $vault.KeeperRecords ) {
39174 $record
40175 }
41176 }
0 commit comments