Skip to content

Commit

Permalink
Merge pull request #2 from itdistrict/refactoring
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
hertus authored Aug 23, 2021
2 parents 1dd1d1f + 349f56f commit f56cbbd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 57 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ Script settings in JSON format which can be defined within the script or taken f
| useWebPluginWin | "", "f008c2f0-5fb3-4c5e-a8eb-8072c1183088" | If not empty then this RoyalTS Windows Plugin ID will be taken as "Browser Engine" for Web connection entries. Also possible to just use Default Settings in RoyalTS |
| folderCreation | none, safe.name, safe.description, safe.name-description, safe.description-name | Will creates folder for all connection entries based on the provided naming scheme: **none** will create no folders, **safe.name** will create folder based on the safe name the accounts are in, **safe.description** from the safe description, **safe.name-description** from safe name + description and **safe.description-name** from safe description + safe name |
| entryName | simple (DEFAULT), named, full | Connection Entry name which can be **simple** or just empty as default and only has the "address" as entry name, **named** as "username@address" and **full** as "target - username@address" for domain users |
| enableNLA | boolean 1 (true) or 0 (false) | Enables NLA in RDP connection entries |
| enableNLA | ScrollBars, SmartResize (default) | Sets the resize mode for RDP connection in RoyalTS (RyoalTS v6 default will do a Reconnect) |
| rdpResizeMode | boolean 1 (true) or 0 (false) | Enables NLA in RDP connection entries |
| excludeAccounts | string array["user1","user2"] | Excludes these accounts / usernames from creating any connection entries |
> In some specific RoyalTS versions there is an issue with "true" und "false" value, where RoyalTS did rewrite these keywords in capital letters. This becomes an invalid type in JSON format so we use 0 (false) or 1 (true)
> instead of the keywords in our json settings
Expand Down
78 changes: 32 additions & 46 deletions clientSide/cyberArkRoyal.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ $settings = @"
"folderCreation": "safe.name",
"entryName": "named",
"enableNLA": 0,
"rdpResizeMode": "",
"excludeAccounts": ["guest"],
"useWebPluginWin": "f008c2f0-5fb3-4c5e-a8eb-8072c1183088",
"platformMappings": {
Expand Down Expand Up @@ -140,6 +141,7 @@ $EffectivePassword$
if ([string]::isNullOrEmpty( $caUser )) { $caUser = $env:username }
if ((!$groupBasedMode) -and $authPrompt) { $caCredentials = Get-Credential -UserName $caUser -Message "Please enter your CyberArk Username and Password" }


# prepare RoyalJSON response
$response = @{ }
$response.Objects = @()
Expand Down Expand Up @@ -173,7 +175,7 @@ function Get-Safes() {
$safeName = $safe.SafeName
$safes[ $safeName ] = $safe
}
if ($debugOn) { Write-Host $stopWatch.Elapsed + " wrote safes to HashTable" }
if ($debugOn) { Write-Host $stopWatch.Elapsed + " fetched safes from API" }

return $safes
}
Expand All @@ -192,6 +194,8 @@ function Get-SafeGroups() {
$safes[ $safeName ] = $group
}
}
if ($debugOn) { Write-Host $stopWatch.Elapsed + " fetched safes from groups" }

return $safes
}

Expand All @@ -218,7 +222,8 @@ function Get-ConnectionRDP($acc, $plat, $comp) {

if ([string]::isNullOrEmpty( $plat.color )) { $entry.ColorFromParent = $true } else { $entry.color = $plat.color }
if ([string]::isNullOrEmpty( $plat.replacePsm )) { $entry.ComputerName = $psmRdpAddress } else { $entry.ComputerName = $plat.replacePsm }

if ([string]::isNullOrEmpty( $settings.rdpResizeMode )) { $entry.ResizeMode = 'SmartSizing' } else { $entry.ResizeMode = $settings.rdpResizeMode }

$entry.Username = $caUser
if ($plat.drivesRedirection) { $entry.Properties.RedirectDrives = 'true' }
if ($settings.enableNLA) { $entry.NLA = 'true' } else { $entry.NLA = 'false' }
Expand Down Expand Up @@ -367,45 +372,29 @@ if ($settings.allAccountsMode) {
}
elseif ($settings.groupBasedMode) {
$safes = Get-SafeGroups
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched group based safes: $( $safes.Count )" }
if ($debugOn) { Write-Host $stopWatch.Elapsed + " fetched group based safes: $( $safes.Count )" }
}
else {
Invoke-Logon
if ($debugOn) { Write-Host $stopWatch.Elapsed + " login done" }

$safes = Get-Safes
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched safes: $( $safes.Count )" }
if ($debugOn) { Write-Host $stopWatch.Elapsed + " fetched safes: $( $safes.Count )" }
}

# get the prepared data file and remove BOM (thanks to .NET, IIS) if necessary
$jsonFileData = Invoke-WebRequest -Uri $dataUrl -Method GET -UseBasicParsing -ContentType 'application/json; charset=utf-8'
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched json file length: $( $jsonFileData.RawContentLength)" }
$safesAndAccountsList = $jsonFileData.Content | Foreach-Object { $_ -replace "\xEF\xBB\xBF", "" } | ConvertFrom-Json

# sort list
switch ($settings.folderCreation) {
"safe.name" { $sortedSafesAndAccountsList = $safesAndAccountsList.psobject.properties | Sort-Object { $_.Value.safe.safename } }
"safe.name-description" { $sortedSafesAndAccountsList = $safesAndAccountsList.psobject.properties | Sort-Object { $_.Value.safe.safename } }
"safe.description" { $sortedSafesAndAccountsList = $safesAndAccountsList.psobject.properties | Sort-Object { $_.Value.safe.description } }
"safe.description-name" { $sortedSafesAndAccountsList = $safesAndAccountsList.psobject.properties | Sort-Object { $_.Value.safe.description } }
Default { $sortedSafesAndAccountsList = $safesAndAccountsList.psobject.properties | Sort-Object { $_.Value.safe.safename } }
}
if ($debugOn) { Write-Host $stopWatch.Elapsed + " fetched json file length: $( $jsonFileData.RawContentLength)" }

# SafesAndAccountsList into a hashtable with key = order
$safesAndAccountsTable = @{ }
foreach ($entry in $sortedSafesAndAccountsList) {
$safesAndAccountsTable[ $safesAndAccountsTable.Count ] = @($entry.Name, $entry.Value)
}
if ($debugOn) { Write-Host $stopWatch.Elapsed + " wrote and sorted safesAndAccounts to HashTable" }
$safesAndAccounts = $jsonFileData.Content | Foreach-Object { $_ -replace "\xEF\xBB\xBF", "" } | ConvertFrom-Json

foreach ($safeKey in $safesAndAccountsTable.getEnumerator() | Sort-Object Key) {
$safeAndAccounts = $safeKey.Value

foreach ($safeAccount in $safesAndAccounts) {

# match safe or continue
if ( !$settings.allAccountsMode -and !$safes.ContainsKey( $safeAndAccounts.safe.SafeName ) ) { continue }
if ( !$settings.allAccountsMode -and !$safes.ContainsKey( $safeAccount.SafeName ) ) { continue }

# apply safeFilter
if ($settings.safeFilter -and !([regex]::Match( $safeAndAccounts.safe.SafeName, $settings.safeFilterRegex ).Success )) { continue }
if ($settings.safeFilter -and !([regex]::Match( $safeAccount.SafeName, $settings.safeFilterRegex ).Success )) { continue }

if ($settings.folderCreation -eq "none") {
$objects = @()
Expand All @@ -417,30 +406,27 @@ foreach ($safeKey in $safesAndAccountsTable.getEnumerator() | Sort-Object Key) {
$folder.ColorFromParent = $true

switch ($settings.folderCreation) {
"safe.name" { $folder.Name = $safeAndAccounts.safe.SafeName }
"safe.name-description" { $folder.Name = $safeAndAccounts.safe.SafeName + ' - ' + $safeAndAccounts.safe.Description }
"safe.description" { $folder.Name = $safeAndAccounts.safe.Description }
"safe.description-name" { $folder.Name = $safeAndAccounts.safe.Description + ' - ' + $safeAndAccounts.safe.SafeName }
"safe.name" { $folder.Name = $safeAccount.SafeName }
"safe.name-description" { $folder.Name = $safeAccount.SafeName + ' - ' + $safeAccount.Description }
"safe.description" { $folder.Name = $safeAccount.Description }
"safe.description-name" { $folder.Name = $safeAccount.Description + ' - ' + $safeAccount.SafeName }
}
}

# get accounts hashtable with key = ID
$accounts = @{ }
$safeAndAccounts.accounts.psobject.properties | ForEach-Object { $accounts[ $_.Name] = $_.Value }
if ($debugOn) { Write-Host $stopWatch.Elapsed + " wrote accounts from $( $safeAndAccounts.safe.SafeName) to HashTable" }
foreach ($accountKey in $accounts.Keys) {
$accountDetails = $accounts[ $accountKey]
$accountPlatform = $accountDetails.platformId
foreach ($account in $safeAccount.Accounts) {

$accountPlatform = $account.platformId

if (!$platformMapping.ContainsKey( $accountPlatform)) { continue }
if ($settings.excludeAccounts.Contains( $accountDetails.userName)) { continue }
if ($settings.excludeAccounts.Contains( $account.userName)) { continue }
if ($debugOn) { $debugNrAccounts++ }
# create connections for every configured connection component
if ($null -eq $accountDetails.remoteMachinesAccess.remoteMachines) {
Add-Member -InputObject $accountDetails -NotePropertyName 'target' -NotePropertyValue $accountDetails.address
if ($null -eq $account.remoteMachines) {
Add-Member -InputObject $account -NotePropertyName 'target' -NotePropertyValue $account.address
$royalPlatform = $platformMapping[ $accountPlatform]
foreach ($connection in $royalPlatform.connections) {
foreach ($component in $connection.components) {
$connectionEntry = Get-ConnectionEntry $accountDetails $royalPlatform $connection.Type $component
$connectionEntry = Get-ConnectionEntry $account $royalPlatform $connection.Type $component
if ($settings.folderCreation -eq "none") { $objects += $connectionEntry }
else { $folder.Objects += $connectionEntry }
if ($debugOn) { $debugNrServerConnections++ }
Expand All @@ -449,13 +435,13 @@ foreach ($safeKey in $safesAndAccountsTable.getEnumerator() | Sort-Object Key) {
}
# create connections for each remoteMachine and every configured connection component
else {
$remoteMachines = $accountDetails.remoteMachinesAccess.remoteMachines.split(';', [System.StringSplitOptions]::RemoveEmptyEntries) | Sort-Object
foreach ($rmAddress in $remoteMachines) {
Add-Member -InputObject $accountDetails -NotePropertyName 'target' -NotePropertyValue $rmAddress -Force
$rmMachines = $account.remoteMachines.split(';', [System.StringSplitOptions]::RemoveEmptyEntries) | Sort-Object
foreach ($rmAddress in $rmMachines) {
Add-Member -InputObject $account -NotePropertyName 'target' -NotePropertyValue $rmAddress -Force
$royalPlatform = $platformMapping[ $accountPlatform]
foreach ($connection in $royalPlatform.connections) {
foreach ($component in $connection.components) {
$connectionEntry = Get-ConnectionEntry $accountDetails $royalPlatform $connection.Type $component
$connectionEntry = Get-ConnectionEntry $account $royalPlatform $connection.Type $component
if ($settings.folderCreation -eq "none") { $objects += $connectionEntry }
else { $folder.Objects += $connectionEntry }
if ($debugOn) { $debugNrServerConnections++ }
Expand All @@ -477,7 +463,7 @@ foreach ($safeKey in $safesAndAccountsTable.getEnumerator() | Sort-Object Key) {
$jsonResponse = $response | ConvertTo-Json -Depth 100

if ($debugOn) {
Write-Host $stopWatch.Elapsed + " got $( $jsonResponse.objects.Count) folders with $debugNrAccounts accounts and $debugNrServerConnections server connections"
Write-Host $stopWatch.Elapsed + " got $debugNrServerConnections server connections"
Out-File -FilePath "data.json" -Encoding UTF8 -InputObject $jsonResponse
}
else {
Expand Down
24 changes: 14 additions & 10 deletions serverSide/cyberarkSafeAccountList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ function Invoke-Request {
return $response
}


#########################################
# MAIN #
#########################################
Expand Down Expand Up @@ -124,25 +123,30 @@ Write-Log -LogString "Retrieved $($safes.Count) CyberArk safes"
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched safes: $($safes.Count)" }

# get accounts from safe list
$safeAndAccountsList = @{ }
$safesAndAccounts = @()
$accountEntriesCount = 0

foreach ($safe in $safes) {
$accountURL = $pvwaUrl + '/api/Accounts?limit=1000&filter=safeName eq ' + $safe.SafeName
$accountsResult = $(Invoke-Request -Uri $accountURL -Headers $header -Method Get).content | ConvertFrom-Json
if ($null -ne $accountsResult.value -and $accountsResult.value.Length -gt 0) {
$safeAndAccountsList.Add( $safe.SafeName, @{ } )
$safeAndAccountsList[$safe.SafeName].Add( "safe", $safe )
$safeAndAccountsList[$safe.SafeName].Add( "accounts", @{ } )
$safeEntry = @{ "SafeName" = $safe.SafeName; "Description" = $safe.Description; "Accounts" = @() }

foreach ($account in $accountsResult.value) {
$safeAndAccountsList[$safe.SafeName]["accounts"].Add( $account.id, $account )
$accountEntry = @{ "userName" = $account.userName; "address" = $account.address ; "platformId" = $account.platformId; "remoteMachines" = $account.remoteMachinesAccess.remoteMachines }
$safeEntry.Accounts += $accountEntry
$accountEntriesCount++
}

$safesAndAccounts += $safeEntry
}
}
Write-Log -LogString "Retrieved $($safeAndAccountsList.Count) CyberArk accounts from all safes"
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched safes accounts: $($safeAndAccountsList.Count)" }
Write-Log -LogString "Retrieved $accountEntriesCount CyberArk accounts"
if ($debugOn) { Write-Host $stopWatch.Elapsed + " catched safes accounts: $accountEntriesCount" }

# check accounts list
if ($safeAndAccountsList.Count -gt 1) {
$results = $safeAndAccountsList | ConvertTo-Json -Depth 100
if ($safesAndAccounts.Count -gt 1) {
$results = $safesAndAccounts | ConvertTo-Json -Depth 100


$filePathBak = $filePath + '.bak'
Expand Down

0 comments on commit f56cbbd

Please sign in to comment.