<#.SYNOPSISExports 'files', i.e., CyberArk Account passwords from a CyberArk Safe using PACLI..DESCRIPTIONUses CyberArk's PACLI command to export files from a CyberArk Safe.It retrieves files, their categories,and contents and exports an objectfor each.It uses filepattern=* to get all files in the safe by default.The default categories are 'Address'and'UserName'.#>param (# The name of the 'Vault' in CyberArk, e.g., 'CAMainVault' [Parameter(Mandatory = $true)][string]$VaultName,# The name of the 'Safe' in CyberArk [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$SafeName,# The CyberArk log on user (must match credentials in the User.ini) [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$Username,# The path to the PACLI directory containing PACLI.exe [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path -PathType Leaf (Join-Path $_ 'PACLI.exe') })] [string]$PACLIPath,# Arguments `findfiles` uses to generate the list of files to export [string[]]$FindFilesArguments ='filepattern=*',# The categories to export from the files [Parameter()][string[]]$Categories =@('Address', 'UserName'),# A CyberArk Vault.ini file [Parameter()][ValidateScript({ Test-Path $_ -PathType Leaf })] [string]$VaultIniPath ='Vault.ini',# A CyberArk User.ini (or .cred) file as generated by CreateCredFile.exe [Parameter()][ValidateScript({ Test-Path $_ -PathType Leaf })] [string]$UserIniPath ='User.ini',# The folder in the safe to export files from--most use 'Root' [string]$FolderName ='Root',# The session ID to use for the underlying PACLI commands [Parameter()][ValidateNotNullOrEmpty()][string]$SessionId,# ErrorAction for retrievefile errors [Parameter()][ValidateSet('Stop', 'Continue', 'SilentlyContinue')] [string]$PACLIErrorAction ='Continue')$PACLI = Join-Path $PACLIPath 'PACLI.exe'-Resolvefunction Invoke-PACLI {param ( [Parameter(Mandatory = $True)][string]$Command, [Parameter(ValueFromRemainingArguments)][string[]]$Arguments ) $Executable = ".\{0}"-f (Split-Path -Leaf $PACLI) $CommandLine = "$Executable $Command $($Arguments -join ' ')"try{ Push-Location $(Split-Path -Parent $PACLI) -StackName 'PACLI' $Output = (& $Executable $Command $Arguments 2>$null)if ($LastExitCode -eq 0) { $Output}else{switch ($PACLIErrorAction){'Continue'{ Write-Error "'$CommandLine' exited with code $LastExitCode"}'Stop'{ throw "'$CommandLine' exited with code $LastExitCode"}}}}finally{ Pop-Location -StackName 'PACLI'}}Invoke-PACLI init$PACLIDefaults ="vault=$VaultName","user=$Username","safe=$SafeName","folder=$FolderName"if ($SessionId) { $PACLIDefaults += "sessionId=$SessionId"}Invoke-PACLI default @PACLIDefaultsInvoke-PACLI definefromfile vault=$VaultName parmfile=(Resolve-Path $VaultIniPath) |Out-NullInvoke-PACLI logon logonfile=(Resolve-Path $UserIniPath) | Out-NullInvoke-PACLI opensafe | Out-Nulltry{# Create a temporary file to store the file contents during processing $tempFile = [IO.Path]::GetTempFileName()# Split the tempFile path into the folder and the filename for 'retrievefile' $localFolder = Split-Path $tempFile $localFile = Split-Path -Leaf $tempFile# Get the list of files in the safe Invoke-PACLI findfiles $FindFilesArguments 'output(name)'| Where-Object { $_.Trim()-ne ''}| ForEach-Object { $file = @{ Name = $_ }# Retrieve the file and store the contents (the password) in the file object Invoke-PACLI retrievefile file=$_ localfolder=$localFolder localfile=$localFileif ($LastExitCode -ne 0) {return} $file.Password = (Get-Content $tempFile).TrimEnd([Char]0)# Can be null-padded# Get the list of categories for the file as a quoted CSV string Invoke-PACLI listfilecategories file=$_ 'output(all,enclose)'| ForEach-Object {# Get the category name and value and strip the quotes $category = ($_ -split ','| ForEach-Object { $_.Trim('"')})[0..1]# Add the category to the file object if it is on the listif ($category[0]-in $Categories) { $file[$category[0]] = $category[1]}} [PSCustomObject]$file}}finally{ Remove-Item -Path $tempFile -Force}Invoke-PACLI closesafe vault=$VaultName user=$Username safe=$SafeName | Out-NullInvoke-PACLI logoff vault=$VaultName user=$Username | Out-NullInvoke-PACLI term | Out-Null