diff --git a/Account Onboard Utility/Accounts_Onboard_Utility.ps1 b/Account Onboard Utility/Accounts_Onboard_Utility.ps1 index 8c0838c..e83ffb3 100644 --- a/Account Onboard Utility/Accounts_Onboard_Utility.ps1 +++ b/Account Onboard Utility/Accounts_Onboard_Utility.ps1 @@ -698,11 +698,11 @@ The Header as Dictionary object $restResponse = '' try { if ([string]::IsNullOrEmpty($Body)) { - Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Compress) -ContentType $ContentType -TimeoutSec $TimeoutSec" + Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Depth 99 -Compress ) -ContentType $ContentType -TimeoutSec $TimeoutSec" $restResponse = Invoke-RestMethod -Uri $URI -Method $Command -Header $Header -ContentType $ContentType -TimeoutSec $TimeoutSec -ErrorAction $ErrAction -Verbose:$false -Debug:$false } else { - Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Compress) -ContentType $ContentType -Body $($Body|ConvertTo-Json -Compress) -TimeoutSec $TimeoutSec" + Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Depth 99 -Compress) -ContentType $ContentType -Body $($Body|ConvertTo-Json -Compress) -TimeoutSec $TimeoutSec" $restResponse = Invoke-RestMethod -Uri $URI -Method $Command -Header $Header -ContentType $ContentType -Body $Body -TimeoutSec $TimeoutSec -ErrorAction $ErrAction -Verbose:$false -Debug:$false } Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod completed without error" @@ -1777,14 +1777,14 @@ ForEach ($account in $accountsCSV) { Write-LogMessage -type Verbose -MSG "Base:`tAccount '$g_LogAccountName' exists" # Get Existing Account Details Write-LogMessage -type Verbose -MSG "Base:`tRetrived $($objAccount.userName) from the CSV" - Write-LogMessage -type Verbose -MSG "Base:`tOutput of $($objAccount.userName) from the CSV in JSON: $($objAccount|ConvertTo-Json -Depth 5)" + Write-LogMessage -type Verbose -MSG "Base:`tOutput of $($objAccount.userName) from the CSV in JSON: $($objAccount|ConvertTo-Json -Depth 5 -Compress)" $s_Account = $(Get-Account -safeName $objAccount.safeName -accountName $objAccount.userName -accountAddress $objAccount.Address -accountObjectName $objAccount.name) If ($s_Account.Count -gt 1) { Throw "Too many accounts for '$g_LogAccountName' in safe $($objAccount.safeName)" } Write-LogMessage -type Verbose -MSG "Base:`tRetrived $($objAccount.userName) from Safe $($objAccount.safeName)" Write-LogMessage -type Verbose -MSG "Base:`tRAW format: $s_Account" - Write-LogMessage -type Verbose -MSG "Base:`tConverted to JSON: $($s_Account|ConvertTo-Json -Depth 5)" + Write-LogMessage -type Verbose -MSG "Base:`tConverted to JSON: $($s_Account|ConvertTo-Json -Depth 5 -Compress)" If ($Update) { $updateChange = $false $s_AccountBody = @() diff --git a/Connection Component/Import-ConnectionComponents.ps1 b/Connection Component/Import-ConnectionComponents.ps1 index e783ccc..74cd1e3 100644 --- a/Connection Component/Import-ConnectionComponents.ps1 +++ b/Connection Component/Import-ConnectionComponents.ps1 @@ -350,11 +350,11 @@ The Header as Dictionary object $restResponse = '' try { if ([string]::IsNullOrEmpty($Body)) { - Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Compress) -ContentType $ContentType -TimeoutSec $TimeoutSec" + Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Depth 99 -Compress) -ContentType $ContentType -TimeoutSec $TimeoutSec" $restResponse = Invoke-RestMethod -Uri $URI -Method $Command -Header $Header -ContentType $ContentType -TimeoutSec $TimeoutSec -ErrorAction $ErrAction -Verbose:$false -Debug:$false } else { - Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Compress) -ContentType $ContentType -Body $($Body|ConvertTo-Json -Compress) -TimeoutSec $TimeoutSec" + Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod -Uri $URI -Method $Command -Header $($Header|ConvertTo-Json -Depth 99 -Compress) -ContentType $ContentType -Body $($Body|ConvertTo-Json -Depth 99 -Compress) -TimeoutSec $TimeoutSec" $restResponse = Invoke-RestMethod -Uri $URI -Method $Command -Header $Header -ContentType $ContentType -Body $Body -TimeoutSec $TimeoutSec -ErrorAction $ErrAction -Verbose:$false -Debug:$false } Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tInvoke-RestMethod completed without error" diff --git a/Identity Authentication/IdentityAuth.psm1 b/Identity Authentication/IdentityAuth.psm1 index 8bdfc39..cb66e87 100644 --- a/Identity Authentication/IdentityAuth.psm1 +++ b/Identity Authentication/IdentityAuth.psm1 @@ -505,7 +505,7 @@ function Get-OAuthCreds { "grant_type" = "client_credentials" "client_id" = $($OAuthCreds.GetNetworkCredential().UserName) "client_secret" = $($OAuthCreds.GetNetworkCredential().Password) - } + } Return $($(Invoke-RestMethod "$IdaptiveBasePlatformURL/oauth2/platformtoken/" -Method 'POST' -Body $body).access_token) } diff --git a/Migration/Migration via REST/CyberArk-Migration.psm1 b/Migration/Migration via REST/CyberArk-Migration.psm1 index 0f442df..683c512 100644 --- a/Migration/Migration via REST/CyberArk-Migration.psm1 +++ b/Migration/Migration via REST/CyberArk-Migration.psm1 @@ -1208,7 +1208,7 @@ Function New-Account { ) $URL_NewAccount = "$url/api/Accounts/" Write-LogMessage -Type Debug -MSG "Entering New-Account" - Write-LogMessage -Type Verbose -MSG "Recieved the following for new account: `n$($account | ConvertTo-Json)" + Write-LogMessage -Type Verbose -MSG "Recieved the following for new account: `n$($account | ConvertTo-Json -Depth 9 -Compress)" Try { If ($allowEmpty) { $result = Invoke-Rest -Command Post -Uri $URL_NewAccount -header $logonHeader -Body $($account | ConvertTo-Json -Compress) diff --git a/Migration/Migration via REST/Invoke-Process.ps1 b/Migration/Migration via REST/Invoke-Process.ps1 index 2f0515b..b9f61a0 100644 --- a/Migration/Migration via REST/Invoke-Process.ps1 +++ b/Migration/Migration via REST/Invoke-Process.ps1 @@ -20,7 +20,7 @@ Function Invoke-ProcessSafe { Log = @() Error = @() } - + Function Write-LogMessage { param( [String]$MSG, @@ -39,7 +39,7 @@ Function Invoke-ProcessSafe { If ($safename -in $objectSafesToRemove) { Write-LogMessage -Type Info -Msg "Safe `"$($safename)`" is in the excluded safes list and will be skipped" $SafeStatus.success = $true - write-LogMessage -Type Verbose -Msg "Final `$SafeStatus $($SafeStatus | ConvertTo-Json -Compress)" + write-LogMessage -Type Verbose -Msg "Final `$SafeStatus $($SafeStatus | ConvertTo-Json -Compress -Depth 9)" continue } Write-LogMessage -Type Debug -Msg "Getting source safe `"$safename`"" @@ -145,7 +145,7 @@ Function Invoke-ProcessSafe { $srcMember.membername = $($($srcMember.membername).Split("@"))[0] $srcMember.memberType = "Role" $null = New-SafeMember -url $dstPVWAURL -logonHeader $dstToken -safe $safename -safemember $srcMember - + Write-LogMessage -Type Info -Msg "[$($safememberCount)] Safe Member $($srcMember.MemberType) `"$($srcMember.membername)`" added to safe `"$($dstsafe.safename)`" succesfully" } } elseif ($srcMember.memberType -eq "User") { @@ -164,7 +164,7 @@ Function Invoke-ProcessSafe { } Write-LogMessage -Type Info -Msg "[$($safememberCount)] Attempting to add user `"$($srcMember.membername)`" to safe `"$($dstsafe.safename)`"" $null = New-SafeMember -url $dstPVWAURL -logonHeader $dstToken -safe $safename -safemember $srcMember - + Write-LogMessage -Type Debug -Msg "[$($safememberCount)] Safe Member User`"$($srcMember.membername)`" added to safe `"$($dstsafe.safename)`"" } elseif ($srcMember.memberType -eq "Group") { Write-LogMessage -Type Debug -Msg "[$($safememberCount)] Safe Member `"$($srcMember.membername)`" is a group, attempting to find source" @@ -220,4 +220,4 @@ Function Invoke-ProcessSafe { $SafeStatus.success = $false } } -} \ No newline at end of file +} diff --git a/Migration/Migration via REST/Migrate.psm1 b/Migration/Migration via REST/Migrate.psm1 index 1302c7c..675c6c0 100644 --- a/Migration/Migration via REST/Migrate.psm1 +++ b/Migration/Migration via REST/Migrate.psm1 @@ -47,7 +47,7 @@ Function Get-CPMUsers { [OutputType([System.Boolean])] [CmdletBinding()] [OutputType([String[]])] - param([switch]$SuppressCPMWarning) + param([switch]$SuppressCPMWarning) $URL_GetCPMList = "$script:srcPVWAURL/API/ComponentsMonitoringDetails/CPM/" Try { $CPMList = Invoke-RestMethod -Method Get -Uri $URL_GetCPMList -Headers $Script:srcToken -ErrorVariable ErrorCPMList @@ -567,7 +567,7 @@ Switch to prevent running in powershell job Initialize-Function Test-SessionsValid Test-AccountList - $global:DomainList = $script:DomainList + $global:DomainList = $script:DomainList #region Safe Work $cpmUsers = Get-CPMUsers -SuppressCPMWarning:$SuppressCPMWarning @@ -708,7 +708,7 @@ Switch to prevent running in powershell job } else { Write-LogMessage -type Verbose -MSG "Final `$SafeStatus $($SafeStatus |Select-Object -Property Id,SafeName,createSkip,Success,UpdateMembersFail | ConvertTo-Json -Depth 1 -Compress)" - } + } $SafeStatus $process.Completed = $true } @@ -759,7 +759,7 @@ Switch to prevent running in powershell job $i++ } } - + $SafeFailed.SafeData | Export-Csv .\FailedSafes.csv } Write-LogMessage -type Info "Safes succesfully processed: $($SafeSuccess.success.count)" @@ -1180,7 +1180,7 @@ To get further information about the paramaters use "Get-Help Sync-Accounts -ful [array]$AccountFailed.accountData | Add-Member -MemberType NoteProperty -Name FailReason -Value $null -Force $i = 0 foreach ($id in $AccountFailed) { - $AccountFailed[$i].accountData.FailReason = $AccountFailed[$i].Error + $AccountFailed[$i].accountData.FailReason = $AccountFailed[$i].Error $i++ } $AccountFailed.accountData | Export-Csv -Force .\FailedAccounts.csv @@ -1192,28 +1192,28 @@ To get further information about the paramaters use "Get-Help Sync-Accounts -ful Function Set-DomainList { ( - [Parameter(Mandatory)] + $domainJSon ) $script:DomainList = $domainJSon } -Function New-DomainList +Function New-DomainList ( - [Parameter(Mandatory)] + $DomainName, - [Parameter(Mandatory)] + $DomainBaseContext ) { [hashtable]$script:DomainList = @{} $script:DomainList.add($DomainBaseContext, $DomainName) } -Function New-DomainEntry +Function New-DomainEntry ( - [Parameter(Mandatory)] + $DomainName, - [Parameter(Mandatory)] + $DomainBaseContext ) { IF ([string]::IsNullOrEmpty($script:domainlist)) { @@ -1230,11 +1230,11 @@ Function New-DomainEntry } } -Function Remove-DomainEntry +Function Remove-DomainEntry ( - [Parameter(Mandatory)] + $DomainName, - [Parameter(Mandatory)] + $DomainBaseContext ) { IF ([string]::IsNullOrEmpty($script:domainlist[$DomainBaseContext])) { diff --git a/Safe Management/Safe-Management.ps1 b/Safe Management/Safe-Management.ps1 index 4f30258..0b55360 100644 --- a/Safe Management/Safe-Management.ps1 +++ b/Safe Management/Safe-Management.ps1 @@ -36,7 +36,7 @@ Fixes to Set-SafeMembers param ( [Parameter(Mandatory = $true, HelpMessage = 'Please enter your PVWA address (For example: https://pvwa.mydomain.com/passwordvault)')] - [Alias('url')] + [Alias('url', 'PCloudURL')] [String]$PVWAURL, [Parameter(Mandatory = $false, HelpMessage = 'Enter the Authentication type (Default:CyberArk)')] @@ -207,6 +207,7 @@ $global:g_includeDefaultUsers = $IncludeDefault #region Functions + function Format-PVWAURL { param ( [Parameter()] @@ -226,7 +227,7 @@ function Format-PVWAURL { } #check url for improper Privilege Cloud URL and add /PasswordVault/ if not present - if ($PVWAURL -match '^(?:https|http):\/\/(?.*).cyberark.(?cloud|com)\/privilegecloud.*$') { + if ($PVWAURL -match '^(?:https|http):\/\/(?.*).cyberark.(?cloud|com)/privilegecloud/.*$') { $PVWAURL = "https://$($matches['sub']).privilegecloud.cyberark.$($matches['top'])/PasswordVault/" Write-LogMessage -type Warning -MSG "Detected improperly formated Privilege Cloud URL `nThe URL was automaticly updated to: $PVWAURL `nPlease ensure you are using the correct URL. Pausing for 10 seconds to allow you to copy correct url.`n" Start-Sleep 10 @@ -238,6 +239,132 @@ function Format-PVWAURL { } return $PVWAURL } +function Get-IdentityURL { + [CmdletBinding()] + param ( + [Parameter( + Mandatory = $true, + HelpMessage = 'Base URL of the CyberArk Identity platform', + ValueFromPipelineByPropertyName = $true)] + [string]$PCloudURL, + [Parameter(ValueFromRemainingArguments = $true, + DontShow = $true)] + $CatchAll + ) + Begin { + $PSBoundParameters.Remove('CatchAll') | Out-Null + $PCloudURL -match '^(?:https|http):\/\/(?.*).privilegecloud.cyberark.(?cloud|com)\/PasswordVault.*$' | Out-Null + $PCloudBaseURL = "https://$($matches['sub']).cyberark.$($matches['top'])" + } + Process { + If ($PSVersionTable.PSVersion.Major -gt 5) { + $IdentityBaseURL = $(Invoke-WebRequest $PCloudBaseURL -WebSession $Script:websession.value).BaseResponse.RequestMessage.RequestUri.Host + } + Else { + $IdentityBaseURL = $(Invoke-WebRequest $PCloudBaseURL -WebSession $Script:websession.value).BaseResponse.ResponseURI.Host + } + } + end { + # Return the Identity URL + $IdentityURL = "https://$IdentityBaseURL" + return $IdentityURL + } +} + +function Get-IdentityRole { + [CmdletBinding(DefaultParameterSetName = 'RoleName')] + param ( + [Parameter(ValueFromRemainingArguments, DontShow)] + $CatchAll, + + [Alias('url')] + [string] + $IdentityURL, + + [Alias('header')] + $LogonToken, + [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'roleName')] + [Alias('role')] + [string] + $roleName, + [switch] + $IDOnly, + [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'AllRoles')] + [switch] + $AllRoles + ) + + Begin { + $PSBoundParameters.Remove('CatchAll') | Out-Null + } + + Process { + if ($AllRoles) { + $query = [PSCustomObject]@{ script = 'SELECT Role.Name, Role.ID FROM Role' } + $result = Invoke-Rest -Uri "$IdentityURL/Redrock/Query" -Method POST -Body ($query | ConvertTo-Json -Depth 99) + return $result.result.results.Row | Select-Object -Property Name, ID + } + + Write-LogMessage -type Verbose -MSG "Attempting to locate Identity Role named `"$roleName`"" + $roles = [PSCustomObject]@{ + '_or' = [PSCustomObject]@{ + '_ID' = [PSCustomObject]@{ '_like' = $roleName } + }, + [PSCustomObject]@{ + 'Name' = [PSCustomObject]@{ + '_like' = [PSCustomObject]@{ + value = $roleName + ignoreCase = 'true' + } + } + } + } + + $rolequery = [PSCustomObject]@{ + 'roles' = ($roles | ConvertTo-Json -Depth 99 -Compress) + 'Args' = [PSCustomObject]@{ + 'PageNumber' = 1 + 'PageSize' = 100000 + 'Limit' = 100000 + 'SortBy' = '' + 'Caching' = -1 + } + } + + Write-LogMessage -type Verbose -MSG 'Gathering Directories' + $dirResult = Invoke-Rest -Uri "$IdentityURL/Core/GetDirectoryServices" -Method Get -Header $LogonToken + + if ($dirResult.Success -and $dirResult.result.Count -ne 0) { + Write-LogMessage -type Verbose -MSG "Located $($dirResult.result.Count) Directories" + Write-LogMessage -type Verbose -MSG "Directory results: $($dirResult.result.Results.Row)" + [string[]]$DirID = $dirResult.result.Results.Row | Where-Object { $_.Service -eq 'CDS' } | Select-Object -ExpandProperty directoryServiceUuid + $rolequery | Add-Member -Type NoteProperty -Name 'directoryServices' -Value $DirID -Force + } + + $result = Invoke-Rest -Uri "$IdentityURL/UserMgmt/DirectoryServiceQuery" -Method POST -Body ($rolequery | ConvertTo-Json -Depth 99) + + if (!$result.Success) { + Write-LogMessage -type Error -MSG $result.Message + return + } + + if ($result.Result.roles.Results.Count -eq 0) { + Write-LogMessage -type Warning -MSG 'No role found' + return + } + else { + if ($IDOnly) { + Write-LogMessage -type Verbose -MSG "Returning ID of role `"$roleName`"" + return $result.Result.roles.Results.Row._ID + } + else { + Write-LogMessage -type Verbose -MSG "Returning all information about role `"$roleName`"" + return $result.Result.roles.Results.Row + } + } + } +} + #region REST Functions # @FUNCTION@ ====================================================================================================================== @@ -272,7 +399,7 @@ The Header as Dictionary object [ValidateNotNullOrEmpty()] [String]$URI, [Parameter(Mandatory = $false)] - [Alias('Headers')] + [Alias('Headers', 'LogonToken')] $Header, [Parameter(Mandatory = $false)] $Body, @@ -1152,6 +1279,20 @@ Set-SafeMember -safename "Win-Local-Admins" -safeMember "Administrator" -memberS [bool]$permMoveAccountsAndFolders = $false ) + If ($Global:IdentityURL) { + IF ($memberType -eq 'Role') { + Write-LogMessage -type Verbose -MSG "Set-SafeMember:`tIdentityURL is set and type is role. Using Identity URL to get the correct case for the safe member" + $safeMemberUpadated = $(Get-IdentityRole -roleName $safeMember -ErrorAction Stop).Name + If ([string]::IsNullOrEmpty($safeMemberUpadated)) { + Write-LogMessage -type Warning -MSG "Set-SafeMember:`tIdentityURL is set and type is role, howevr unable to locate role $safeMember. Attempting to use current name of $safeMember" + } + else { + $safeMember = $safeMemberUpadated + Write-LogMessage -type Verbose -MSG "Set-SafeMember:`tSafeMember: $safeMember is a role, updating to $safeMemberUpadated" + } + } + } + If ($safeMember -NotIn $g_DefaultUsers) { $SafeMembersBody = @{ MemberName = "$safeMember" @@ -1342,6 +1483,14 @@ else { return } +If ($PVWAURL -match '^(?:https|http):\/\/(?.*).privilegecloud.cyberark.(?cloud|com)\/PasswordVault.*$') { + + Write-LogMessage -type Verbose -MSG "Base`tPcloudURL found: $global:PCloudURL" + $PSDefaultParameterValues['*:LogonToken'] = $logonToken + $PSDefaultParameterValues['*:PVWAURL'] = $PCloudURL + $PSDefaultParameterValues['*:IdentityURL'] = Get-IdentityURL $PCloudURL +} + #region [Logon] try { # Get Credentials to Login