profiles.psm1

# Helpers
function Resolve-SafeguardProfileItemId
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition = $null,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true)]
        [ValidateSet("PasswordRule", "CheckSchedule", "ChangeSchedule", "Profile", IgnoreCase=$true)]
        [string]$ItemType,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$Item
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    switch ($ItemType)
    {
        "passwordrule" { $local:ResourceName = "PasswordRules"; $local:ErrorResource = "account password rule"; break}
        "checkschedule" { $local:ResourceName = "CheckSchedules"; $local:ErrorResource = "password check schedule"; break }
        "changeschedule" { $local:ResourceName = "ChangeSchedules"; $local:ErrorResource = "password change schedule"; break }
        "profile" { $local:ResourceName = "Profiles"; $local:ErrorResource = "password profile"; break }
    }

    if ($Item.Id -as [int])
    {
        $Item = $Item.Id
    }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                             -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId)
    if ($AssetPartitionId)
    {
        $local:RelPath = "AssetPartitions/$AssetPartitionId/$($local:ResourceName)"
        $local:ErrMsgSuffix = " in asset partition (Id=$AssetPartitionId)"
    }
    else
    {
        $local:RelPath = "AssetPartitions/$($local:ResourceName)"
        $local:ErrMsgSuffix = ""
    }

    if (-not ($Item -as [int]))
    {
        try
        {
            $local:ItemList = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core GET "$($local:RelPath)" `
                                   -Parameters @{ filter = "Name ieq '$Item'"; fields = "Id" })
        }
        catch
        {
            Write-Verbose $_
            Write-Verbose "Caught exception with ieq filter, trying with q parameter"
            $local:ItemList = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core GET "$($local:RelPath)" `
                                   -Parameters @{ q = $Item; fields = "Id" })
        }
        if (-not $local:ItemList)
        {
            throw "Unable to find $($local:ErrorResource) matching '$Item'$($local:ErrMsgSuffix)"
        }
        if ($local:ItemList.Count -ne 1)
        {
            throw "Found $($local:ItemList.Count) $($local:ErrorResource)s matching '$Item'$($local:ErrMsgSuffix)"
        }
        $local:ItemList[0].Id
    }
    else
    {
        if ($AssetPartitionId)
        {
            # Make sure it actually exists
            $local:ItemList = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core GET "$($local:RelPath)" `
                                   -Parameters @{ filter = "Id eq $Item and AssetPartitionId eq $AssetPartitionId"; fields = "Id" })
            if (-not $local:ItemList)
            {
                throw "Unable to find $($local:ErrorResource) matching '$Item'$($local:ErrMsgSuffix)"
            }
        }
        $Item
    }
}
function Resolve-SafeguardAccountPasswordRuleId
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition = $null,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$AccountPasswordRule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Resolve-SafeguardProfileItemId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartition -ItemType "PasswordRule" -Item $AccountPasswordRule
}
function Resolve-SafeguardPasswordCheckScheduleId
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition = $null,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordCheckSchedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Resolve-SafeguardProfileItemId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartition -ItemType "CheckSchedule" -Item $PasswordCheckSchedule
}
function Resolve-SafeguardPasswordChangeScheduleId
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition = $null,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordChangeSchedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Resolve-SafeguardProfileItemId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartition -ItemType "ChangeSchedule" -Item $PasswordChangeSchedule
}
function Resolve-SafeguardPasswordProfileId
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition = $null,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordProfile
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Resolve-SafeguardProfileItemId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartition -ItemType "Profile" -Item $PasswordProfile
}
function Get-SafeguardProfileItem
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true)]
        [ValidateSet("PasswordRule", "CheckSchedule", "ChangeSchedule", "Profile", IgnoreCase=$true)]
        [string]$ItemType,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$ItemToGet,
        [Parameter(Mandatory=$false)]
        [string[]]$Fields
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    switch ($ItemType)
    {
        "passwordrule" { $local:ResourceName = "PasswordRules"; break}
        "checkschedule" { $local:ResourceName = "CheckSchedules"; break }
        "changeschedule" { $local:ResourceName = "ChangeSchedules"; break }
        "profile" { $local:ResourceName = "Profiles"; break }
    }

    $local:Parameters = $null
    if ($Fields)
    {
        $local:Parameters = @{ fields = ($Fields -join ",")}
    }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId)

    if ($AssetPartitionId)
    {
        $local:RelPath = "AssetPartitions/$AssetPartitionId/$($local:ResourceName)"
    }
    else
    {
        $local:RelPath = "AssetPartitions/$($local:ResourceName)"
    }

    if ($ItemToGet)
    {
        $local:ItemId = (Resolve-SafeguardProfileItemId -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
                                -AssetPartitionId $AssetPartitionId -ItemType $ItemType $ItemToGet)
        Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
            Core GET "$($local:RelPath)/$($local:ItemId)" -Parameters $local:Parameters
    }
    else
    {
        Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
            Core GET "$($local:RelPath)" -Parameters $local:Parameters
    }
}
function Remove-SafeguardProfileItem
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true)]
        [ValidateSet("PasswordRule", "CheckSchedule", "ChangeSchedule", "Profile", IgnoreCase=$true)]
        [string]$ItemType,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ItemToDelete
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    switch ($ItemType)
    {
        "passwordrule" { $local:ResourceName = "PasswordRules"; break}
        "checkschedule" { $local:ResourceName = "CheckSchedules"; break }
        "changeschedule" { $local:ResourceName = "ChangeSchedules"; break }
        "profile" { $local:ResourceName = "Profiles"; break }
    }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:RelPath = "AssetPartitions/$AssetPartitionId/$($local:ResourceName)"

    $local:ItemId = (Resolve-SafeguardProfileItemId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                       -AssetPartitionId $AssetPartitionId -ItemType $ItemType -Item $ItemToDelete)

    Invoke-SafeguardMethod -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure Core DELETE "$($local:RelPath)/$($local:ItemId)"
}
function Rename-SafeguardProfileItem
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true)]
        [ValidateSet("PasswordRule", "CheckSchedule", "ChangeSchedule", "Profile", IgnoreCase=$true)]
        [string]$ItemType,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ItemToEdit,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$NewName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    switch ($ItemType)
    {
        "passwordrule" { $local:ResourceName = "PasswordRules"; break}
        "checkschedule" { $local:ResourceName = "CheckSchedules"; break }
        "changeschedule" { $local:ResourceName = "ChangeSchedules"; break }
        "profile" { $local:ResourceName = "Profiles"; break }
    }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:RelPath = "AssetPartitions/$AssetPartitionId/$($local:ResourceName)"

    $local:Item = (Get-SafeguardProfileItem -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                       -AssetPartitionId $AssetPartitionId -ItemType $ItemType -ItemToGet $ItemToEdit)

    $local:Item.Name = $NewName

    Invoke-SafeguardMethod -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure Core PUT "$($local:RelPath)/$($local:Item.Id)" -Body $local:Item
}
function Copy-SafeguardProfileItem
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true)]
        [ValidateSet("PasswordRule", "CheckSchedule", "ChangeSchedule", "Profile", IgnoreCase=$true)]
        [string]$ItemType,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ItemToCopy,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$CopyName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    switch ($ItemType)
    {
        "passwordrule" { $local:ResourceName = "PasswordRules"; break}
        "checkschedule" { $local:ResourceName = "CheckSchedules"; break }
        "changeschedule" { $local:ResourceName = "ChangeSchedules"; break }
        "profile" { $local:ResourceName = "Profiles"; break }
    }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:RelPath = "AssetPartitions/$AssetPartitionId/$($local:ResourceName)"

    $local:Item = (Get-SafeguardProfileItem -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                       -AssetPartitionId $AssetPartitionId -ItemType $ItemType -ItemToGet $ItemToCopy)

    $local:Item.Id = 0 # <== gets ignored for POST
    $local:Item.Name = $CopyName

    Invoke-SafeguardMethod -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure Core POST "$($local:RelPath)" -Body $local:Item
}


# account password rules

<#
.SYNOPSIS
Get account password rules in Safeguard via the Web API.
 
.DESCRIPTION
Get one or all account password rules that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to get account password rules from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to get account password rules from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER PasswordRuleToGet
An integer containing the ID of the account password rule to get or a string containing the name.
 
.PARAMETER Fields
An array of the account password rule property names to return.
#>

function Get-SafeguardAccountPasswordRule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$PasswordRuleToGet = $null,
        [Parameter(Mandatory=$false)]
        [string[]]$Fields = $null
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Get-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "PasswordRule" -ItemToGet $PasswordRuleToGet -Fields $Fields
}

<#
.SYNOPSIS
Create a new account password rule in Safeguard via the Web API.
 
.DESCRIPTION
Create a new account password rule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to create the account password rule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to create the account password rule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER Name
A string containing the name of the new account password rule.
 
.PARAMETER Description
A string containing the description of the new account password rule.
 
.PARAMETER MinCharacters
An integer of the minimum number of characters (default: 8)
 
.PARAMETER MaxCharacters
An integer of the maximum number of characters (default: 12)
 
.PARAMETER AllowUppercase
A boolean of whether or not to allow uppercase characters (default: true)
 
.PARAMETER MinUppercase
An integer of the minimum number of uppercase characters (default: 1)
 
.PARAMETER MaxConsecutiveUppercase
An integer of the maximum number of consecutive uppercase characters (default: not set)
 
.PARAMETER InvalidUppercase
A string containing all of the invalid uppercase characters (default: not set)
Example: "ATXYZ", meaning none of those characters will show up in passwords
 
.PARAMETER AllowLowercase
A boolean of whether or not to allow lowercase characters (default: true)
 
.PARAMETER MinLowercase
An integer of the minimum number of lowercase characters (default: 1)
 
.PARAMETER MaxConsecutiveLowercase
An integer of the maximum number of consecutive lowercase characters (default: not set)
 
.PARAMETER InvalidLowercaseChars
A string containing all of the invalid lowercase characters (default: not set)
Example: "aefbkdjs", meaning none of those characters will show up in passwords
 
.PARAMETER AllowNumeric
A boolean of whether or not to allow numeric characters (default: true)
 
.PARAMETER MinNumeric
An integer of the minimum number of numeric characters (default: 1)
 
.PARAMETER MaxConsecutiveNumeric
An integer of the maximum number of consecutive numeric characters (default: not set)
 
.PARAMETER InvalidNumericChars
A string containing all of the invalid numeric characters (default: not set)
Example: "12590", meaning none of those characters will show up in passwords
 
.PARAMETER AllowSymbols
A boolean of whether or not to allow symbol characters (default: false)
 
.PARAMETER MinSymbols
An integer of the minimum number of symbol characters (default: 0)
 
.PARAMETER MaxConsecutiveSymbols
An integer of the maximum number of consecutive symbol characters (default: not set)
 
.PARAMETER InvalidSymbolChars
A string containing all of the invalid symbol characters (default: not set)
Example: "%^=,", meaning none of those characters will show up in passwords
This parameter is mutually exclusive with AllowedSymbolChars
 
.PARAMETER AllowedSymbolChars
A string containing all of the symbol characters to allow (default: not set)
Example: "@#$%&", meaning only those characters will be used as symbols in passwords
 
.PARAMETER AllowedFirstCharType
A string containing which type of character to start the password with (default: not set)
 
.PARAMETER AllowedLastCharType
A string containing which type of character to end the password with (default: not set)
 
.PARAMETER MaxConsecutiveAlpha
An integer of the maximum number of consecutive alphabetic characters (default: not set)
 
.PARAMETER MaxConsecutiveAlphanumeric
An integer of the maximum number of consecutive alphanumeric characters (default: not set)
 
.PARAMETER RepeatedCharRestriction
A string containing the repeated character restriction setting for new passwords (default: "NoConsecutiveRepeatedCharacters")
#>

function New-SafeguardAccountPasswordRule
{
    [CmdletBinding(DefaultParameterSetName="Exclude")]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [string]$Name,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [int]$MinCharacters = 8,
        [Parameter(Mandatory=$false)]
        [int]$MaxCharacters = 12,
        [Parameter(Mandatory=$false)]
        [bool]$AllowUppercase = $true,
        [Parameter(Mandatory=$false)]
        [int]$MinUppercase = 1,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveUppercase = $null,
        [Parameter(Mandatory=$false)]
        [string[]]$InvalidUppercaseChars = $null,
        [Parameter(Mandatory=$false)]
        [bool]$AllowLowercase = $true,
        [Parameter(Mandatory=$false)]
        [int]$MinLowercase = 1,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveLowercase = $null,
        [Parameter(Mandatory=$false)]
        [string]$InvalidLowercaseChars = $null,
        [Parameter(Mandatory=$false)]
        [bool]$AllowNumeric = $true,
        [Parameter(Mandatory=$false)]
        [int]$MinNumeric = 1,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveNumeric = $null,
        [Parameter(Mandatory=$false)]
        [string]$InvalidNumericChars = $null,
        [Parameter(Mandatory=$false)]
        [bool]$AllowSymbols = $false,
        [Parameter(Mandatory=$false)]
        [int]$MinSymbols = 0,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveSymbols = $null,
        [Parameter(Mandatory=$false,ParameterSetName="Exclude")]
        [string]$InvalidSymbolChars = $null,
        [Parameter(Mandatory=$false,ParameterSetName="Include")]
        [string]$AllowedSymbolChars = $null,
        [Parameter(Mandatory=$false)]
        [ValidateSet("All", "AlphaNumeric", "Alphabetic", IgnoreCase=$true)]
        [string]$AllowedFirstCharType = $null,
        [Parameter(Mandatory=$false)]
        [ValidateSet("All", "AlphaNumeric", "Alphabetic", IgnoreCase=$true)]
        [string]$AllowedLastCharType = $null,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveAlpha = $null,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveAlphanumeric = $null,
        [Parameter(Mandatory=$false)]
        [ValidateSet("NotSpecified", "NoConsecutiveRepeatedCharacters", "NoRepeatedCharacters", "AllowRepeatedCharacters", IgnoreCase=$true)]
        [string]$RepeatedCharRestriction = "NoConsecutiveRepeatedCharacters"
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:Body = @{
        "Name" = $Name;
        "Description" = $Description;
        "MinCharacters" = $MinCharacters;
        "MaxCharacters" = $MaxCharacters;
        "AllowUppercaseCharacters" = $AllowUppercase;
        "MinUppercaseCharacters" = $MinUppercase;
        "AllowLowercaseCharacters" = $AllowLowercase;
        "MinLowercaseCharacters" = $MinLowercase;
        "AllowNumericCharacters" = $AllowNumeric;
        "MinNumericCharacters" = $MinNumeric;
        "AllowNonAlphaNumericCharacters" = $AllowSymbols;
        "MinNonAlphaNumericCharacters" = $MinSymbols;
        "RepeatedCharacterRestriction" = $RepeatedCharRestriction;
    }

    if ($MaxConsecutiveUppercase) { $local:Body.MaxConsecutiveUppercaseCharacters = $MaxConsecutiveUppercase }
    if ($InvalidUppercaseChars) { $local:Body.InvalidUppercaseCharacters = $InvalidUppercaseChars }

    if ($MaxConsecutiveLowercase) { $local:Body.MaxConsecutiveLowercaseCharacters = $MaxConsecutiveLowercase }
    if ($InvalidLowercaseChars) { $local:Body.InvalidLowercaseCharacters = [string[]]($InvalidLowercaseChars -split "(?<=.)(?=.)") }

    if ($MaxConsecutiveNumeric) { $local:Body.MaxConsecutiveNumericCharacters = $MaxConsecutiveNumeric }
    if ($InvalidNumericChars) { $local:Body.InvalidNumericCharacters = [string[]]($InvalidNumericChars -split "(?<=.)(?=.)") }

    if ($MaxConsecutiveSymbols) { $local:Body.MaxConsecutiveNonAlphaNumericCharacters = $MaxConsecutiveSymbols }
    if ($SymbolRestrictionType) { $local:Body.NonAlphaNumericRestrictionType = $SymbolRestrictionType }
    if ($InvalidSymbolChars)
    {
        $local:Body.InvalidNonAlphaNumericCharacters = [string[]]($InvalidSymbolChars -split "(?<=.)(?=.)")
        $local:Body.NonAlphaNumericRestrictionType = "Exclude"
    }
    if ($AllowedSymbolChars)
    {
        $local:Body.AllowedNonAlphaNumericCharacters = [string[]]($AllowedSymbolChars -split "(?<=.)(?=.)")
        $local:Body.NonAlphaNumericRestrictionType = "Include"
    }

    if ($AllowedFirstCharType) { $local:Body.AllowedFirstCharacterType = $AllowedFirstCharType }
    if ($AllowedLastCharType) { $local:Body.AllowedLastCharacterType = $AllowedLastCharType }

    if ($MaxConsecutiveAlpha) { $local:Body.MaxConsecutiveAlphabeticCharacters = $MaxConsecutiveAlpha }
    if ($MaxConsecutiveAlphanumeric) { $local:Body.MaxConsecutiveAlphaNumericCharacters = $MaxConsecutiveAlpha }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        POST "AssetPartitions/$($local:AssetPartitionId)/PasswordRules" -Body $local:Body
}

<#
.SYNOPSIS
Edit an existing account password rule in Safeguard via the Web API.
 
.DESCRIPTION
Edit an existing account password rule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to create the account password rule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to create the account password rule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER PasswordRuleToEdit
An integer containing the ID of the account password rule to get or a string containing the name.
 
.PARAMETER Description
A string containing the description of the account password rule.
 
.PARAMETER MinCharacters
An integer of the minimum number of characters (default: 8)
 
.PARAMETER MaxCharacters
An integer of the maximum number of characters (default: 12)
 
.PARAMETER AllowUppercase
A boolean of whether or not to allow uppercase characters (default: true)
 
.PARAMETER MinUppercase
An integer of the minimum number of uppercase characters (default: 1)
 
.PARAMETER MaxConsecutiveUppercase
An integer of the maximum number of consecutive uppercase characters (default: not set)
 
.PARAMETER InvalidUppercase
A string containing all of the invalid uppercase characters (default: not set)
Example: "ATXYZ", meaning none of those characters will show up in passwords
 
.PARAMETER AllowLowercase
A boolean of whether or not to allow lowercase characters (default: true)
 
.PARAMETER MinLowercase
An integer of the minimum number of lowercase characters (default: 1)
 
.PARAMETER MaxConsecutiveLowercase
An integer of the maximum number of consecutive lowercase characters (default: not set)
 
.PARAMETER InvalidLowercaseChars
A string containing all of the invalid lowercase characters (default: not set)
Example: "aefbkdjs", meaning none of those characters will show up in passwords
 
.PARAMETER AllowNumeric
A boolean of whether or not to allow numeric characters (default: true)
 
.PARAMETER MinNumeric
An integer of the minimum number of numeric characters (default: 1)
 
.PARAMETER MaxConsecutiveNumeric
An integer of the maximum number of consecutive numeric characters (default: not set)
 
.PARAMETER InvalidNumericChars
A string containing all of the invalid numeric characters (default: not set)
Example: "12590", meaning none of those characters will show up in passwords
 
.PARAMETER AllowSymbols
A boolean of whether or not to allow symbol characters (default: false)
 
.PARAMETER MinSymbols
An integer of the minimum number of symbol characters (default: 0)
 
.PARAMETER MaxConsecutiveSymbols
An integer of the maximum number of consecutive symbol characters (default: not set)
 
.PARAMETER InvalidSymbolChars
A string containing all of the invalid symbol characters (default: not set)
Example: "%^=,", meaning none of those characters will show up in passwords
This parameter is mutually exclusive with AllowedSymbolChars
 
.PARAMETER AllowedSymbolChars
A string containing all of the symbol characters to allow (default: not set)
Example: "@#$%&", meaning only those characters will be used as symbols in passwords
 
.PARAMETER AllowedFirstCharType
A string containing which type of character to start the password with (default: not set)
 
.PARAMETER AllowedLastCharType
A string containing which type of character to end the password with (default: not set)
 
.PARAMETER MaxConsecutiveAlpha
An integer of the maximum number of consecutive alphabetic characters (default: not set)
 
.PARAMETER MaxConsecutiveAlphanumeric
An integer of the maximum number of consecutive alphanumeric characters (default: not set)
 
.PARAMETER RepeatedCharRestriction
A string containing the repeated character restriction setting for new passwords (default: "NoConsecutiveRepeatedCharacters")
#>

function Edit-SafeguardAccountPasswordRule
{
    [CmdletBinding(DefaultParameterSetName="Exclude")]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordRuleToEdit,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [int]$MinCharacters,
        [Parameter(Mandatory=$false)]
        [int]$MaxCharacters,
        [Parameter(Mandatory=$false)]
        [bool]$AllowUppercase,
        [Parameter(Mandatory=$false)]
        [int]$MinUppercase,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveUppercase,
        [Parameter(Mandatory=$false)]
        [string[]]$InvalidUppercaseChars,
        [Parameter(Mandatory=$false)]
        [bool]$AllowLowercase,
        [Parameter(Mandatory=$false)]
        [int]$MinLowercase,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveLowercase,
        [Parameter(Mandatory=$false)]
        [string]$InvalidLowercaseChars,
        [Parameter(Mandatory=$false)]
        [bool]$AllowNumeric,
        [Parameter(Mandatory=$false)]
        [int]$MinNumeric,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveNumeric,
        [Parameter(Mandatory=$false)]
        [string]$InvalidNumericChars,
        [Parameter(Mandatory=$false)]
        [bool]$AllowSymbols,
        [Parameter(Mandatory=$false)]
        [int]$MinSymbols,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveSymbols,
        [Parameter(Mandatory=$false,ParameterSetName="Exclude")]
        [string]$InvalidSymbolChars,
        [Parameter(Mandatory=$false,ParameterSetName="Include")]
        [string]$AllowedSymbolChars,
        [Parameter(Mandatory=$false)]
        [ValidateSet("All", "AlphaNumeric", "Alphabetic", IgnoreCase=$true)]
        [string]$AllowedFirstCharType,
        [Parameter(Mandatory=$false)]
        [ValidateSet("All", "AlphaNumeric", "Alphabetic", IgnoreCase=$true)]
        [string]$AllowedLastCharType,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveAlpha,
        [Parameter(Mandatory=$false)]
        [int]$MaxConsecutiveAlphanumeric,
        [Parameter(Mandatory=$false)]
        [ValidateSet("NotSpecified", "NoConsecutiveRepeatedCharacters", "NoRepeatedCharacters", "AllowRepeatedCharacters", IgnoreCase=$true)]
        [string]$RepeatedCharRestriction
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    $local:RuleObj = (Get-SafeguardAccountPasswordRule -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                          -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId $PasswordRuleToEdit)

    if ($PSBoundParameters.ContainsKey("Description")) { $local:RuleObj.Description = $Description }
    if ($PSBoundParameters.ContainsKey("MinCharacters")) { $local:RuleObj.MinCharacters = $MinCharacters }
    if ($PSBoundParameters.ContainsKey("MaxCharacters")) { $local:RuleObj.MaxCharacters = $MaxCharacters }
    if ($PSBoundParameters.ContainsKey("AllowUppercase")) { $local:RuleObj.AllowUppercaseCharacters = $AllowUppercase }
    if ($PSBoundParameters.ContainsKey("MinUppercase")) { $local:RuleObj.MinUppercaseCharacters = $MinUppercase }
    if ($PSBoundParameters.ContainsKey("AllowLowercase")) { $local:RuleObj.AllowLowercaseCharacters = $AllowLowercase }
    if ($PSBoundParameters.ContainsKey("MinLowercase")) { $local:RuleObj.MinLowercaseCharacters = $MinLowercase }
    if ($PSBoundParameters.ContainsKey("AllowNumeric")) { $local:RuleObj.AllowNumericCharacters = $AllowNumeric }
    if ($PSBoundParameters.ContainsKey("MinNumeric")) { $local:RuleObj.MaxConsecutiveUppercaseCharacters = $MinNumeric }
    if ($PSBoundParameters.ContainsKey("AllowSymbols")) { $local:RuleObj.AllowNonAlphaNumericCharacters = $AllowSymbols }
    if ($PSBoundParameters.ContainsKey("MinSymbols")) { $local:RuleObj.MinNonAlphaNumericCharacters = $MinSymbols }
    if ($PSBoundParameters.ContainsKey("RepeatedCharRestriction")) { $local:RuleObj.RepeatedCharacterRestriction = $RepeatedCharRestriction }

    if ($PSBoundParameters.ContainsKey("MaxConsecutiveUppercase")) { $local:RuleObj.MaxConsecutiveUppercaseCharacters = $MaxConsecutiveUppercase }
    if ($PSBoundParameters.ContainsKey("InvalidUppercaseChars")) { $local:RuleObj.InvalidUppercaseCharacters = $InvalidUppercaseChars }

    if ($PSBoundParameters.ContainsKey("MaxConsecutiveLowercase")) { $local:RuleObj.MaxConsecutiveLowercaseCharacters = $MaxConsecutiveLowercase }
    if ($PSBoundParameters.ContainsKey("InvalidLowercaseChars")) { $local:RuleObj.InvalidLowercaseCharacters = [string[]]($InvalidLowercaseChars -split "(?<=.)(?=.)") }

    if ($PSBoundParameters.ContainsKey("MaxConsecutiveNumeric")) { $local:RuleObj.MaxConsecutiveNumericCharacters = $MaxConsecutiveNumeric }
    if ($PSBoundParameters.ContainsKey("InvalidNumericChars")) { $local:RuleObj.InvalidNumericCharacters = [string[]]($InvalidNumericChars -split "(?<=.)(?=.)") }

    if ($PSBoundParameters.ContainsKey("MaxConsecutiveSymbols")) { $local:RuleObj.MaxConsecutiveNonAlphaNumericCharacters = $MaxConsecutiveSymbols }
    if ($PSBoundParameters.ContainsKey("SymbolRestrictionType")) { $local:RuleObj.NonAlphaNumericRestrictionType = $SymbolRestrictionType }
    if ($PSBoundParameters.ContainsKey("InvalidSymbolChars"))
    {
        $local:RuleObj.InvalidNonAlphaNumericCharacters = [string[]]($InvalidSymbolChars -split "(?<=.)(?=.)")
        $local:RuleObj.NonAlphaNumericRestrictionType = "Exclude"
    }
    if ($PSBoundParameters.ContainsKey("AllowedSymbolChars"))
    {
        $local:RuleObj.AllowedNonAlphaNumericCharacters = [string[]]($AllowedSymbolChars -split "(?<=.)(?=.)")
        $local:RuleObj.NonAlphaNumericRestrictionType = "Include"
    }

    if ($PSBoundParameters.ContainsKey("AllowedFirstCharType")) { $local:RuleObj.AllowedFirstCharacterType = $AllowedFirstCharType }
    if ($PSBoundParameters.ContainsKey("AllowedLastCharType")) { $local:RuleObj.AllowedLastCharacterType = $AllowedLastCharType }

    if ($PSBoundParameters.ContainsKey("MaxConsecutiveAlpha")) { $local:RuleObj.MaxConsecutiveAlphabeticCharacters = $MaxConsecutiveAlpha }
    if ($PSBoundParameters.ContainsKey("MaxConsecutiveAlphanumeric")) { $local:RuleObj.MaxConsecutiveAlphaNumericCharacters = $MaxConsecutiveAlpha }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        PUT "AssetPartitions/$($local:RuleObj.AssetPartitionId)/PasswordRules/$($local:RuleObj.Id)" -Body $local:RuleObj
}

<#
.SYNOPSIS
Delete an account password rule from Safeguard via the Web API.
 
.DESCRIPTION
Delete an account password rule. It must not be associated with a password profile
in order to be able to delete it.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to delete the account password rule from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to delete the account password rule from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER PasswordRuleToDelete
An integer containing the ID of the account password rule to delete or a string containing the name.
#>

function Remove-SafeguardAccountPasswordRule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordRuleToDelete
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Remove-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "PasswordRule" -ItemToDelete $PasswordRuleToDelete
}

<#
.SYNOPSIS
Rename an account password rule in Safeguard via the Web API.
 
.DESCRIPTION
Rename an account password rule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to rename the account password rule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to rename the account password rule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER PasswordRuleToEdit
An integer containing the ID of the account password rule to rename or a string containing the name.
 
.PARAMETER NewName
A string containing the new name for the account password rule.
#>

function Rename-SafeguardAccountPasswordRule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordRuleToEdit,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$NewName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Rename-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "PasswordRule" -ItemToEdit $PasswordRuleToEdit -NewName $NewName
}

<#
.SYNOPSIS
Copy an account password rule in Safeguard via the Web API.
 
.DESCRIPTION
Copy an account password rule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to copy the account password rule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to copy the account password rule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER PasswordRuleToCopy
An integer containing the ID of the account password rule to copy or a string containing the name.
 
.PARAMETER CopyName
A string containing the name for the new account password rule.
#>

function Copy-SafeguardAccountPasswordRule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$PasswordRuleToCopy,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$CopyName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Copy-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "PasswordRule" -ItemToCopy $PasswordRuleToCopy -CopyName $CopyName
}

# password check schedules

<#
.SYNOPSIS
Get password check schedules in Safeguard via the Web API.
 
.DESCRIPTION
Get one or all password check schedules that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to get password check schedules from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to get password check schedules.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER CheckScheduleToGet
An integer containing the ID of the password check schedule to get or a string containing the name.
 
.PARAMETER Fields
An array of the password check schedule property names to return.
#>

function Get-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$CheckScheduleToGet,
        [Parameter(Mandatory=$false)]
        [string[]]$Fields
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Get-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "CheckSchedule" -ItemToGet $CheckScheduleToGet -Fields $Fields
}

<#
.SYNOPSIS
Create a new password check schedule in Safeguard via the Web API.
 
.DESCRIPTION
Create a new password check schedule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to create the password check schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to create the password check schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER Name
A string containing the name of the new password check schedule.
 
.PARAMETER Description
A string containing the description of the new password check schedule.
 
.PARAMETER ChangePasswordOnMismatch
Whether to change the password if a password mismatch is found (does not apply to manual check tasks).
 
.PARAMETER NotifyOwnersOnMismatch
Whether to notify delegated owners if a password mismatch is found (does not apply to manual check tasks).
 
.PARAMETER Schedule
A Safeguard schedule object of when to run password checks, see New-SafeguardSchedule and associated cmdlets.
 
.EXAMPLE
New-SafeguardPasswordCheckSchedule "Daily Check at Noon" -ChangePasswordOnMismatch -Schedule (New-SafeguardScheduleDaily -StartTime "12:00")
#>

function New-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [string]$Name,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordOnMismatch,
        [Parameter(Mandatory=$false)]
        [switch]$NotifyOwnersOnMismatch,
        [Parameter(Mandatory=$false)]
        [HashTable]$Schedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:Body = @{
        "Name" = $Name;
        "Description" = $Description;
        "ResetPasswordOnMismatch" = [bool]$ChangePasswordOnMismatch;
        "NotifyOwnersOnMismatch" = [bool]$NotifyOwnersOnMismatch;
    }

    if ($Schedule)
    {
        Import-Module -Name "$PSScriptRoot\schedules.psm1" -Scope Local
        $local:Body = (Copy-ScheduleToDto -Schedule $Schedule -Dto $local:Body)
    }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        POST "AssetPartitions/$($local:AssetPartitionId)/CheckSchedules" -Body $local:Body
}

<#
.SYNOPSIS
Edit an existing password check schedule in Safeguard via the Web API.
 
.DESCRIPTION
Edit an existing password check schedule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to edit the password check schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to edit the password check schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER CheckScheduleToEdit
An integer containing the ID of the password check schedule to edit or a string containing the name.
 
.PARAMETER Description
A string containing the description for the password check schedule.
 
.PARAMETER ChangePasswordOnMismatch
Whether to change the password if a password mismatch is found (does not apply to manual check tasks).
 
.PARAMETER NotifyOwnersOnMismatch
Whether to notify delegated owners if a password mismatch is found (does not apply to manual check tasks).
 
.PARAMETER Schedule
A Safeguard schedule object of when to run password checks, see New-SafeguardSchedule and associated cmdlets.
 
.EXAMPLE
Edit-SafeguardPasswordCheckSchedule "Daily Check at Noon" -ChangePasswordOnMismatch -Schedule (New-SafeguardScheduleDaily -StartTime "12:00")
#>

function Edit-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$CheckScheduleToEdit,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordOnMismatch,
        [Parameter(Mandatory=$false)]
        [switch]$NotifyOwnersOnMismatch,
        [Parameter(Mandatory=$false)]
        [HashTable]$Schedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    $local:CheckObj = (Get-SafeguardPasswordCheckSchedule -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                           -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId $CheckScheduleToEdit)

    if ($PSBoundParameters.ContainsKey("Description")) { $local:CheckObj.Description = $Description }
    if ($PSBoundParameters.ContainsKey("ChangePasswordOnMismatch")) { $local:CheckObj.ResetPasswordOnMismatch = [bool]$ChangePasswordOnMismatch }
    if ($PSBoundParameters.ContainsKey("NotifyOwnersOnMismatch")) { $local:CheckObj.NotifyOwnersOnMismatch = [bool]$NotifyOwnersOnMismatch }
    if ($PSBoundParameters.ContainsKey("Schedule"))
    {
        Import-Module -Name "$PSScriptRoot\schedules.psm1" -Scope Local
        $local:CheckObj = (Copy-ScheduleToDto -Schedule $Schedule -Dto $local:CheckObj)
    }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        PUT "AssetPartitions/$($local:CheckObj.AssetPartitionId)/CheckSchedules/$($local:CheckObj.Id)" -Body $local:CheckObj
}

<#
.SYNOPSIS
Delete a password check schedule from Safeguard via the Web API.
 
.DESCRIPTION
Delete a password check schedule. It must not be associated with a password profile
in order to be able to delete it.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to delete the password check schedule from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to the delete password check schedule from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER CheckScheduleToDelete
An integer containing the ID of the password check schedule to delete or a string containing the name.
#>

function Remove-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$CheckScheduleToDelete
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Remove-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "CheckSchedule" -ItemToDelete $CheckScheduleToDelete
}

<#
.SYNOPSIS
Rename a password check schedule in Safeguard via the Web API.
 
.DESCRIPTION
Rename a password check schedule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to rename the password check schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to rename the password check schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER CheckScheduleToEdit
An integer containing the ID of the password check schedule to rename or a string containing the name.
 
.PARAMETER NewName
A string containing the new name for the password check schedule.
#>

function Rename-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$CheckScheduleToEdit,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$NewName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Rename-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "CheckSchedule" -ItemToEdit $CheckScheduleToEdit -NewName $NewName
}

<#
.SYNOPSIS
Copy a password check schedule in Safeguard via the Web API.
 
.DESCRIPTION
Copy a password check schedule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to copy the password check schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to copy the password check schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER CheckScheduleToEdit
An integer containing the ID of the password check schedule to copy or a string containing the name.
 
.PARAMETER CopyName
A string containing the name for the new password check schedule.
#>

function Copy-SafeguardPasswordCheckSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$CheckScheduleToCopy,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$CopyName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Copy-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "CheckSchedule" -ItemToCopy $CheckScheduleToCopy -CopyName $CopyName
}

# password change schedules

<#
.SYNOPSIS
Get password change schedules in Safeguard via the Web API.
 
.DESCRIPTION
Get one or all password change schedules that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to get password change schedules from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to get password change schedules.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ChangeScheduleToGet
An integer containing the ID of the password change schedule to get or a string containing the name.
 
.PARAMETER Fields
An array of the password change schedule property names to return.
#>

function Get-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$ChangeScheduleToGet,
        [Parameter(Mandatory=$false)]
        [string[]]$Fields
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Get-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "ChangeSchedule" -ItemToGet $ChangeScheduleToGet -Fields $Fields
}

<#
.SYNOPSIS
Create a new password change schedule in Safeguard via the Web API.
 
.DESCRIPTION
Create a new password change schedule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to create the password change schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to create the password change schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER Name
A string containing the name of the new password change schedule.
 
.PARAMETER Description
A string containing the description of the new password change schedule.
 
.PARAMETER ChangePasswordIfInUse
Whether or not to change the password even if it is currently checked out.
 
.PARAMETER RequireCurrentPassword
Whether to require the current password to change to a new password.
 
.PARAMETER SuspendAccountWhenCheckedIn
Whether to disable the account when password is not checked out. (limited platform support)
 
.PARAMETER ChangePasswordsManually
Whether or not to require asset administrators to change passwords manually.
 
.PARAMETER UpdateServices
Whether or not to update Windows services when passwords are changed.
 
.PARAMETER RestartServices
Whether or not to restart Windows services when passwords are changed.
 
.PARAMETER UpdateIisAppPools
Whether or not to update Windows IIS app pools when passwords are changed.
 
.PARAMETER UpdateComPlus
Whether or not to update Windows COM+ services when passwords are changed.
 
.PARAMETER UpdateTasks
Whether or not to update Windows tasks when passwords are changed.
 
.PARAMETER Schedule
A Safeguard schedule object of when to run password changes, see New-SafeguardSchedule and associated cmdlets.
 
.EXAMPLE
New-SafeguardPasswordChangeSchedule "Daily Change at Noon" -Schedule (New-SafeguardScheduleDaily -StartTime "12:00")
 
.EXAMPLE
New-SafeguardPasswordChangeSchedule "Windows Daily at 7pm" -Description "Changes passwords and restarts services" -Schedule (New-SafeguardScheduleDaily -StartTime "19:00") -ChangePasswordIfInUse -UpdateServices -RestartServices -UpdateTasks
#>

function New-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [string]$Name,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordIfInUse,
        [Parameter(Mandatory=$false)]
        [switch]$RequireCurrentPassword,
        [Parameter(Mandatory=$false)]
        [switch]$SuspendAccountWhenCheckedIn,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordsManually,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateServices,
        [Parameter(Mandatory=$false)]
        [switch]$RestartServices,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateIisAppPools,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateComPlus,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateTasks,
        [Parameter(Mandatory=$false)]
        [HashTable]$Schedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:Body = @{
        "Name" = $Name;
        "Description" = $Description;
        "AllowPasswordChangeWhenReleased" = [bool]$ChangePasswordIfInUse;
        "RequireCurrentPassword" = [bool]$RequireCurrentPassword;
        "SuspendAccountWhenCheckedIn" = [bool]$SuspendAccountWhenCheckedIn;
        "NotifyOwnersOnly" = [bool]$ChangePasswordsManually;
        # Windows service stuff
        "UpdateWindowsServiceOnPasswordChange" = [bool]$UpdateServices;
        "RestartWindowsServiceOnPasswordChange" = [bool]$RestartServices;
        "UpdateIisPoolsOnPasswordChange" = [bool]$UpdateIisAppPools;
        "UpdateComPlusOnPasswordChange" = [bool]$UpdateComPlus;
        "UpdateWindowsTasksOnPasswordChange" = [bool]$UpdateTasks;
        # backwards compat for prior to SSH key management
        "ManagePassword" = $true;
    }

    if ($Schedule)
    {
        Import-Module -Name "$PSScriptRoot\schedules.psm1" -Scope Local
        $local:Body = (Copy-ScheduleToDto -Schedule $Schedule -Dto $local:Body)
    }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        POST "AssetPartitions/$($local:AssetPartitionId)/ChangeSchedules" -Body $local:Body
}

<#
.SYNOPSIS
Edit an existing password change schedule in Safeguard via the Web API.
 
.DESCRIPTION
Edit an existing password change schedule that can be associated to a password profile
which can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to edit the password change schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to edit the password change schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ChangeScheduleToEdit
An integer containing the ID of the password change schedule to edit or a string containing the name.
 
.PARAMETER Description
A string containing the description for the password change schedule.
 
.PARAMETER ChangePasswordIfInUse
Whether or not to change the password even if it is currently checked out.
 
.PARAMETER RequireCurrentPassword
Whether to require the current password to change to a new password.
 
.PARAMETER SuspendAccountWhenCheckedIn
Whether to disable the account when password is not checked out. (limited platform support)
 
.PARAMETER ChangePasswordsManually
Whether or not to require asset administrators to change passwords manually.
 
.PARAMETER UpdateServices
Whether or not to update Windows services when passwords are changed.
 
.PARAMETER RestartServices
Whether or not to restart Windows services when passwords are changed.
 
.PARAMETER UpdateIisAppPools
Whether or not to update Windows IIS app pools when passwords are changed.
 
.PARAMETER UpdateComPlus
Whether or not to update Windows COM+ services when passwords are changed.
 
.PARAMETER UpdateTasks
Whether or not to update Windows tasks when passwords are changed.
 
.PARAMETER Schedule
A Safeguard schedule object of when to run password changes, see New-SafeguardSchedule and associated cmdlets.
 
.EXAMPLE
Edit-SafeguardPasswordChangeSchedule "Daily Change at Noon" -Schedule (New-SafeguardScheduleDaily -StartTime "12:00") -ChangePasswordsManually
 
.EXAMPLE
Edit-SafeguardPasswordChangeSchedule "Windows Daily at 7pm" -Schedule (New-SafeguardScheduleDaily -StartTime "19:00") -ChangePasswordIfInUse -UpdateServices -RestartServices -UpdateTasks
#>

function Edit-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$ChangeScheduleToEdit,
        [Parameter(Mandatory=$false)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordIfInUse,
        [Parameter(Mandatory=$false)]
        [switch]$RequireCurrentPassword,
        [Parameter(Mandatory=$false)]
        [switch]$SuspendAccountWhenCheckedIn,
        [Parameter(Mandatory=$false)]
        [switch]$ChangePasswordsManually,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateServices,
        [Parameter(Mandatory=$false)]
        [switch]$RestartServices,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateIisAppPools,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateComPlus,
        [Parameter(Mandatory=$false)]
        [switch]$UpdateTasks,
        [Parameter(Mandatory=$false)]
        [HashTable]$Schedule
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    $local:ChangeObj = (Get-SafeguardPasswordChangeSchedule -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId $ChangeScheduleToEdit)

    if ($PSBoundParameters.ContainsKey("Description")) { $local:ChangeObj.Description = $Description }
    if ($PSBoundParameters.ContainsKey("ChangePasswordIfInUse")) { $local:ChangeObj.AllowPasswordChangeWhenReleased = [bool]$ChangePasswordIfInUse }
    if ($PSBoundParameters.ContainsKey("RequireCurrentPassword")) { $local:ChangeObj.RequireCurrentPassword = [bool]$RequireCurrentPassword }
    if ($PSBoundParameters.ContainsKey("SuspendAccountWhenCheckedIn")) { $local:ChangeObj.SuspendAccountWhenCheckedIn = [bool]$SuspendAccountWhenCheckedIn }
    if ($PSBoundParameters.ContainsKey("ChangePasswordsManually")) { $local:ChangeObj.NotifyOwnersOnly = [bool]$ChangePasswordsManually }

    if ($PSBoundParameters.ContainsKey("UpdateServices")) { $local:ChangeObj.UpdateWindowsServiceOnPasswordChange = [bool]$UpdateServices }
    if ($PSBoundParameters.ContainsKey("RestartServices")) { $local:ChangeObj.RestartWindowsServiceOnPasswordChange = [bool]$RestartServices }
    if ($PSBoundParameters.ContainsKey("UpdateIisAppPools")) { $local:ChangeObj.UpdateIisPoolsOnPasswordChange = [bool]$UpdateIisAppPools }
    if ($PSBoundParameters.ContainsKey("UpdateComPlus")) { $local:ChangeObj.UpdateComPlusOnPasswordChange = [bool]$UpdateComPlus }
    if ($PSBoundParameters.ContainsKey("UpdateTasks")) { $local:ChangeObj.UpdateWindowsTasksOnPasswordChange = [bool]$UpdateTasks }

    if ($PSBoundParameters.ContainsKey("Schedule"))
    {
        Import-Module -Name "$PSScriptRoot\schedules.psm1" -Scope Local
        $local:ChangeObj = (Copy-ScheduleToDto -Schedule $Schedule -Dto $local:ChangeObj)
    }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        PUT "AssetPartitions/$($local:ChangeObj.AssetPartitionId)/ChangeSchedules/$($local:ChangeObj.Id)" -Body $local:ChangeObj
}

<#
.SYNOPSIS
Delete a password change schedule from Safeguard via the Web API.
 
.DESCRIPTION
Delete a password change schedule. It must not be associated with a password profile
in order to be able to delete it.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to delete the password change schedule from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to the delete password change schedule from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ChangeScheduleToDelete
An integer containing the ID of the password change schedule to delete or a string containing the name.
#>

function Remove-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ChangeScheduleToDelete
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Remove-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "ChangeSchedule" -ItemToDelete $ChangeScheduleToDelete
}

<#
.SYNOPSIS
Rename a password change schedule in Safeguard via the Web API.
 
.DESCRIPTION
Rename a password change schedule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to rename the password change schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to rename the password change schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ChangeScheduleToEdit
An integer containing the ID of the password change schedule to rename or a string containing the name.
 
.PARAMETER NewName
A string containing the new name for the password change schedule.
#>

function Rename-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ChangeScheduleToEdit,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$NewName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Rename-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "ChangeSchedule" -ItemToEdit $ChangeScheduleToEdit -NewName $NewName
}
<#
.SYNOPSIS
Copy a password change schedule in Safeguard via the Web API.
 
.DESCRIPTION
Copy a password change schedule without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to copy the password change schedule in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to copy the password change schedule in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ChangeScheduleToEdit
An integer containing the ID of the password change schedule to copy or a string containing the name.
 
.PARAMETER CopyName
A string containing the name for the new password change schedule.
#>

function Copy-SafeguardPasswordChangeSchedule
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ChangeScheduleToCopy,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$CopyName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Copy-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "ChangeSchedule" -ItemToCopy $ChangeScheduleToCopy -CopyName $CopyName
}

# password profiles

<#
.SYNOPSIS
Get password profiles in Safeguard via the Web API.
 
.DESCRIPTION
Get one or all password profiles that can be assigned to partitions, assets, and accounts.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to get password profiles from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to get password profiles.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ProfileToGet
An integer containing the ID of the password profiles to get or a string containing the name.
 
.PARAMETER Fields
An array of the password profile property names to return.
#>

function Get-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$false,Position=0)]
        [object]$ProfileToGet,
        [Parameter(Mandatory=$false)]
        [string[]]$Fields
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Get-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "Profile" -ItemToGet $ProfileToGet -Fields $Fields
}

<#
.SYNOPSIS
Create a new password profile in Safeguard via the Web API.
 
.DESCRIPTION
Create a new password profile. You must have already created the password rule,
check schedule, and change schedule so they can be set in the new password
profile.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to create the password profile in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to the create password profile in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER Name
A string containing the name for the new profile.
 
.PARAMETER Description
A string containing a description for the new profile.
 
.PARAMETER PasswordRuleToSet
An integer containing the ID of the account password rule to set in the new profile
or a string containing the name.
 
.PARAMETER CheckScheduleToSet
An integer containing the ID of the password check schedule to set in the new profile
or a string containing the name.
 
.PARAMETER ChangeScheduleToSet
An integer containing the ID of the password change schedule to set in the new profile
or a string containing the name.
#>

function New-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [string]$Name,
        [Parameter(Mandatory=$false,Position=1)]
        [string]$Description,
        [Parameter(Mandatory=$true)]
        [object]$PasswordRuleToSet,
        [Parameter(Mandatory=$true)]
        [object]$CheckScheduleToSet,
        [Parameter(Mandatory=$true)]
        [object]$ChangeScheduleToSet
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local
    $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                            -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault)

    $local:Body = @{
        "Name" = $Name;
        "Description" = $Description
    }

    $local:Body.AccountPasswordRuleId = (Resolve-SafeguardAccountPasswordRuleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                             -AssetPartitionId $AssetPartitionId -AccountPasswordRule $PasswordRuleToSet)
    $local:Body.CheckScheduleId  = (Resolve-SafeguardPasswordCheckScheduleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                        -AssetPartitionId $AssetPartitionId -PasswordCheckSchedule $CheckScheduleToSet)
    $local:Body.ChangeScheduleId = (Resolve-SafeguardPasswordChangeScheduleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                        -AssetPartitionId $AssetPartitionId -PasswordChangeSchedule $ChangeScheduleToSet)

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        POST "AssetPartitions/$($local:AssetPartitionId)/Profiles" -Body $local:Body
}

<#
.SYNOPSIS
Edit an existing password profile in Safeguard via the Web API.
 
.DESCRIPTION
Edit an existing password profile to change which password rule, check schedule,
or change schedule it is using.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to delete the password profile from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to the delete password profile from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ProfileToEdit
An integer containing the ID of the password profile to edit or a string containing the name.
 
.PARAMETER Description
A string containing a description for the new profile.
 
.PARAMETER PasswordRuleToSet
An integer containing the ID of the account password rule to set in the profile
or a string containing the name.
 
.PARAMETER CheckScheduleToSet
An integer containing the ID of the password check schedule to set in the profile
or a string containing the name.
 
.PARAMETER ChangeScheduleToSet
An integer containing the ID of the password change schedule to set in the profile
or a string containing the name.
#>

function Edit-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ProfileToEdit,
        [Parameter(Mandatory=$false,Position=1)]
        [string]$Description,
        [Parameter(Mandatory=$false)]
        [object]$PasswordRuleToSet,
        [Parameter(Mandatory=$false)]
        [object]$CheckScheduleToSet,
        [Parameter(Mandatory=$false)]
        [object]$ChangeScheduleToSet
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    $local:ProfileObj = (Get-SafeguardPasswordProfile -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                             -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId $ProfileToEdit)

    if ($PSBoundParameters.ContainsKey("Description")) { $local:ProfileObj.Description = $Description }

    if ($PSBoundParameters.ContainsKey("PasswordRuleToSet"))
    {
        $local:ProfileObj.AccountPasswordRuleId = (Resolve-SafeguardAccountPasswordRuleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                                       -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -AccountPasswordRule $PasswordRuleToSet)
    }
    if ($PSBoundParameters.ContainsKey("CheckScheduleToSet"))
    {
        $local:ProfileObj.CheckScheduleId  = (Resolve-SafeguardPasswordCheckScheduleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                                  -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -PasswordCheckSchedule $CheckScheduleToSet)
    }
    if ($PSBoundParameters.ContainsKey("ChangeScheduleToSet"))
    {
        $local:ProfileObj.ChangeScheduleId = (Resolve-SafeguardPasswordChangeScheduleId -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure `
                                                  -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -PasswordChangeSchedule $ChangeScheduleToSet)
    }

    Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core `
        PUT "AssetPartitions/$($local:ProfileObj.AssetPartitionId)/Profiles/$($local:ProfileObj.Id)" -Body $local:ProfileObj
}

<#
.SYNOPSIS
Delete a password profile from Safeguard via the Web API.
 
.DESCRIPTION
Delete a password profile. It must not the default password profile of an asset partition
in order to be able to delete it.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to delete the password profile from.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to the delete password profile from.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ProfileToDelete
An integer containing the ID of the password profile to delete or a string containing the name.
#>

function Remove-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ProfileToDelete
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Remove-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure `
        -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -ItemType "Profile" -ItemToDelete $ProfileToDelete
}

<#
.SYNOPSIS
Rename a password profile in Safeguard via the Web API.
 
.DESCRIPTION
Rename a password profile without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to rename the password profile in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to rename the password profile in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ProfileToEdit
An integer containing the ID of the password profile to rename or a string containing the name.
 
.PARAMETER NewName
A string containing the new name for the password profile.
#>

function Rename-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ProfileToEdit,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$NewName
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    Rename-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
        -AssetPartitionId $AssetPartitionId -ItemType "Profile" -ItemToEdit $ProfileToEdit -NewName $NewName
}

<#
.SYNOPSIS
Copy a password profile in Safeguard via the Web API.
 
.DESCRIPTION
Copy a password profile without changing any of its configuration.
 
.PARAMETER Appliance
IP address or hostname of a Safeguard appliance.
 
.PARAMETER AccessToken
A string containing the bearer token to be used with Safeguard Web API.
 
.PARAMETER Insecure
Ignore verification of Safeguard appliance SSL certificate.
 
.PARAMETER AssetPartition
An integer containing an ID or a string containing the name of the asset partition
to copy the password profile in.
 
.PARAMETER AssetPartitionId
An integer containing the asset partition ID to copy the password profile in.
(If specified, this will override the AssetPartition parameter)
 
.PARAMETER ProfileToEdit
An integer containing the ID of the password profile to copy or a string containing the name.
 
.PARAMETER CopyName
A string containing the name for the new password profile.
 
.PARAMETER DeepCopy
Whether to deep copy the profile, meaning make a copy of the account password rule, check password
schedule, and change password schedule, which will be given names based on the CopyName parameter
that is provided.
#>

function Copy-SafeguardPasswordProfile
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Appliance,
        [Parameter(Mandatory=$false)]
        [object]$AccessToken,
        [Parameter(Mandatory=$false)]
        [switch]$Insecure,
        [Parameter(Mandatory=$false)]
        [object]$AssetPartition,
        [Parameter(Mandatory=$false)]
        [int]$AssetPartitionId = $null,
        [Parameter(Mandatory=$true,Position=0)]
        [object]$ProfileToCopy,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$CopyName,
        [Parameter(Mandatory=$false)]
        [switch]$DeepCopy
    )

    if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
    if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") }

    $local:Copy = (Copy-SafeguardProfileItem -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
                       -AssetPartitionId $AssetPartitionId -ItemType "Profile" -ItemToCopy $ProfileToCopy -CopyName $CopyName)
    if ($DeepCopy)
    {
        $local:APR = (Copy-SafeguardAccountPasswordRule -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
                          -AssetPartitionId $AssetPartitionId -PasswordRuleToCopy $local:Copy.AccountPasswordRule.Id -CopyName "$CopyName Password Rule")
        $local:Chk = (Copy-SafeguardPasswordCheckSchedule -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
                          -AssetPartitionId $AssetPartitionId -CheckScheduleToCopy $local:Copy.CheckSchedule.Id -CopyName "$CopyName Check Schedule")
        $local:Chg = (Copy-SafeguardPasswordChangeSchedule -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
                          -AssetPartitionId $AssetPartitionId -ChangeScheduleToCopy $local:Copy.ChangeSchedule.Id -CopyName "$CopyName Change Schedule")

        $local:Copy = (Edit-SafeguardPasswordProfile -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure -AssetPartition $AssetPartition `
                           -AssetPartitionId $AssetPartitionId $local:Copy.Id -PasswordRuleToSet $local:APR.Id -CheckScheduleToSet $local:Chk.Id -ChangeScheduleToSet $local:Chg.Id)
    }

    $local:Copy
}