Skip to content

Commit 53e3350

Browse files
committed
New function to update PVWAURL format and cleanup of whitespaces
1 parent fbd2f01 commit 53e3350

File tree

2 files changed

+231
-158
lines changed

2 files changed

+231
-158
lines changed

Account Onboard Utility/Accounts_Onboard_Utility.ps1

Lines changed: 108 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Updated error output
2828
2023-06-25 - Updated to add WideAccountsSearch, NarrowSearch, ignoreAccountName
2929
2025-01-07 - Updated to allow automatically not create duplicates, fix bad record handling, formating update
3030
2025-03-17 - Updated to allow for verbose output to a file
31+
2025-04-30 - Updated to check and correct URL scheme and path for Privilege Cloud
3132
=======
3233
3334
@@ -142,7 +143,7 @@ $PSBoundParameters.GetEnumerator() | ForEach-Object { $ScriptParameters += ("-{0
142143
$global:g_ScriptCommand = '{0} {1}' -f $ScriptFullPath, $($ScriptParameters -join ' ')
143144

144145
# Script Version
145-
$ScriptVersion = '2.6.0'
146+
$ScriptVersion = '2.6.1'
146147

147148
# Set Log file path
148149
$global:LOG_DATE = $(Get-Date -Format yyyyMMdd) + '-' + $(Get-Date -Format HHmmss)
@@ -155,43 +156,40 @@ $global:UseVerboseFile = $UseVerboseFile.IsPresent
155156

156157
[hashtable]$Global:BadAccountHashTable = @{}
157158

158-
# Global URLS
159-
# -----------
160-
$URL_PVWAAPI = $PVWAURL + '/api'
161-
$URL_Authentication = $URL_PVWAAPI + '/auth'
162-
$URL_Logon = $URL_Authentication + "/$AuthType/Logon"
163-
$URL_Logoff = $URL_Authentication + '/Logoff'
164159

165-
# URL Methods
166-
# -----------
167-
$URL_Safes = $URL_PVWAAPI + '/Safes'
168-
$URL_SafeDetails = $URL_Safes + '/{0}'
169-
$URL_SafeMembers = $URL_SafeDetails + '/Members'
170-
$URL_Accounts = $URL_PVWAAPI + '/Accounts'
171-
$URL_AccountsDetails = $URL_Accounts + '/{0}'
172-
$URL_AccountsPassword = $URL_AccountsDetails + '/Password/Update'
173-
$URL_PlatformDetails = $URL_PVWAAPI + '/Platforms/{0}'
174-
175-
# Script Defaults
176-
# ---------------
177-
$global:g_CsvDefaultPath = $Env:CSIDL_DEFAULT_DOWNLOADS
178-
179-
# Safe Defaults
180-
# --------------
181-
$NumberOfDaysRetention = 7
182-
#$NumberOfVersionsRetention = 0
183-
184-
# Template Safe parameters
185-
# ------------------------
186-
$TemplateSafeDetails = ''
187-
$TemplateSafeMembers = ''
160+
#region Helper Functions
161+
function Format-PVWAURL {
162+
param (
163+
[Parameter()]
164+
[string]
165+
$PVWAURL
166+
)
167+
#check url scheme to ensure it's secure and add https if not present
168+
IF ($PVWAURL -match '^(?<scheme>https:\/\/|http:\/\/|).*$') {
169+
if ('http://' -eq $matches['scheme'] -and $AllowInsecureURL -eq $false) {
170+
$PVWAURL = $PVWAURL.Replace('http://', 'https://')
171+
Write-LogMessage -type Warning -MSG "Detected inscure scheme in URL `nThe URL was automaticly updated to: $PVWAURL `nPlease ensure you are using the correct scheme in the url"
172+
}
173+
elseif ([string]::IsNullOrEmpty($matches['scheme'])) {
174+
$PVWAURL = "https://$PVWAURL"
175+
Write-LogMessage -type Warning -MSG "Detected no scheme in URL `nThe URL was automaticly updated to: $PVWAURL `nPlease ensure you are using the correct scheme in the url"
176+
}
177+
}
188178

189-
# Initialize Script Variables
190-
# ---------------------------
191-
$global:g_LogonHeader = ''
192-
$global:g_LogAccountName = ''
179+
#check url for improper Privilege Cloud URL and add /PasswordVault/ if not present
180+
if ($PVWAURL -match '^(?:https|http):\/\/(?<sub>.*).cyberark.(?<top>cloud|com)\/privilegecloud.*$') {
181+
$PVWAURL = "https://$($matches['sub']).privilegecloud.cyberark.$($matches['top'])/PasswordVault/"
182+
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"
183+
Start-Sleep 10
184+
}
185+
elseif ($PVWAURL -notmatch '^.*PasswordVault(?:\/|)$') {
186+
$PVWAURL = "$PVWAURL/PasswordVault/"
187+
Write-LogMessage -type Warning -MSG "Detected improperly formated Privileged Access Manager 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"
188+
Start-Sleep 10
189+
}
190+
return $PVWAURL
191+
}
193192

194-
#region Helper Functions
195193
# @FUNCTION@ ======================================================================================================================
196194
# Name...........: Test-CommandExists
197195
# Description....: Tests if a command exists
@@ -215,10 +213,10 @@ The command to test
215213
RETURN $true
216214
}
217215
}
218-
Catch {
216+
catch {
219217
Write-Host "$command does not exist"; RETURN $false
220218
}
221-
Finally {
219+
Finally {
222220
$ErrorActionPreference = $oldPreference
223221
}
224222
} #end function test-CommandExists
@@ -242,7 +240,7 @@ The text to encode
242240
Write-LogMessage -type Debug -MSG "Returning URL Encode of $sText"
243241
return [URI]::EscapeDataString($sText)
244242
}
245-
else {
243+
else {
246244
return $sText
247245
}
248246
}
@@ -270,10 +268,10 @@ The text to convert to bool (True / False)
270268
if ($txt -match '^y$|^yes$') {
271269
$retBool = $true
272270
}
273-
elseif ($txt -match '^n$|^no$') {
271+
elseif ($txt -match '^n$|^no$') {
274272
$retBool = $false
275273
}
276-
else {
274+
else {
277275
[bool]::TryParse($txt, [ref]$retBool) | Out-Null
278276
}
279277

@@ -298,7 +296,7 @@ The text to handle
298296
if ($null -ne $sText) {
299297
return $sText.Trim()
300298
}
301-
# Else
299+
#else
302300
return $sText
303301
}
304302

@@ -418,7 +416,7 @@ Creates a new Account Object
418416

419417
return $_Account
420418
}
421-
catch {
419+
catch {
422420
Throw $(New-Object System.Exception ('New-AccountObject: There was an error creating a new account object.', $_.Exception))
423421
}
424422
}
@@ -462,24 +460,24 @@ The Location to open the dialog in
462460
Function Write-LogMessage {
463461
<#
464462
.SYNOPSIS
465-
Method to log a message on screen and in a log file
463+
Method to log a message on screen and in a log file
466464
467465
.DESCRIPTION
468-
Logging The input Message to the Screen and the Log File.
469-
The Message Type is presented in colours on the screen based on the type
466+
Logging The input Message to the Screen and the Log File.
467+
The Message Type is presented in colours on the screen based on the type
470468
471469
.PARAMETER LogFile
472-
The Log File to write to. By default using the LOG_FILE_PATH
470+
The Log File to write to. By default using the LOG_FILE_PATH
473471
.PARAMETER MSG
474-
The message to log
472+
The message to log
475473
.PARAMETER Header
476-
Adding a header line before the message
474+
Adding a header line before the message
477475
.PARAMETER SubHeader
478-
Adding a Sub header line before the message
476+
Adding a Sub header line before the message
479477
.PARAMETER Footer
480-
Adding a footer line after the message
478+
Adding a footer line after the message
481479
.PARAMETER Type
482-
The type of the message to log (Info, Warning, Error, Debug)
480+
The type of the message to log (Info, Warning, Error, Debug)
483481
#>
484482
param(
485483
[Parameter(Mandatory = $true)]
@@ -753,7 +751,7 @@ The Header as Dictionary object
753751
Throw $PSItem.Exception
754752
}
755753
Else {
756-
Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tError in running $Command on '$URI', $($($Details.Details.ErrorMessage) -Join ";")"
754+
Write-LogMessage -type Verbose -MSG "Invoke-Rest:`tError in running $Command on '$URI', $($($Details.Details.ErrorMessage) -Join ';')"
757755
Write-LogMessage -type Verbose -MSG "Invoke-Rest:`t$($Details.Details.ErrorMessage)"
758756
Throw $($Details.Details.ErrorMessage)
759757
}
@@ -795,7 +793,7 @@ The Safe Name to return
795793
$accSafeURL = $URL_SafeDetails -f $(ConvertTo-URL $safeName)
796794
$_safe = $(Invoke-Rest -Uri $accSafeURL -Header $g_LogonHeader -Command 'Get' -ErrAction $ErrAction)
797795
}
798-
catch {
796+
catch {
799797
Write-LogMessage -type Error -MSG "Error getting Safe '$safeName' details. Error: $($($($_.ErrorDetails.Message) |ConvertFrom-Json).ErrorMessage)"
800798
}
801799

@@ -936,7 +934,7 @@ The Safe Name to return its Members
936934
$_retSafeOwners += $item
937935
}
938936
}
939-
catch {
937+
catch {
940938
Write-LogMessage -type Error -MSG "Error getting Safe '$safeName' members. Error: $(Join-ExceptionMessage $_.Exception)"
941939
}
942940

@@ -976,7 +974,7 @@ The Safe Name check if exists
976974
return $true
977975
}
978976
}
979-
catch {
977+
catch {
980978
Write-LogMessage -type Error -MSG "Error testing safe '$safeName' existence. Error: $(Join-ExceptionMessage $_.Exception)" -ErrorAction 'SilentlyContinue'
981979
}
982980
}
@@ -1018,7 +1016,7 @@ The Template Safe object (returned from the Get-Safe method). If entered the new
10181016
$templateSafeObject.SafeName = $safeName
10191017
$restBody = $templateSafeObject | ConvertTo-Json -Depth 3 -Compress
10201018
}
1021-
else {
1019+
else {
10221020
# Create the Target Safe
10231021
Write-LogMessage -type Info -MSG "Creating Safe $safeName"
10241022
$bodySafe = @{ SafeName = $safeName; Description = "$safeName - Created using Accounts Onboard Utility"; OLACEnabled = $false; ManagingCPM = $cpmName; NumberOfDaysRetention = $NumberOfDaysRetention }
@@ -1058,12 +1056,12 @@ Outputs the bad record to a CSV file for correction and processing
10581056
.DESCRIPTION
10591057
Outputs the bad record to a CSV file for correction and processing
10601058
#>
1061-
[CmdletBinding()]
1062-
param (
1063-
[Parameter()]
1064-
[string]
1065-
$ErrorMessage
1066-
)
1059+
[CmdletBinding()]
1060+
param (
1061+
[Parameter()]
1062+
[string]
1063+
$ErrorMessage
1064+
)
10671065
Try {
10681066

10691067
If ($null -ne $ErrorMessage) {
@@ -1124,7 +1122,7 @@ The Good record to output
11241122
Write-LogMessage -type Debug -MSG 'Outputted good record to CSV'
11251123
Write-LogMessage -type Verbose -MSG "Good Record:`t$global:workAccount"
11261124
}
1127-
catch {
1125+
catch {
11281126
Write-LogMessage -type Error -MSG "Unable to output good record to file: $csvPathGood"
11291127
Write-LogMessage -type Verbose -MSG "Good Record:`t$global:workAccount"
11301128

@@ -1280,7 +1278,7 @@ The Account Safe Name to search in
12801278
throw "Found $($_retAccount.count) accounts in search - fix duplications"
12811279
}
12821280
}
1283-
catch {
1281+
catch {
12841282
Throw $(New-Object System.Exception ('Get-Account: Error getting Account.', $_.Exception))
12851283
}
12861284

@@ -1332,7 +1330,7 @@ The Account Safe Name to search in
13321330
return $true
13331331
}
13341332
}
1335-
catch {
1333+
catch {
13361334
Write-LogMessage -type Error -MSG "Error testing Account '$g_LogAccountName' existence. Error: $(Join-ExceptionMessage $_.Exception)" -ErrorAction 'SilentlyContinue'
13371335
}
13381336
}
@@ -1377,7 +1375,7 @@ The property to check in the platform
13771375
Throw 'Platform does not exist or we had an issue'
13781376
}
13791377
}
1380-
catch {
1378+
catch {
13811379
Write-LogMessage -type Error -MSG "Error checking platform properties. Error: $(Join-ExceptionMessage $_.Exception)"
13821380
}
13831381

@@ -1412,7 +1410,7 @@ The REST API Credentials to authenticate
14121410
If ($concurrentSession) {
14131411
$logonBody = @{ username = $Credentials.username.Replace('\', ''); password = $Credentials.GetNetworkCredential().password; concurrentSession = 'true' } | ConvertTo-Json -Compress
14141412
}
1415-
else {
1413+
else {
14161414
$logonBody = @{ username = $Credentials.username.Replace('\', ''); password = $Credentials.GetNetworkCredential().password } | ConvertTo-Json -Compress
14171415
}
14181416
If (![string]::IsNullOrEmpty($RadiusOTP)) {
@@ -1425,7 +1423,7 @@ The REST API Credentials to authenticate
14251423
# Clear logon body
14261424
$logonBody = ''
14271425
}
1428-
catch {
1426+
catch {
14291427
Throw $(New-Object System.Exception ("Get-LogonHeader: $($_.Exception.Response.StatusDescription)", $_.Exception))
14301428
}
14311429

@@ -1467,7 +1465,7 @@ Tests if the script is running the latest version
14671465
try {
14681466
$getScriptContent = (Invoke-WebRequest -UseBasicParsing -Uri $scriptURL).Content
14691467
}
1470-
catch {
1468+
catch {
14711469
Throw $(New-Object System.Exception ("Test-LatestVersion: Couldn't download and check for latest version", $_.Exception))
14721470
}
14731471
If ($($getScriptContent -match 'ScriptVersion\s{0,1}=\s{0,1}\"([\d\.]{1,5})\"')) {
@@ -1497,6 +1495,44 @@ Tests if the script is running the latest version
14971495

14981496
#endregion
14991497

1498+
1499+
# Global URLS
1500+
# -----------
1501+
$URL_PVWAURL = Format-PVWAURL($PVWAURL)
1502+
$URL_PVWAAPI = $URL_PVWAURL + '/api'
1503+
$URL_Authentication = $URL_PVWAAPI + '/auth'
1504+
$URL_Logon = $URL_Authentication + "/$AuthType/Logon"
1505+
$URL_Logoff = $URL_Authentication + '/Logoff'
1506+
1507+
# URL Methods
1508+
# -----------
1509+
$URL_Safes = $URL_PVWAAPI + '/Safes'
1510+
$URL_SafeDetails = $URL_Safes + '/{0}'
1511+
$URL_SafeMembers = $URL_SafeDetails + '/Members'
1512+
$URL_Accounts = $URL_PVWAAPI + '/Accounts'
1513+
$URL_AccountsDetails = $URL_Accounts + '/{0}'
1514+
$URL_AccountsPassword = $URL_AccountsDetails + '/Password/Update'
1515+
$URL_PlatformDetails = $URL_PVWAAPI + '/Platforms/{0}'
1516+
1517+
# Script Defaults
1518+
# ---------------
1519+
$global:g_CsvDefaultPath = $Env:CSIDL_DEFAULT_DOWNLOADS
1520+
1521+
# Safe Defaults
1522+
# --------------
1523+
$NumberOfDaysRetention = 7
1524+
#$NumberOfVersionsRetention = 0
1525+
1526+
# Template Safe parameters
1527+
# ------------------------
1528+
$TemplateSafeDetails = ''
1529+
$TemplateSafeMembers = ''
1530+
1531+
# Initialize Script Variables
1532+
# ---------------------------
1533+
$global:g_LogonHeader = ''
1534+
$global:g_LogAccountName = ''
1535+
15001536
# Write the entire script command when running in Verbose mode
15011537
Write-LogMessage -type Verbose -MSG "Base:`t$g_ScriptCommand"
15021538
# Header
@@ -1514,7 +1550,7 @@ If ($DisableSSLVerify) {
15141550
# Disable SSL Verification
15151551
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $DisableSSLVerify }
15161552
}
1517-
catch {
1553+
catch {
15181554
Write-LogMessage -type Error -MSG 'Could not change SSL validation'
15191555
Write-LogMessage -type Error -MSG (Join-ExceptionMessage $_.Exception) -ErrorAction 'SilentlyContinue'
15201556
return
@@ -1525,7 +1561,7 @@ Else {
15251561
Write-LogMessage -type Debug -MSG 'Setting script to use TLS 1.2'
15261562
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
15271563
}
1528-
catch {
1564+
catch {
15291565
Write-LogMessage -type Error -MSG 'Could not change SSL settings to use TLS 1.2'
15301566
Write-LogMessage -type Error -MSG (Join-ExceptionMessage $_.Exception) -ErrorAction 'SilentlyContinue'
15311567
}
@@ -1663,7 +1699,7 @@ $csvPathBad = "$csvPath.bad.csv"
16631699
Remove-Item $csvPathBad -Force -ErrorAction SilentlyContinue
16641700

16651701
$accountsCSV = Import-Csv $csvPath -Delimiter $delimiter
1666-
$accountsCSV = $accountsCSV |Select-Object -ExcludeProperty ErrorMessage
1702+
$accountsCSV = $accountsCSV | Select-Object -ExcludeProperty ErrorMessage
16671703
$rowCount = $($accountsCSV.Safe.Count)
16681704
$counter = 0
16691705

0 commit comments

Comments
 (0)