Private/Update-PVEAuthTicket.ps1

function Update-PVEAuthTicket {
  <#
  .SYNOPSIS
  Obtains or renews the PVEAuthCookie ticket for a ticket-authenticated connection.
  .DESCRIPTION
  Without -ForceLogin, first tries to renew by posting the current ticket as the password (supported by
  POST /access/ticket: "The secret password. This can also be a valid ticket."). If that fails, or with
  -ForceLogin, logs in again with the stored credential.
  #>

  [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private helper; only refreshes in-memory authentication state.')]
  [CmdletBinding()]
  param(
    [Parameter(Mandatory)]
    [psobject]$Connection,

    [switch]$ForceLogin
  )

  $state = $script:PVEAuthState[$Connection.Id]
  if ($null -eq $state -or $state.AuthType -ne 'Ticket') {
    return
  }

  $userName = $state.Credential.UserName
  $result = $null

  if (-not $ForceLogin -and $state.Ticket) {
    try {
      $result = Invoke-PVERequest -Connection $Connection -Method POST -Path '/access/ticket' -NoAuth -Parameters @{
        username = $userName
        password = $state.Ticket
      }
    }
    catch {
      Write-Verbose "Ticket renewal for $userName failed ($($_.Exception.Message)); logging in with the stored credential."
    }
  }

  if ($null -eq $result) {
    $result = Invoke-PVERequest -Connection $Connection -Method POST -Path '/access/ticket' -NoAuth -Parameters @{
      username = $userName
      password = ConvertFrom-PVESecureString -SecureString $state.Credential.Password
    }
  }

  # With two-factor authentication enabled, PVE returns a half-authenticated ticket and NeedTFA instead
  # of a usable ticket. TFA login is not supported; API tokens are the intended route for automation.
  $ticket = [string](Get-PVEValue $result 'ticket')
  $csrfToken = [string](Get-PVEValue $result 'CSRFPreventionToken')
  if ((Get-PVEValue $result 'NeedTFA') -or $ticket.Contains('!tfa!')) {
    throw "User $userName has two-factor authentication enabled, which PVEPS does not support for interactive login. Use an API token instead (Connect-PVE -Token)."
  }
  if (-not $ticket -or -not $csrfToken) {
    throw "Login to $($Connection.Server) as $userName did not return a ticket and CSRF token."
  }

  $state.Ticket = $ticket
  $state.CsrfToken = $csrfToken
  $state.TicketTime = Get-Date
}