Created
April 23, 2024 13:25
-
-
Save luke-z/59f077fd958d859ce9230578ce45d1c2 to your computer and use it in GitHub Desktop.
Password Secure Code Snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Write-Host -ForegroundColor Yellow "This CLI tool does not work with MFA authentication." | |
Write-Host -ForegroundColor Yellow "Please make sure you're using PowerShell 7.4+" | |
Do { | |
$version = Read-Host "Enter the PWS version (8 or 9)" | |
if (!$version -or ($version -ne '8' -and $version -ne '9')) { | |
Write-Error "Please enter a valid API URL." | |
} | |
} while (!$version -or ($version -ne '8' -and $version -ne '9')) | |
# Load the DLL | |
if ($version -eq '8') { | |
try { | |
Add-Type -Path "dll_v8\PsrApi.dll" | |
} catch { | |
Write-Host -ForegroundColor Red "You have previously used the CLI tool with PWS v9 in this Powershell instance. Please open a new Powershell instance to use it with PWS v8." | |
exit | |
} | |
Write-Host -ForegroundColor Blue "Using PWS v8" | |
} | |
else { | |
try { | |
Add-Type -Path "dll_v9\PsrApi.dll" | |
} catch { | |
Write-Host -ForegroundColor Red "You have previously used the CLI tool with PWS v8 in this Powershell instance. Please open a new Powershell instance to use it with PWS v9." | |
exit | |
} | |
Write-Host -ForegroundColor Blue "Using PWS v9" | |
} | |
# Create the API object | |
Do { | |
$apiUrl = Read-Host "Enter the API URL, without the protocol (e.g. pwswebclienturl.ch/api)" | |
if (!$apiUrl) { | |
Write-Error "Please enter a valid API URL." | |
} | |
} while (!$apiUrl) | |
$psrApi = New-Object PsrApi.PsrApi($apiUrl.Trim()) | |
# Get login credentials | |
Do { | |
$db = Read-Host "Enter the database name" | |
if (!$db) { | |
Write-Error "Please enter a database name" | |
} | |
} while (!$db) | |
Do { | |
$username = Read-Host "Enter the username" | |
if (!$username) { | |
Write-Error "Please enter a username" | |
} | |
} while (!$username) | |
Do { | |
$password = Read-Host -MaskInput "Enter the password" | |
if (!$password) { | |
Write-Error "Please enter a password" | |
} | |
} while (!$password) | |
# Login for PWS v8 | |
if ($version -eq '8') { | |
$loginTask = $psrApi.AuthenticationManager.Login($db.Trim(), $username.Trim(), $password.Trim()) | |
try { | |
$loginTask.Wait() | |
} | |
catch { | |
Write-Error "Login failed. Please check the credentials and try again." | |
return | |
} | |
} | |
# Login for PWS v9 | |
else { | |
$authenticationFlow = $psrApi.AuthenticationManagerV2.StartNewAuthentication($db.Trim(), $username.Trim()) | |
$startLoginTask = $authenticationFlow.StartLogin() | |
$startLoginTask.Wait() | |
$requirement = $authenticationFlow.GetNextRequirement() | |
$selectedRequirement = $requirement.PossibleRequirements[0] | |
foreach ($field in $selectedRequirement.Fields) { | |
$field.Value = $password.Trim() | |
} | |
$authenticateTask = $authenticationFlow.Authenticate($selectedRequirement) | |
try { | |
$authenticateTask.Wait() | |
} | |
catch { | |
Write-Error "Login failed. Please check the credentials and try again." | |
return | |
} | |
} | |
# Get the container list | |
$defaultContainerFilter = New-Object PsrApi.Data.PsrContainerListFilter | |
# Get all forms | |
$findFormsTask = $psrApi.ContainerManager.GetContainerList([PsrApi.Data.Enums.PsrContainerType]::Form, $defaultContainerFilter) | |
$findFormsTask.Wait() | |
Do { | |
$formName = Read-Host "Enter the form name" | |
if (!$formName) { | |
Write-Error "Please enter a valid form name" | |
} | |
} while (!$formName) | |
# Find the form by name | |
$filteredForm = $findFormsTask.Result.Where({ $_.Name -eq $formName.Trim() }) | |
if ($filteredForm.Count -eq 0) { | |
Write-Error "No forms with the name '$formName' found." | |
return | |
} | |
$formId = $filteredForm.Id | |
# Get all Password containers based on the form | |
$findPasswordTask = $psrApi.ContainerManager.GetContainerList([PsrApi.Data.Enums.PsrContainerType]::Password, $defaultContainerFilter) | |
$findPasswordTask.Wait() | |
$containersBasedOnForm = $findPasswordTask.Result.Where({ $_.BaseContainerId -eq $formId }) | |
if ($containersBasedOnForm.Count -eq 0) { | |
Write-Error "No containers found for the form '$formName'." | |
return | |
} | |
# Get the old and new password field names | |
Do { | |
$oldField = Read-Host "Enter the name of the OLD password field" | |
if (!$oldField) { | |
Write-Error "Please enter an old field name" | |
} | |
} while (!$oldField) | |
Do { | |
$newField = Read-Host "Enter the name of the NEW password field" | |
if (!$newField) { | |
Write-Error "Please enter a new field name" | |
} | |
} while (!$newField) | |
$formFieldsExist = $true | |
$containerMissingFields = '' | |
# Check if the form fields exist | |
foreach ($container in $containersBasedOnForm) { | |
# Check if both "Password" and "Password (old)" are present in the Items | |
$passwordPresent = $false | |
$passwordOldPresent = $false | |
$passwordDescription = '' | |
foreach ($item in $container.Items) { | |
if ($item.Name -eq $newField.Trim()) { | |
$passwordPresent = $true | |
} | |
if ($item.Name -eq $oldField.Trim()) { | |
$passwordOldPresent = $true | |
} | |
if ($item.Name -eq "Description") { | |
$passwordDescription = $item.Value | |
} | |
} | |
if (-not $passwordPresent -or -not $passwordOldPresent) { | |
$formFieldsExist = $false | |
$containerMissingFields = $passwordDescription | |
break | |
} | |
} | |
# If the form fields don't exist, return an error | |
if (!$formFieldsExist) { | |
Write-Error "The following container is missing the required form fields: $containerMissingFields" | |
return | |
} | |
$progressTracker = [hashtable]::Synchronized(@{}) | |
# Update the passwords | |
$containersBasedOnForm | ForEach-Object -ThrottleLimit 10 -Parallel { | |
# Get the old password value | |
$passwordOldItem = $_.Items | Where-Object { $_.Name -eq $($using:oldField).Trim() } | |
$passwordOldValue = $passwordOldItem.Value | |
# Set the PlainTextValue of the new password field to the old password value | |
$passwordItem = $_.Items | Where-Object { $_.Name -eq $($using:newField).Trim() } | |
if ($null -ne $passwordItem -and $null -ne $passwordOldItem) { | |
$passwordItem.PlainTextValue = $passwordOldValue | |
} | |
# Update the container | |
$updateTask = $($using:psrApi).ContainerManager.UpdateContainer($_) | |
$updateTask.Wait() | |
$($using:progressTracker)[$_.Id] = $true | |
# Update the progress | |
$completed = $($using:progressTracker).Keys.Count | |
$percentComplete = ($completed / $($using:containersBasedOnForm).Count) * 100 | |
Write-Progress -Activity "Updating Container Passwords" -Status "$completed of $($($using:containersBasedOnForm).Count) Completed" -PercentComplete $percentComplete | |
} | |
# Logout | |
if ($version -eq '8') { | |
$logoutTask = $psrApi.AuthenticationManager.Logout() | |
$logoutTask.Wait() | |
} else { | |
$logoutTask = $psrApi.AuthenticationManagerV2.Logout() | |
$logoutTask.Wait() | |
} | |
Write-Host -ForegroundColor Green "The script successfully processed $($containersBasedOnForm.Count) Password container(s)" | |
Read-Host -Prompt "Press any key to close" | Out-Null | |
exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment