Jump to content

support

Administrators
  • Posts

    5,086
  • Joined

  • Last visited

  • Days Won

    318

Posts posted by support

  1. Passwordstate has many different types of two factor authentication options, and a popular choice is One Time Passwords.  One Time Passwords in an industry standard that can be used with many apps such as Google or Microsoft Authenticator.  Passwordstate's own Mobile App even has a built on One Time Password feature.  This forum post explains how to set up One Time Passwords and authenticate with them into Passwordstate.

     

    Step 1:

    Ensure you take note of your emergency password before attempting to make any change to your system like this, in case you accidently lock yourself out of the system.  You can always log in as emergency and reverse out any changes if needed.  This blog post explains the emergency access feature: https://blog.clickstudios.com.au/emergency-access-password-what-is-it-and-how-do-i-find-it/

     

    Step 2:

    You can now apply One-Time Passwords in one of three ways:

     

    1. Apply it to all users in the system, by setting the option under Administration -> System Settings -> Authentication Options (screenshot #1 below)
    2. Apply it to a subset of users, by using a User Account Policy (UAP).  This forum post explains how to set up a UAP, and you'll need to select Manual Login and One-Time Passwords as the authentication option:  https://forums.clickstudios.com.au/topic/2994-user-account-policies-explained/
    3. You can apply it to your user account only, under your own personal preferences (screenshot #2 below)

     

    Screenshot #1

    2024-02-22_9-02-36.png

     

    Screenshot #2

    2024-02-22_9-28-31.png

     

    How to use One-Time Passwords?

    The first time you log in to Passwordstate after applying One-Time Passwords, you will need to generate a QR code on the login screen. (screenshot #3 below).  You need to scan this QR code into your Mobile App, which will then present you with a temporary code you can then continually use to log into Passwordstate with. 

     

    Once you log in, this is saved to your own personal profile in Passwordstate.  This will work with any App that supports One Time Codes, such as Google, Microsoft etc.

     

    Screenshot #3 - Generate, Scan and Enter OTP

    2024-02-22_9-35-52.png

     

     

    What do you do if you lose your phone and no longer have access tot he One Time Code?

    As a Passwordstate Security Administrator, open the appropriate user account and clear the One Time Code as per screenshot #4 below.  This will present the option on the initial login screen again for the user, so they can scan in a new QR code:

     

    Screenshot #4

    2024-02-22_9-40-57.png

     

    If needed, you can always refresh your own QR code under your personal preferences, screenshot #5 and #6 below:

     

    Screenshot #5

    2024-02-22_9-43-13.png

     

     

    Screenshot #6

    2024-02-22_9-43-47.png

     

     

    Known Issues:

    Click Studio support occasionally get request advising the the One Time Code is not working for a user.  This is always due to a time difference, between the time on the phone, and the time of the Passwordstate webserver.  As One Time Passwords are a time based algorithm, the phone will need to be in sync as close as possible with the time on the webserver.  

     

    You may also have a time drift of several seconds.  Resetting this back to 0 should fix the issue:

    2024-02-22_9-52-58.png

     

     

     

    If you have any questions about any of this, please log a support call with Click Studios via our support page:  https://www.clickstudios.com.au/support-agreement.aspx

     

    Regards,

    Support.

     

     

     

  2. Hi Everyone, 

     

    Build 9849 of Passwordstate has been released, along with a new version of our Browser extensions for Chrome, Edge and Firefox that now supports Passkeys.  The browser extension versions are also 9849 and should have automatically updated in your browser.  Currently this is a beta build of the Passkeys functionality, and we'd appreciate if you notice any bug to please log a support call with Click Studios via this page: https://www.clickstudios.com.au/support.aspx

     

    You'll need to upgrade your core Passwordstate application tot he latest build by following this guide: https://www.clickstudios.com.au/downloads/version9/Upgrade_Instructions.pdf

     

    Once upgraded, you'll find a new section in the Help -> Browser Extensions Manual called "Web Authentication Passkeys" that will help understand how to use this new feature.

     

    Supported website can be found at this link:  https://passkeys.directory/

     

    Thanks to all for your feature request, and if you run into any issues with it, or have any questions, please let us know!

     

    Regards,
    Support

  3. Hi guys,

     

    For security reasons, browsers do not allow you to clear the clipboard, without some sort of user interaction.

     

    If using our browser extensions though, there is an on your Preferences screen (browser extension tab), to clear the clipboard after a certain amount of time.

    Regards

    Click Studios

  4. Hello,

     

    This functionality will be coming in version 10, which we are currently working on. Specifically, the following - at this stage we do not have a release date for V10 though.

     

    Hosts

    1. Adding a Host record

    2. Deleting a Host record

    3. Searching for Host records

     

    Host Folders

    1. Add Host Folder

    2. Delete Host Folder

    3. Search Host Folder

    4. Add Host Folder Permissions

    5. Delete Host Folder Permissions

    6. Add Host Records into Folder

    7. Remove Host Records from Folder

     

    Remote Session Credentials

    1. Add Remote Session Credential

    2. Update Remote Session Credential

    3. Delete Remote Session Credential

    4. Search Remote Session Credentials

    5. Add Remote Session Credential Permission

    6. Delete Remote Session Credential Permission

    7. Search Remote Session Credential Permissions

     

    Regards

    Click Studios

  5. Issue:

    Passwordstate has two Auditing tables, and this blog goes into great details about how they are used:  https://blog.clickstudios.com.au/auditing-archived-events-and-sql-management/

     

    Occasionally we get customers how need to clean up their old auditing data, and this forum post explains how you can do this.  There are a few reasons why you would want to do this:

     

    1. You are getting errors in your Administration -> Error Console or the Application Event logs on your webserver advising data could not be moved into the 'AuditingArchive' table due to some sort of error
    2. Your 'AuditingArchive' table is getting large in size, and you want to reduce the size of your database to ease the impact on your servers, and backup processes.
    3. To help with speeding up future upgrades of Passwordstate

     

    **Note: We would not recommend this process on any other table in the database without logging a support call with Click Studios to confirm.  AuditingArchive table is typically the only table in the database that requires this maintenance.

     

    Checking the size of the AuditingAchive Table:

    This SQL Script will output the tables sizes of every table in the Passwordstate database.  You'll need to connect to your Passwordstate database server using SQL Management Studio Tools with an account that has permissions to run this query.  This query outputs the size of each table in megabytes.

     

    USE Passwordstate
    SELECT
    s.Name AS SchemaName,
    t.Name AS TableName,
    p.rows AS RowCounts,
    CAST(ROUND((SUM(a.used_pages) / 128.00), 2) AS NUMERIC(36, 2)) AS Used_MB,
    CAST(ROUND((SUM(a.total_pages) - SUM(a.used_pages)) / 128.00, 2) AS NUMERIC(36, 2)) AS Unused_MB,
    CAST(ROUND((SUM(a.total_pages) / 128.00), 2) AS NUMERIC(36, 2)) AS Total_MB
    FROM sys.tables t
    INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id
    INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
    INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    GROUP BY t.Name, s.Name, p.Rows
    ORDER BY s.Name, t.Name

     

     

    Exporting Data:

    Below is how you can export data to a csv file from the AuditingArchive table:

     

    Connect to database server, right click the Passwordstate database and choose Export Data:

    2024-02-09_9-54-46.png

     

     

    Click Next

    2024-02-09_9-55-05.png

     

    At the Data Source page, choose the SQL Server Native Client 11.0 data source:

    2024-02-09_9-57-32.png

     

    Select Flat File Destination on the Destination screen.  Choose a file name and path to where this will be saved.  Ensure the file is a .txt file

    2024-02-09_11-07-42.png

     

     

    Click Next

    2024-02-09_10-02-48.png

     

    Choose the [dbo].[AuditingArchive] table to export, and click Next

    2024-02-09_10-03-06.png

     

    Click Next

    2024-02-09_10-03-23.png

     

    Click Finish

    2024-02-09_11-08-08.png

     

    Results should show Success status

    2024-02-09_11-08-21.png

     

     

    Clean the Auditing Archive Table:

    Now that you have exported all the data to that text file, you can safely store that away in case you need to restore at a future date, in the event you eve needed to reference that data again for compliance reasons.

     

    Next you'll need to truncate the AuditingArchive table to remove all data from it.  This can be done with another SQL Script, which is below

     

    USE Passwordstate

    TRUNCATE TABLE AuditingArchive

     

     

    This completes the process.  Your database should be significantly smaller in size now.  If you were having receiving errors in your error console or event logs about moving data into your auditingarchive table, the we'd recommend restarting your Passwordstate Window Service.

     

     

    If you have any further enquiries about this, please log a support call with Click Studios Support from this page:  https://www.clickstudios.com.au/support.aspx

     

    Regards,

    Support

     

     

     

     

  6. Issue:

    You are running a report directly from the user interface that does not execute and presents you with a general error screen, or have a scheduled report that does not execute as expected.

     

    Troubleshooting Steps:

    The first thing to check is your Base URL under Administration -> System Settings is correct.  This must be the exact URL you use to access Passwordstate including being prefixed with HTTPS.  HTTP will not work.

     

    If the above Base URL is correct, then determine if you are using something like a load balancer, app proxy or reverse proxy of some kind.  When you run a report in Passwordstate, it uses the Base URL and forms a API call by constructing a URL that looks something like this:  https://support.clickdemo.com/api/reporting/22?SiteID=0.  The section in red is the Base URL and the bold section is the additional parameters that is specific to make this report run.

     

    It's possible that the API URL is being malformed by the Proxy server, and one way to confirm this is to bypass the proxy and run the report again. A quick way to do this is to:

     

    • Create a new test HTTPS binding in IIS, along with functioning DNS for that new binding
    • Update the Base URL in Passwordstate to that new URL, and run the report again

     

    If this runs successfully, then maybe look at logs on the Proxy server to see what the URL being passed is, and hopefully this can be bypassed somehow in the Proxy server settings.

     

    If you need to see the different URLs that each report produces to help you troubleshoot this for any other report, please got to the API manuals found under the help menu, and in those manuals you’ll find a reporting section.  Each report has a slightly different URL depending on what data it is trying to achieve.

     

    Regards,

    Support

  7. A customer has request a System Setting to make the Password List option "Users must first specify a reason why they need to view, edit or copy passwords" mandatory for appropriate calls in the API's.

    With the different API calls which can retrieve password records, this would require either an exception to be raised if the "reason" is not specified, or records excluded from the method which searches across multiple Password Lists.

  8. Hi Alan,

     

    Thanks for your request.

     

    We don't know if the following would fulfill all your requirements, but are you aware you can currently add "dependency" scripts to password records - so when a reset occurs, it can trigger the execution of dependency script?

     

    If you have a look in our PAM manual, section "18 Password Reset Dependency Records", this might give you some idea of what's possible - https://www.clickstudios.com.au/downloads/version9/Passwordstate_Privileged_Account_Management_Manual.pdf

     

    Let us know if you think you need any additional functionality on top of this.

     

    Regards

    Click Studios

  9. Error:

    Build No '9835' - Error Code = The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the <machineKey> configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster., StackTrace = at System.Web.Helpers.AntiXsrf.AntiForgeryTokenSerializer.Deserialize(String serializedToken) at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext) at uRM=.zSI=.uhM=(Object zyI=, EventArgs 0CI=)

     

    Fix:

    Set up Session Persistence in the Netscalar.  This is under the Configuration tab -> Traffic Management -> Load Balancing -> Virtual Servers page.  If you open your virtual server you use for Passwordstate, then you can enable Persistence like my screenshot below:

    2023-12-20_14-13-55.png

     

     

    Regards,

    Support.

  10. Purpose:

    Passwordstate currently has a built in feature to import KeePass data into a folder structure with shared lists, but currently it's not possible to import into Private Lists within the User Interface.  This script below will allow you to import into Private Lists for a single user.

     

    Note:

    This script is using the Windows API, so you must be logged into a Windows machine, with a domain account that has a login into Passwordstate.  All Passwords Lists will be created as Private lists, and only that user will see the imported Folder and Password Lists.

     

    Requirements:

    You will need to create a Password List Template with the settings below.  Take note of the Password List Template ID when creating this List.

    2023-12-14_10-49-24.png

     

    2023-12-14_10-51-00.png

     

    2023-12-14_10-51-08.png

     

    How to Run the Script:

    In a section below is the entire contents of the script you'll need to open in Powershell ISE.  You'll need to modify the top three lines of the script with the relevant information to your environment, Passwordstate URL, path to KeePass XML file, and the Password List Template ID for the template you created above:

     

    2023-12-14_11-21-57.png

     

     

    Results:

    After running the script, you will see a new folder in the root of Passwords Home, which will be named after the exact name of your KeePass database.  All nested Lists will be Private, and only the user who ran the script will see this folder structure and nested Password Lists/Passwords.

    2023-12-14_10-53-24.png

     

    Powershell Script Contents:

     

    $global:PasswordstateURL = "https://support.clickdemo.com"
    $KeePassFile = "C:\Data\Import\Keepass\Database.xml"
    $global:PasswordstateTemplateID = "79"


    add-type @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class TrustAllCertsPolicy : ICertificatePolicy {
            public bool CheckValidationResult(
                ServicePoint srvPoint, X509Certificate certificate,
                WebRequest request, int certificateProblem) {
                return true;
            }
        }
    "@
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12


    switch -regex ($global:PasswordstateLinkToTemplate)
    {
        "(Y(e|es)?|True)" {$global:PasswordstateLinkToTemplate = $true; break}
        default {$global:PasswordstateLinkToTemplate = $false; break}
    }
    switch -regex ($global:PasswordstateTakePermsFromTemplate)
    {
        "(Y(e|es)?|True)" {$global:PasswordstateTakePermsFromTemplate = $true;break}
        default {
            $global:PasswordstateTakePermsFromTemplate = $false
            break
        }
    }

    #region Passwordstate Functions
    Function CreatePasswordstateFolder() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Name,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Description,
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$ParentFolderID       
        ) 
     
        Begin { 
        
        } 
     
        Process { 
            $Body = @{
                FolderName = $Name
                Description = $Description
                NestUnderFolderID = $ParentFolderID
            }

            $jsonBody = $Body | ConvertTo-Json

            $PasswordstateURLFull = "$($global:PasswordstateURL)/winapi/folders"
            $result = Invoke-Restmethod -Method POST -Uri $PasswordstateURLFull -ContentType "application/json" -Body ([System.Text.Encoding]::UTF8.GetBytes($jsonBody)) -UseDefaultCredentials
            $output = $result.FolderID
        }

        End {
            Write-Output $output
        }

    }

    Function CreatePasswordstatePasswordlist() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Name,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Description,
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$ParentFolderID
        ) 
     
        Begin {  } 
     
        Process { 
            $Body = @{
                PasswordList = $Name
                Description = $Description
                ApplyPermissionsForUserID = "$env:USERDOMAIN\$env:USERNAME"
                Permission = if($global:PasswordstateTakePermsFromTemplate -eq $False) {"A"} else {$null}
                CopySettingsFromTemplateID = $global:PasswordstateTemplateID
                LinkToTemplate = $global:PasswordstateLinkToTemplate
                PrivatePasswordList = "true"
                NestUnderFolderID = $ParentFolderID
                SiteID = "0"
            }

            $jsonBody = $Body | ConvertTo-Json

            $PasswordstateURLFull = "$($global:PasswordstateURL)/winapi/passwordlists"
            $result = Invoke-Restmethod -Method POST -Uri $PasswordstateURLFull -ContentType "application/json" -Body ([System.Text.Encoding]::UTF8.GetBytes($jsonBody)) -UseDefaultCredentials
            $output = $result.PasswordListID 
        }

        End {
            Write-Output $output
        }

    }

    Function AddPasswordstatePasswordToPasswordlist() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [Int]$PasswordListID,
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Title,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Username,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Password,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Description,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Notes,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$URL,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$OTP
        ) 
     
        Begin { 
            If ($Notes) {
                $Notes = ConvertTextToHtml -text $Notes
            }
        } 
     
        Process { 
            $Body = @{
                PasswordListID = $PasswordListID
                Title = $Title
                Username = $Username
                Password = $Password
                Notes = $Notes
                URL = $URL
                OTPUri = $OTP
                Description = $Description
            }
            $jsonBody = $Body | ConvertTo-Json
            
            $PasswordstateURLFull = "$($global:PasswordstateURL)/winapi/passwords"
            #We are calling the WinAPI here, as you cannot add in passwords into a Private Password List wiht a System Wide API Key. This script will not work when running inside Passwordstate, it must be run outside of Passwordstate, in Powershell, under the identity of the user who wants to do the import.  Must be an AD account.
            $result = Invoke-Restmethod -Method Post -Uri $PasswordstateUrlFull -ContentType "application/json" -Body ([System.Text.Encoding]::UTF8.GetBytes($jsonBody)) -UseDefaultCredentials
            $output = $result.PasswordID 
        }

        End {
            Write-Output $output
        }

    }
    #endregion

    #region GeneralFunctions
    Function ConvertTextToHtml() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$text          
        ) 
     
        Begin {  } 
     
        Process { 
            $html = $($text -replace "\n", "<br>")
        }

        End {
            Write-Output $html
        }

    }

    Function CreateFoldersRecursive() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$PasswordstateParentFolderID, 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [Object]$KeePassGroup,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Tree        
        ) 
     
        Begin {        
            $Tree = $Tree + "/" + $KeePassGroup.Name
        } 
     
        Process { 
            $Tree = $Tree + "/" + $KeePassGroup.Name
            
            #Check if folder has children; if yes, create folder, else create password list (terminal-folder)
            If ($KeePassGroup.Group) {
                #Create subfolder in Passwordstate
                $passwordStateNewFolderID = CreatePasswordstateFolder -Name $KeePassGroup.Name -Description $KeePassGroup.Notes -ParentFolderID $PasswordstateParentFolderID

                #Check if there are passwords in this folder; if yes, create a password list beneath the folder with the same name and all its passwords
                If ($KeePassGroup.Entry) {
                    $passwordStateNewPasswordlistID = CreatePasswordstatePasswordlist -Name $KeePassGroup.Name -Description $KeePassGroup.Notes -ParentFolderID $passwordStateNewFolderID
                    AddPasswordsToPasswordlist -PasswordListID $passwordStateNewPasswordlistID -KeePassEntries $KeePassGroup.Entry -Tree $Tree
                }

                #do so for all SubFolders
                ForEach ($group in $KeePassGroup.Group) {
                    CreateFoldersRecursive -PasswordstateParentFolderID $passwordStateNewFolderID -KeePassGroup $group -Tree $Tree
                }
            } Else {
                $passwordStateNewPasswordlistID = CreatePasswordstatePasswordlist -Name $KeePassGroup.Name -Description $KeePassGroup.Notes -ParentFolderID $PasswordstateParentFolderID
                If ($KeePassGroup.Entry) {
                    AddPasswordsToPasswordlist -PasswordListID $passwordStateNewPasswordlistID -KeePassEntries $KeePassGroup.Entry -Tree $Tree
                }
            }        
        }
    }

    Function AddPasswordsToPasswordlist() {
        Param ( 
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$PasswordListID,
                [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [Object]$KeePassEntries,
                [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)]
                [String]$Tree 
        ) 
     
        Begin {   } 
     
        Process {
            ForEach($KeePassEntry in $KeePassEntries) {
                $Title = ($KeePassEntry.String | Where-Object { $_.Key -eq "Title" }).Value
                $Username = ($KeePassEntry.String | Where-Object { $_.Key -eq "Username" }).Value
                $Password = ($KeePassEntry.String | Where-Object { $_.Key -eq "Password" }).Value.'#text'
                $Description = ($KeePassEntry.String | Where-Object { $_.Key -eq "Notes" }).Value
                $URL = ($KeePassEntry.String | Where-Object { $_.Key -eq "URL" }).Value
                $Secret = ($KeePassEntry.String | Where-Object { $_.Key -eq "TimeOtp-Secret-Base32" }).Value.'#text'
                if (($Title -eq "") -AND ($Username -ne "")) { $Title = $Username }
                if ($Title -eq "") { $Title = "no name" }
                if (!$Title){ $Title = "no name" }
                
       
                if (!(Test-Path variable:secret) -or ($Secret -eq '' -or $Secret -eq $null))
                {
                # Set OTP to be empty as there is no data to import
                $OTP = ''
                }
                else
                {
                # As we have detected a "Secret" in this KeePass record, we now build the OTP string. Algorithm, Digits and Period values may not exist in KeePass XML file, so we will need to set those with default velues
                $Issuer = $Title #Keepass does not store Issuer for the OTP entries, so we must assume the Title of the KeePass Record is the Issuer
                
                $Algorithm = ($KeePassEntry.String | Where-Object { $_.Key -eq "TimeOtp-Algorithm" }).Value
                if ($Algorithm -eq ''){$Algorithm = "HMAC-SHA-1"}

                $Digits = ($KeePassEntry.String | Where-Object { $_.Key -eq "TimeOtp-Length" }).Value
                if ($Digits -eq ''){$Digits = "6"}

                $Period = ($KeePassEntry.String | Where-Object { $_.Key -eq "TimeOtp-Period" }).Value
                if ($Period -eq ''){$Period = "30"}
                
                $OTP = "otpauth://totp/$Issuer" + "?secret=$Secret" + "&algorithm=$Algorithm" + "&digits=$Digits" + "&period=$Period"

                }
                $result = AddPasswordstatePasswordToPasswordlist -PasswordListID $PasswordListID -Title $Title -Username $Username -Password $Password -Notes $Description -URL $URL -OTP $OTP
            }        
        }

        End { }

    }
    #endregion


    try
    {    
        [xml]$XmlDocument = Get-Content -Path $KeePassFile
        $KeePassRoot = $XmlDocument.ChildNodes.Root.Group
        
        CreateFoldersRecursive -PasswordstateParentFolderID 0 -KeePassGroup $KeePassRoot
    #CreateFoldersRecursive -PasswordstateParentFolderID $global:PasswordstateImportFolderID -KeePassGroup $KeePassRoot
            
        Write-Output "Success"
    }
    catch
    {
        switch -wildcard ($error[0].Exception.ToString().ToLower())
        {
            default { Write-Output "Failed to import passwords. Error = " $error[0].Exception }
        }
    }

     

     

     

     

     

×
×
  • Create New...