
Parallels RAS guarda toda su configuración en una base de datos centralizada alojada en el Connection Broker: reglas de publicación, topología de la granja, directivas de sesión, personalización de la interfaz y mucho más. Perder esta configuración —tras una avería del broker, una actualización fallida o la reconstrucción completa de un servidor— obliga a reconfigurarlo todo a mano, lo que puede llevar varias horas en un despliegue complejo.
El cmdlet Invoke-RASExportSettings, incluido en el SDK de PowerShell de Parallels RAS, permite exportar la configuración completa a un archivo .dat2 que se puede restaurar en cualquier momento con Invoke-RASImportSettings. El script que presentamos en este artículo automatiza esta exportación a diario y gestiona la retención de los archivos.
La autenticación se basa en una cuenta de dominio dedicada, svc_rasexport, cuya contraseña se cifra localmente en un archivo de credenciales mediante la API SecureString de PowerShell. Las copias se guardan en un recurso compartido de red dedicado, \MSHOME-VEEAMRASBACKUP$, alojado en el servidor de copias de Veeam. Esta cuenta necesita el rol RAS Administrator en la granja RAS: Power Administrator no basta. En este ejemplo, el script se ejecuta directamente desde uno de los brokers.

$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$LogFile = "$ScriptRootRASBackup_$(Get-Date -Format 'yyyy-MM').log"
$BackupShare = "\MSHOME-VEEAM\RASBACKUP$\$(Get-Date -Format 'dd-MM-yyyy').dat2"
$BrokerFQDN = $env:COMPUTERNAME
$ServiceAccount = "svc_rasexport@$($env:USERDNSDOMAIN)"
$CredentialStore = "$ScriptRootsvc_rasexport.cred"
$EncryptionKey = (1..32)
$RetentionDays = 30
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$Entry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [$Level] $Message"
Add-Content -Path $LogFile -Value $Entry
switch ($Level) {
"ERROR" { Write-Host $Entry -ForegroundColor Red }
"WARN" { Write-Host $Entry -ForegroundColor Yellow }
default { Write-Host $Entry }
}
}
function Get-RASCredential {
if (-not (Test-Path $CredentialStore)) {
Write-Log "Credential store not found: $CredentialStore" "ERROR"
Write-Log "Run once to initialize: Read-Host -AsSecureString | ConvertFrom-SecureString -Key (1..32) | Set-Content '$CredentialStore'" "WARN"
exit 1
}
try {
$SecurePassword = Get-Content $CredentialStore | ConvertTo-SecureString -Key $EncryptionKey
return New-Object System.Management.Automation.PSCredential($ServiceAccount, $SecurePassword)
}
catch {
Write-Log "Failed to decrypt credential: $_" "ERROR"
exit 1
}
}
function Connect-RASBroker {
$Credential = Get-RASCredential
try {
Write-Log "Connecting to RAS broker $BrokerFQDN as $ServiceAccount"
New-RASSession -Server $BrokerFQDN -Username $Credential.UserName -Password $Credential.Password
Write-Log "RAS session established"
return $true
}
catch {
Write-Log "Failed to connect to RAS broker: $_" "ERROR"
return $false
}
}
function Invoke-RASBackup {
$BackupDir = Split-Path -Parent $BackupShare
if (-not (Test-Path $BackupDir)) {
New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null
}
try {
Write-Log "Exporting RAS settings to $BackupShare"
Invoke-RASExportSettings $BackupShare
Write-Log "Export completed successfully"
}
catch {
Write-Log "Export failed: $_" "ERROR"
exit 1
}
finally {
Remove-RASSession -ErrorAction SilentlyContinue
Write-Log "RAS session closed"
}
}
function Invoke-BackupRetention {
$BackupDir = Split-Path -Parent $BackupShare
Get-ChildItem -Path $BackupDir -Filter "*.dat2" |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$RetentionDays) } |
ForEach-Object {
Remove-Item $_.FullName -Force
Write-Log "Removed expired backup: $($_.Name)" "WARN"
}
}
Write-Log "Backup started"
if (Connect-RASBroker) {
Invoke-RASBackup
Invoke-BackupRetention
Write-Log "Backup completed"
} else {
Write-Log "Backup failed" "ERROR"
exit 1
}
Para inicializar el archivo de credenciales, ejecuta el siguiente script una sola vez, de forma interactiva, en el broker y con la cuenta que ejecutará la tarea programada:
$CredentialStore = "$PSScriptRootsvc_rasexport.cred"
$EncryptionKey = (1..32)
Read-Host -AsSecureString -Prompt "Password for svc_rasexport" |
ConvertFrom-SecureString -Key $EncryptionKey |
Set-Content $CredentialStore
Write-Host "Credential store created: $CredentialStore"
Por ahora no es posible usar una cuenta gMSA para ejecutar este script. El cmdlet New-RASSession exige un parámetro -Password explícito de tipo SecureString, incompatible con el mecanismo de gestión de contraseñas de las cuentas gMSA. Una cuenta de servicio clásica con un archivo de contraseña cifrado sigue siendo la única opción viable.
