Functions/Accounts/Add-PASAccount.ps1

function Add-PASAccount {
    <#
.SYNOPSIS
Adds a new privileged account to the Vault
Uses either the API present from 10.4 onwards, or the version 9 API endpoint.

.DESCRIPTION
Adds a new privileged account to the Vault.
Parameters are processed to create request object from passed parameters in the required format.

.PARAMETER name
The name of the account.
A version 10.4 onward specific parameter

.PARAMETER secretType
The type of password.
A version 10.4 onward specific parameter

.PARAMETER secret
The password value
A version 10.4 onward specific parameter

.PARAMETER platformAccountProperties
key-value pairs to associate with the account, as defined by the account platform.
These properties are validated against the mandatory and optional properties of the specified platform's definition.
A version 10.4 onward specific parameter

.PARAMETER automaticManagementEnabled
Whether CPM Password Management should be enabled
A version 10.4 onward specific parameter

.PARAMETER manualManagementReason
A reason for disabling CPM Password Management
A version 10.4 onward specific parameter

.PARAMETER remoteMachines
For supported platforms, a list of remote machines the account can connect to.
A version 10.4 onward specific parameter

.PARAMETER accessRestrictedToRemoteMachines
Whether access is restricted to the defined remote machines.
A version 10.4 onward specific parameter

.PARAMETER SafeName
The safe where the account will be created

.PARAMETER PlatformID
The CyberArk platform to assign to the account

.PARAMETER Address
The Address of the machine where the account will be used

.PARAMETER AccountName
The name of the account
Relevant for CyberArk versions earlier than 10.4

.PARAMETER Password
The password value as a secure string
Relevant for CyberArk versions earlier than 10.4

.PARAMETER Username
Username on the target machine

.PARAMETER DisableAutoMgmt
Whether or not automatic management wll be disabled for the account
Relevant for CyberArk versions earlier than 10.4

.PARAMETER DisableAutoMgmtReason
The reason why automatic management wll be disabled for the account
Relevant for CyberArk versions earlier than 10.4

.PARAMETER GroupName
A groupname with which the account will be associated
Relevant for CyberArk versions earlier than 10.4

.PARAMETER GroupPlatformID
Group platform to base created group ID on, if ID doesn't exist
Relevant for CyberArk versions earlier than 10.4

.PARAMETER Port
Port number over which the account will be used
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass1Name
Logon account name
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass1Folder
Folder where logon account is stored
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass1Safe
Safe where logon account is stored
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass3Name
Reconcile account name
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass3Folder
Folder where reconcile account is stored
Relevant for CyberArk versions earlier than 10.4

.PARAMETER ExtraPass3Safe
Safe where reconcile account is stored
Relevant for CyberArk versions earlier than 10.4

.PARAMETER DynamicProperties
Hashtable of name=value pairs
Relevant for CyberArk versions earlier than 10.4

.EXAMPLE
Add-PASAccount -address ThisServer -userName ThisUser -platformID UNIXSSH -SafeName UNIXSafe -automaticManagementEnabled $false

Using the version 10 API, adds an account which is disabled for automatic password management

.EXAMPLE
Add-PASAccount -safe Prod_Access -PlatformID WINDOMAIN -Address domain.com -Password $secureString -username domainUser

Using the "version 9" API, adds account domain.com\domainuser to the Prod_Access Safe using the WINDOMAIN platform.
The contents of $secureString will be set as the password value.

.INPUTS
All parameters can be piped by property name

.OUTPUTS
None for v9
v10.4 outputs the details of the created account.

.LINK
https://pspas.pspete.dev/commands/Add-PASAccount
#>

    [CmdletBinding()]
    param(

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [string]$name,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [string]$address,

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [string]$userName,

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [Alias("PolicyID")]
        [string]$platformID,

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [ValidateNotNullOrEmpty()]
        [Alias("safe")]
        [string]$SafeName,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [ValidateSet("Password", "Key")]
        [string]$secretType,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [securestring]$secret,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [hashtable]$platformAccountProperties,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [boolean]$automaticManagementEnabled,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [string]$manualManagementReason,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [string]$remoteMachines,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V10"
        )]
        [boolean]$accessRestrictedToRemoteMachines,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$accountName,

        [parameter(
            Mandatory = $true,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [securestring]$password,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [boolean]$disableAutoMgmt,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$disableAutoMgmtReason,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$groupName,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$groupPlatformID,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [int]$Port,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [ValidateNotNullOrEmpty()]
        [string]$ExtraPass1Name,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$ExtraPass1Folder,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [ValidateNotNullOrEmpty()]
        [string]$ExtraPass1Safe,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [ValidateNotNullOrEmpty()]
        [string]$ExtraPass3Name,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [string]$ExtraPass3Folder,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [ValidateNotNullOrEmpty()]
        [string]$ExtraPass3Safe,

        [parameter(
            Mandatory = $false,
            ValueFromPipelinebyPropertyName = $true,
            ParameterSetName = "V9"
        )]
        [hashtable]$DynamicProperties
    )

    BEGIN {

        #The (version 9 API) Add Account JSON object requires specific formatting.
        #Different parameters are contained within the JSON at different depths.
        #Programmatic processing is required to format the JSON as required.

        #V9 baseparameters are contained in JSON object at the same depth
        $baseParameters = @("Safe", "PlatformID", "Address", "AccountName", "Password", "Username",
            "DisableAutoMgmt", "DisableAutoMgmtReason", "GroupName", "GroupPlatformID")

        #V10 parameters are nested under JSON object properties
        $remoteMachine = @("remoteMachines", "accessRestrictedToRemoteMachines")
        $SecretMgmt = @("automaticManagementEnabled", "manualManagementReason")

    }#begin

    PROCESS {

        #Get all parameters that will be sent in the request
        $boundParameters = $PSBoundParameters | Get-PASParameter

        switch ($PSCmdlet.ParameterSetName) {

            "V10" {

                Assert-VersionRequirement -RequiredVersion 10.4

                #Create URL for Request
                $URI = "$Script:BaseURI/api/Accounts"

                #deal with "secret" SecureString
                If ($PSBoundParameters.ContainsKey("secret")) {

                    #Include decoded password in request
                    $boundParameters["secret"] = $(ConvertTo-InsecureString -SecureString $secret)

                }

                $remoteMachinesAccess = @{ }
                $boundParameters.keys | Where-Object { $remoteMachine -contains $_ } | ForEach-Object {

                    #add key=value to hashtable
                    $remoteMachinesAccess[$_] = $boundParameters[$_]


                }

                $secretManagement = @{ }
                $boundParameters.keys | Where-Object { $SecretMgmt -contains $_ } | ForEach-Object {

                    #add key=value to hashtable
                    $secretManagement[$_] = $boundParameters[$_]

                }

                $boundParameters["remoteMachinesAccess"] = $remoteMachinesAccess
                $boundParameters["secretManagement"] = $secretManagement

                $body = $boundParameters |
                Get-PASParameter -ParametersToRemove @($remoteMachine + $SecretMgmt) |
                ConvertTo-Json -depth 4

                break

            }

            "V9" {

                #Create URL for Request
                $URI = "$Script:BaseURI/WebServices/PIMServices.svc/Account"

                #deal with Password SecureString
                If ($PSBoundParameters.ContainsKey("password")) {

                    #Include decoded password in request
                    $boundParameters["password"] = $(ConvertTo-InsecureString -SecureString $password)

                }

                #Process for required formatting - fix V10 specific parameter names
                $boundParameters.remove("SafeName")
                $boundParameters.remove("userName")
                $boundParameters["safe"] = $SafeName
                $boundParameters["username"] = $userName

                #declare empty hashtable to hold "non-base" parameters
                $properties = @{ }

                #declare empty array to hold keys to remove from bound parameters
                [array]$keysToRemove = @()

                #Get "non-base" parameters
                $boundParameters.keys | Where-Object { $baseParameters -notcontains $_ } | ForEach-Object {

                    #For all "non-base" parameters except "DynamicProperties"
                    if ($_ -ne "DynamicProperties") {

                        #Add key/Value to "properties" hashtable
                        $properties[$_] = $boundParameters[$_]

                    }

                    Else {
                        #for DynamicProperties key=value pairs

                        #Enumerate DynamicProperties object
                        $boundParameters[$_].getenumerator() | ForEach-Object {

                            #add key=value to "properties" hashtable
                            $properties[$_.name] = $_.value

                        }
                    }

                    #add the "non-base" parameter key to array
                    $keysToRemove = $keysToRemove + $_

                }

                #Add "non-base" parameter hashtable as value of "properties" on boundparameters object
                $boundParameters["properties"] = @($properties.getenumerator() | ForEach-Object { $_ })

                #Create body of request
                $body = @{

                    #account node does not contain non-base parameters
                    "account" = $boundParameters | Get-PASParameter -ParametersToRemove $keysToRemove

                    #ensure nodes at all required depths are included in the JSON object
                } | ConvertTo-Json -Depth 4

                break

            }

        }

        #send request to PAS web service
        $result = Invoke-PASRestMethod -Uri $URI -Method POST -Body $Body -WebSession $Script:WebSession

        if ($PSCmdlet.ParameterSetName -eq "V10") {

            If ($null -ne $result) {

                #Return Results
                $result | Add-ObjectDetail -typename "psPAS.CyberArk.Vault.Account.V10"

            }

        }

    }#process

    END { }#end
}