$pamServer = "pam.domain.tld" # IP/URL of PAM server $start = "2022-05-25 0:0:0 UTC" $end = "2023-05-25 0:0:0 UTC" # Function to display the open file dialog function Save-File([string] $initialDirectory){ [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog $SaveFileDialog.initialDirectory = $initialDirectory $SaveFileDialog.filter = "CSV (*.csv)| *.csv" $SaveFileDialog.ShowDialog() | Out-Null return $SaveFileDialog.filename } # Required to deal with certificate trust/validaition issues 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 # Prompt for an API key if not already set if (-not $apiKey) {$apiKey = Get-Credential -Message "Enter API Key"} # Prompt for an username/pw if not already set if (-not $cliKey) {$cliKey = Get-Credential -Message "Enter PAM Username and Password"} # Open the open file dialog $outFile = Save-File $PSScriptRoot # exit if no source file was selected if ($outFile -eq "") { Write-Host "You must choose a output file" exit } # Get the list of all Target Accounts if (-not $targetAccounts){ Write-Host "Retriving target account information..." # create Target Accounts request $request = @{ "adminUserID" = $cliKey.UserName "adminPassword" = $cliKey.GetNetworkCredential().Password "authentication" = "CSPM" "cmdName" = "searchTargetAccount" } # Get the results [xml]$taResults = Invoke-WebRequest -Uri "https://$pamServer/cspm/servlet/adminCLI" -Body $request -TimeoutSec 30 -Method Get # Get the actual results from the #cdata section [xml]$cdata = $taResults.'cw.appMessage'.content.'#cdata-section' # Create Target Accounts Array $targetAccounts = $cdata.SelectNodes('//TargetAccount') # Convert to hashtable for faster lookups $taHash = @{} $targetAccounts | foreach { $taHash[[int]$_.ID] = $_ } } # Get the list of all Target Applications if (-not $targetApps) { Write-Host "Retrieving Target Application information..." # Creae Target Apps request $request = @{ "adminUserID" = $cliKey.UserName "adminPassword" = $cliKey.GetNetworkCredential().Password "authentication" = "CSPM" "cmdName" = "searchTargetApplication" } # Get the results [xml]$tappResults = Invoke-WebRequest -Uri "https://$pamServer/cspm/servlet/adminCLI" -Body $request -TimeoutSec 30 -Method Get # Get the actual results from the #cdata section [xml]$cdata = $tappResults.'cw.appMessage'.content.'#cdata-section' # Create Target Apps Array $targetApps = $cdata.SelectNodes('//TargetApplication') # Convert to hashtable for faster lookups $tappsHash = @{} $targetApps | foreach { $tappsHash[[int]$_.ID] = $_ } } # Get all PAM users if (-not $users) { Write-Host "Retrieving PAM User info..." $userResults = Invoke-RestMethod -Uri "https://$pamServer/api.php/v1/users.json?limit=0&fields=userId%2CuserName" -Method Get -Credential $apiKey $users = $userResults.users # Convert to hashtable for faster lookups $usersHash = @{} $users | foreach { $usersHash[[int]$_.userId] = $_ } } # Get get the password view requests that have a supplied reference code. Write-Host "Retrieving view requests..." $pvrResults = Invoke-RestMethod -Uri "https://$pamServer/api.php/v1/passwords/viewRequests.json?fields=*&requestPeriodStart=$start&requestPeriodEnd=$end" -Method Get -Credential $apiKey $pvrs = $pvrResults | where 'referenceCode' -NE "" Write-Host "Processing Password View Requests..." $i = 0 foreach ($pvr in $pvrs) { $i = $i+1 Write-Progress -Activity "Processing Requests" -Status "$i of $($pvrs.count)" -PercentComplete $(($i/$pvrs.Count)*100) Write-Host Processing Password View Request $pvr.id $pvr.startDate = [datetime]::parseexact(($pvr.startDate).Replace(" UTC","Z"), 'ddd MMM dd HH:mm:ssK yyyy', $null).toUniversalTime() $pvr.endDate = [datetime]::parseexact(($pvr.startDate).Replace(" UTC","Z"), 'ddd MMM dd HH:mm:ssK yyyy', $null).toUniversalTime() $approverUserName = $usersHash[[int]$pvr.approverID].userName $requestorUserName = $usersHash[[int]$pvr.requestorID].userName $targetAccountUserName = $taHash[[int]$pvr.accountID].userName $targetApplicationName = $tappsHash[[int]$taHash[[int]$pvr.accountID].targetApplicationID].name $pvr | add-member -MemberType NoteProperty -Name "approverUserName" -Value $approverUserName $pvr | add-member -memberType NoteProperty -Name "requestorUserName" -Value $requestorUserName $pvr | add-member -memberType NoteProperty -Name "targetAccountUserName" -Value $targetAccountUserName $pvr | add-member -memberType NoteProperty -Name "deviceName" -Value $targetApplicationName } $pvrs.Count # export the csv $pvrs | select id, deviceName,targetAccountUserName,startDate,endDate,requestorUserName,referenceCode,reason,reasonDescription,comments,status,approverUserName,approvalReasonDescription | Export-Csv -Path $outFile -NoTypeInformation