Infrastruttura dispositivo virtuale non persistente (NP-VDI)
NP-VDI consente al team IT di eseguire rapidamente il provisioning di desktop virtuali insieme a dispositivi fisici, il tutto da un'unica piattaforma unificata. La gestione automatizzata integrata consente di risparmiare tempo, ridurre il sovraccarico manuale e ottenere un controllo completo degli endpoint negli ambienti cloud.
Flusso di lavoro funzione
Distribuzione agente sull'immagine di base:
-
L'agente è installato (non registrato) su una VM pulita.
-
L'agente viene quindi registrato manualmente come "Immagine di base" utilizzando gli strumenti a riga di comando forniti.
Sigillatura dell'immagine di base:
-
Una volta che l'agente immagine di base si è registrato e la configurazione è stata convalidata, la VM è "sigillata" tramite la riga di comando.
Istanze di generazione:
-
Le nuove istanze NP-VDI possono essere generate dall'immagine di base, generando di solito un nuovo indirizzo MAC per ogni sessione.
-
Ivanti Neurons rileva e tiene traccia di questi come endpoint unici a breve termine gestiti sotto l'immagine di base.
Gestione criteri:
-
È possibile apportare modifiche ai criteri a livello di immagine di base. Tutte le istanze generate ereditano l'ultimo criterio applicato al successivo check-in.
Fase 1: Preparare l'immagine di base
Per preparare l'immagine di base, attenersi alla seguente procedura:
- Accedere ad Agente > Distribuzione agente > Installazione manuale.
- Nella scheda Installazione manuale, scegliere un criterio agente e una chiave di registrazione.
- Selezionare Windows. Quindi, scegliere una Modalità di installazione e fare clic su Scarica.
Il programma di installazione dell'agente verrà scaricato.Questa azione scarica due file. Salvare il programma di installazione con il nome file "IvantiCloudAgent.exe.options". Questo file verrà utilizzato per l'installazione.
- Installare l'agente NP-VDI scaricato.
Per installare l'agente:- Rinominare il file IvantiCloudAgent.exe.options associato prima dell'installazione.
- Eseguire il programma di installazione. Quando viene visualizzata la chiave di attivazione o l'opzione Cookie, fare clic su Annulla.
Questo installa l'agente sull'endpoint senza registrarlo sul tenant.
- Registrare l'agente come immagine di base. Per registrarsi come immagine di base, eseguire il seguente comando, come amministratore, dalla posizione di installazione dell'agente:
STAgentCtl.exe register --asBaseImage <Base Image Name> --instanceIdType MacAddress --enrollmentkey "%enrollmentkey%" --baseurl https://agentreg.ivanticloud.com
Nel comando precedente:
<Base Image Name> è il nome del dispositivo immagine di base.
%enrollmentkey% è una combinazione di tenantid_activationkey.
instanceIdType può essere "MacAddress", "HostName" o "Personalizzato". Viene utilizzato come flag univoco per l'identificazione dell'istanza.
Se si utilizza "Personalizzato", è possibile specificare un'opzione tagList contenente un elenco separato da virgole di tag personalizzati per identificare tale agente. Per maggiori informazioni sui tag personalizzati, vedere la sezione Elenco tag personalizzati e Aggiorna tag.
Sia il tenantid che la activationkey possono essere trovati nel file .options associato, scaricato con l'agente come mostrato nell'esempio seguente:
tenantid = 11111111-1111-1111-1111-4gc02d5b0f0d
activationkey = 9aI7SOQNybweiM2QKI7kcqIG8ufUFU21AvZwJwAEx6C-SAO5UGK62YkEgm89kvC2m-xwLesZA4t1_TBtEjIQMVaBU0KsVe-V60ZLBwWu83YREcUp3diAFvHjBvLtkxT3
cloudhost=https:agentreg.ivanticlouddev.comLa chiave di registrazione per il codice di cui sopra è:
%enrollmentkey% = 11111111-1111-1111-1111-4gc02d5b0f0d_9aI7SOQNybweiM2QKI7kcqIG8ufUFU21AvZwJwAEx6C-SAO5UGK62YkEgm89kvC2m-xwLesZA4t1_TBtEjIQMVaBU0KsVe-V60ZLBwWu83YREcUp3diAFvHjBvLtkxT3La riga di comando per registrare un dispositivo con il tenant di esempio per un'immagine di base denominata "Win11" sarà la seguente:
STAgentCtl.exe register --asBaseImage Win11 --instanceIdType MacAddress --enrollmentkey “11111111-1111-1111-1111-4gc02d5b0f0d_9aI7SOQNybweiM2QKI7kcqIG8ufUFU21AvZwJwAEx6C-SAO5UGK62YkEgm89kvC2m-xwLesZA4t1_TBtEjIQMVaBU0KsVe-V60ZLBwWu83YREcUp3diAFvHjBvLtkxT3" --baseurl https://agentreg.ivanticloud.com
- Per aggiornare l'immagine di base:
- Scaricare lo script PowerShell dal portale della community Ivanti: Ivanti-Neurons -Non-Persistent-VDI - Agent Script.
Prima di eseguire lo script PowerShell, verificare che l'amministratore disponga delle autorizzazioni pertinenti per eseguirlo sull'immagine di base, in quanto il criterio di esecuzione sull'endpoint potrebbe bloccarlo:
Per controllare, utilizzare il comando "Get-ExecutionPolicy".
Per modificare, utilizzare il comando "Set-ExecutionPolicy RemoteSigned".
- Se lo script viene eseguito senza parametri, tenterà quanto segue:
- Rimuovere il sigillo dell'agente.
- Eseguire gli aggiornamenti sia per gli agenti che per i motori.
- Sigillare nuovamente l'agente.
- Se l'agente è già dissigillato e deve rimanere dissigillato dopo l'aggiornamento. Passare il parametro "DoNotSeal" per eseguire tutti gli stessi passaggi, tranne la sigillatura dell'immagine.
- Il timeout predefinito per gli aggiornamenti è di 300 secondi. È possibile modificare l'ora passando l'argomento "-TimeoutSec".
Per ulteriori riferimenti, è possibile accedere alla copia dello script nella sezione Appendice.
- Per preparare l'immagine di base:
- Eseguire il comando "STAgentCtl.exe prepareImage" per rendere un'immagine di base sigillata e non persistente pronta per NP-VDI.
Questo comando è obbligatorio e interrompe tutti i servizi ed elimina tutti i dati relativi all'ID agente effettivo dell'immagine di base. Quando l'istanza non persistente si avvia, il servizio viene riavviato.L'ID agente cambierà con ogni istanza non persistente generata dall'immagine di base.
- Utilizzare i seguenti comandi per sigillare manualmente l'immagine di base (al di fuori dello script di aggiornamento):
- Per sigillare manualmente l'immagine di base, immettere "STAgentCtl.exe seal".
Utilizzare il comando "unseal" per sbloccare l'immagine. Ciò rimane attivo fino al riavvio del sistema o all'utilizzo del comando "Sigilla".
- Per sigillare manualmente l'immagine di base, immettere "STAgentCtl.exe seal".
- Eseguire il comando "STAgentCtl.exe prepareImage" per rendere un'immagine di base sigillata e non persistente pronta per NP-VDI.
- (Facoltativo) Preparare l'immagine per l'uso con "sysprep".
Se la preparazione desktop non persistente include una fase sysprep, rimuoverà la chiave privata del certificato agente dall'archivio dei certificati. Per risolvere questo problema, attenersi alla seguente procedura:L'amministratore deve fornire la propria password di esportazione certificato; altrimenti, questo processo non riuscirà.
- Individuare il numero di serie del certificato utilizzando il comando certutil -store "Ivanti Cloud Agent Agent".
Questo elenco elenca il certificato nell'archivio dei certificati agente. - Dopo aver eseguito il comando "stagentctl prepareImage" nella Fase 7, è possibile esportare il certificato agente utilizzando il seguente comando:
certutil -exportPFX -privatekey -p "%pfxpass%" “Ivanti Cloud Agent Agent” %serialnumber% "%ProgramFiles%\Ivanti\Ivanti Cloud Agent\agent.pfx" NoChain,NoRoot
Nel comando precedente:
%pfxpass% è una password fornita dall'amministratore.
%serialnumber% è il numero di serie localizzato del certificato agente.
- Scaricare lo script SetupComplete.cmd disponibile dal sito web della comunità Ivanti qui: ripristinare la chiave privata dallo script file .pfx esportato.
- Modificare lo script SetupComplete.cmd e aggiornare la password in modo che corrisponda alla password utilizzata per esportare il certificato utilizzato nella Fase 2.
- Memorizzare lo script in %WINDIR%\Setup\Scripts\SetupComplete.cmd sull'immagine dorata.
Lo script verrà eseguito automaticamente una volta completata la configurazione di Windows (il che accade la prima volta che il dispositivo viene avviato dopo sysprep).Questo ripristinerà la chiave privata dal file .pfx esportato, quindi eliminerà sia il file .pfx che lo script stesso, in modo che il segreto non finisca in istanze non persistenti.
Il certificato con l'oggetto OU "Agente ST" (ad es. "Subject: OU=ST Agent, CN=011472EFB12BABF06122F2903BBE12AC4E32EBFE5082") deve essere esportato, utilizzando il numero di serie corrispondente da tale voce.
- Individuare il numero di serie del certificato utilizzando il comando certutil -store "Ivanti Cloud Agent Agent".
Fase 2: creazione e test di istanze NP-VDI
Per ruotare una nuova istanza dall'immagine di base, attenersi alla seguente procedura:
-
Assicurarsi che a ogni nuova istanza sia assegnato un nuovo indirizzo MAC (per garantire che l'opzione instanceIdType MacAddress funzioni).
In alternativa, assicurarsi di utilizzare un nome host o un tag diverso. -
Avviare l'istanza della macchina virtuale e confermare che l'istanza venga visualizzata nell'interfaccia utente Neurons come endpoint NP-VDI univoco. Andare alla sezione Agenti > Gestione agenti dell'interfaccia Ivanti Neurons per eseguire questa operazione.
È disponibile una nuova colonna Tipo VDI che indica se il dispositivo è un'immagine di base, un dispositivo non persistente o persistente. -
Ciascun endpoint agente è ora collegato dalla pagina Gestione agenti alla pagina Dispositivi. Fare clic sul nome dell'endpoint agente per avviare una nuova finestra che mostra il dispositivo nella vista Dispositivi.
-
Fare clic sull'opzione Istanze collegate per visualizzare tutte le istanze generate da questa immagine di base.
Le istanze non persistenti verranno contrassegnate come non persistenti nella vista Dispositivi.
Fase 3: riassegnazione del criterio con NP-VDI
Per riassegnare un criterio all'immagine di base direttamente dall'interfaccia Ivanti Neurons, attenersi alla seguente procedura:
-
Navigare in Agenti > Criteri agente.
-
Selezionare l'immagine di base e scegliere Riassegna criterio dal menu Azioni.
-
Scegliere il criterio da riassegnare e fare clic su Salva.
In questo modo viene riassegnato il criterio. Dopo che il criterio è stato riassegnato all'immagine di base, tutte le istanze VDI non persistenti erediteranno il criterio la prossima volta che effettuano il check-in (che per impostazione predefinita è ogni 200 minuti). -
Convalidare che le nuove istanze ereditano il criterio aggiornato dopo il check-in, utilizzando l'interfaccia Ivanti Neurons Agents o Agent Management o dall'immagine non persistente stessa, utilizzando la riga di comando "Stato Stagentctl".
Non è possibile effettuare azioni di riavvio su un'istanza NP-VDI. Ciò reimposterebbe il dispositivo allo stato iniziale, causando potenzialmente la perdita di lavoro da parte dell'utente durante la sessione.
Inoltre, le Azioni disponibili nella vista Dispositivi per le istanze non persistenti non contengono azioni di riavvio.
Comandi aggiuntivi STAgentCtle.exe
È possibile utilizzare i seguenti comandi aggiuntivi:
-
Per aprire l'agente di base per gli aggiornamenti, immettere il comando "Standantctl.exe unseal".
-
Per forzare la riga di comando ad attendere il completamento dell'aggiornamento prima di restituire il controllo, immettere il comando "Stagentctl.exe update -wait".
Il comando "Attesa" potrebbe riscontrare problemi quando l'agente viene aggiornato, in quanto richiede l'esecuzione degli eseguibili, il che porta alla necessità di un riavvio dopo l'aggiornamento. Per evitare questo problema, Ivanti offre uno script PowerShell che consente l'esecuzione di un comando di aggiornamento sincrono.
-
Per chiudere l'agente di base per gli aggiornamenti, immettere il comando "Stagentclt.exe seal".
Elenco tag personalizzati
Un elenco di tag personalizzati è una raccolta definita dall'utente di tag che possono essere assegnati agli endpoint in Ivanti Neurons, comprese le istanze NP-VDI. I tag personalizzati aiutano a classificare, organizzare e identificare i dispositivi in base ai requisiti aziendali, operativi o tecnici.
Ad esempio, l'utilizzo del tag "Sales-[MacAddress]" genera un tag univoco per ciascun dispositivo sostituendo [MacAddress] con l'indirizzo MAC reale del dispositivo. Questa funzionalità è particolarmente utile per generare tag univoci per istanze VDI non persistenti.
Utilizzare la seguente sintassi per fare riferimento agli attributi del dispositivo e alle variabili ambientali:
-
Per fare riferimento all'indirizzo MAC, utilizzare "[MacAddress]"
-
Per fare riferimento al nome host, utilizzare "[HostName]"
-
Per fare riferimento a una variabile di ambiente, utilizzare "[env:<name>]"
Dove <name> è il nome che fa distinzione tra maiuscole e minuscole della variabile di ambiente.
Aggiorna tag
I tag assegnati durante la registrazione dell'immagine di base rimangono statici per tutte le istanze associate. Se è necessario aggiornare i tag, registrare nuovamente/sigillare l'immagine di base o utilizzare l'automazione per assegnare i tag in base ai criteri correnti dopo la distribuzione VM.
Appendice
.SYNOPSIS
Aggiorna un agente non persistente, in attesa del completamento dell'aggiornamento, quindi sigilla facoltativamente l'agente.
.PARAMETER TimeoutSec
Timeout totale in secondi.
.PARAMETER UpgradeCode
Codice di aggiornamento dell'agente in fase di aggiornamento.
.PARAMETER DoNotSeal
Questo parametro specifica di non sigillare l'agente dopo l'aggiornamento.
#>
param
(
[int] $TimeoutSec = 300,
[guid] $UpgradeCode = "{0C5D7E9C-0424-462D-A570-2A7469EE3739}", # Neurons Agent
[switch] $DoNotSeal
)
function Check-UpdatersComplete
{
$updaters = Get-Process -Name "STAgentUpdater" -ErrorAction SilentlyContinue
return ($updaters.Count -eq 0)
}
function Wait-UpdatersComplete([DateTime] $timeoutDateTime, [int] $checkIntervalSec)
{
while ((Get-Date) -lt $timeoutDateTime)
{
if (Check-UpdatersComplete)
{
return
}
Start-Sleep -Seconds $checkIntervalSec
}
throw "Timeout waiting for all updaters to complete."
}
function Get-AgentVersionFromManifest([string] $manifestPath, [string] $platformKey)
{
if (-not (Test-Path $manifestPath))
{
throw "Could not find manifest at '$manifestPath'."
}
[xml]$manifestXml = Get-Content $manifestPath
$agentFile = $manifestXml.manifest.files.file | Where-Object { $_.key -eq $platformKey }
if (-not ($agentFile))
{
throw "Agent entry with key='$platformKey' not found."
}
if (-not ($agentFile.version))
{
throw "Unable to find agent version in manifest."
}
return [version]::Parse($agentFile.version)
}
function Get-CurrentAgentVersion([guid] $agentUpgradeCode)
{
$agentProductCode = Get-ProductCode -UpgradeCode $agentUpgradeCode
$agentObject = Get-WmiObject -Class Win32_Product | Where-Object { [guid]::Parse($_.IdentifyingNumber) -eq $agentProductCode }
if (-not ($agentObject))
{
throw "Installed agent not found."
}
if (-not ($agentObject.Version))
{
throw "Installed agent version not found."
}
return [version]::Parse($agentObject.Version)
}
function Check-AgentUpToDate([string] $manifestPath, [guid] $agentUpgradeCode, [string] $platformKey)
{
$manifestVersion = Get-AgentVersionFromManifest -ManifestPath $manifestPath -PlatformKey $platformKey
$currentVersion = Get-CurrentAgentVersion -AgentUpgradeCode $agentUpgradeCode
return ($currentVersion -ge $manifestVersion)
}
function Wait-AgentUpdated([DateTime] $timeoutDateTime, [int] $checkIntervalSec, [string] $manifestPath, [guid] $agentUpgradeCode, [string] $platformKey)
{
while ((Get-Date) -lt $timeoutDateTime)
{
if (Check-AgentUpToDate -ManifestPath $manifestPath -AgentUpgradeCode $agentUpgradeCode -PlatformKey $platformKey)
{
return
}
Start-Sleep -Seconds $checkIntervalSec
}
throw "Waiting for agent update timed out."
}
funzione Update-Agent([DateTime] $timeoutDateTime, [stringa] $manifestPath, [guida] $agentUpgradeCode, [stringa] function Update-Agent([DateTime] $timeoutDateTime, [string] $manifestPath, [guid] $agentUpgradeCode, [string] $agentCtlPath, [string] $platformKey)
{
$timeoutSec = [math]::Ceiling(($timeoutDateTime - (Get-Date)).TotalSeconds)
if ($timeoutSec -le 0)
{
throw "Can't run check-in because of small timeout."
}
& $agentCtlPath update --checkin --wait $timeoutSec
if (-not $?)
{
throw "Check-in operation failed."
}
& $agentCtlPath update --all
if (-not $?)
{
throw "Update operation failed."
}
Wait-AgentUpdated -TimeoutDateTime $timeoutDateTime -CheckIntervalSec 1 -ManifestPath $manifestPath -AgentUpgradeCode $agentUpgradeCode -PlatformKey $platformKey
Wait-UpdatersComplete -TimeoutDateTime $timeoutDateTime -CheckIntervalSec 1
$timeoutSec = [math]::Ceiling(($timeoutDateTime - (Get-Date)).TotalSeconds)
if ($timeoutSec -le 0)
{
throw "Can't run final update because of small timeout."
}
& $agentCtlPath update --all --wait $timeoutSec
if (-not $?)
{
throw "Final update operation failed."
}
}
function Get-ProductCode([guid] $upgradeCode)
{
$upgradeCodeStr = $upgradeCode.ToString("B") # Format as {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
$wmiFilter = "Property='UpgradeCode' AND Value='$upgradeCodeStr'"
$productCode = @(Get-WmiObject -Class Win32_Property -Filter $wmiFilter).ProductCode
if ($productCode.Count -eq 0)
{
throw "Upgrade code '$upgradeCode' not found."
}
if ($productCode.Count -gt 1)
{
throw "Multiple products with the same upgrade code '$upgradeCode' were found."
}
return [guid]::Parse($productCode)
}
function Get-AgentEnvironment([string] $installDirPath)
{
$configPath = Join-Path $installDirPath "AgentEnvironment.config"
if (-Not (Test-Path $configPath))
{
throw "Config file not found at $configPath."
}
[xml]$agentEnvironment = Get-Content $configPath
return $agentEnvironment
}
function Get-InstallLocation([guid] $productCode)
{
$productObject = Get-WmiObject -Class Win32_Product | Where-Object { [guid]::Parse($_.IdentifyingNumber) -eq $productCode }
if ($null -eq $productObject)
{
throw "The product GUID was not found."
}
return $productObject.InstallLocation
}
$timeoutDateTime = (Get-Date).AddSeconds($TimeoutSec)
Write-Host "Gathering information..."
try
{
$agentProductCode = Get-ProductCode -UpgradeCode $UpgradeCode
$installDirPath = Get-InstallLocation -ProductCode $agentProductCode
Write-Host " Install directory: $installDirPath"
$agentEnvironment = Get-AgentEnvironment -InstallDirPath $installDirPath
$dataDirPath = $agentEnvironment.agentEnvironment.agentDataDirectory
Write-Host " Data directory: $dataDirPath"
$regPath = Join-Path "HKLM:" $agentEnvironment.agentEnvironment.registryPath
Write-Host " Registry key: $regPath"
$platformKey = Get-ItemProperty -Path $regPath -Name "PlatformManifestKey" -ErrorAction Stop | Select-Object -ExpandProperty "PlatformManifestKey" -ErrorAction Stop
Write-Host " Platform key: $platformKey"
$agentCtlPath = Join-Path $installDirPath "STAgentCtl.exe"
$manifestPath = Join-Path $dataDirPath "manifest.xml"
}
catch
{
Write-Error "ERROR: $_"
exit -1
}
if ((Get-Date) -gt $timeoutDateTime)
{
Write-Error "ERRORE: il timeout è scaduto prima che l'aggiornamento dell'agente potesse iniziare".
exit -1
}
Write-Host "Dissigillare l'agente..."
& $agentCtlPath unseal
if (-not $?)
{
Errore di scrittura "ERRORE: impossibile eseguire l'operazione di desigillatura".
exit -1
}
Write-Host "Aggiornamento dell'agente..."
$result = -1
try
{
Update-Agent -TimeoutDateTime $timeoutDateTime -ManifestPath $manifestPath -AgentUpgradeCode $UpgradeCode -AgentCtlPath $agentCtlPath -PlatformKey $platformKey
$result = 0
}
catch
{
Write-Error "ERROR: $_"
}
if ($DoNotSeal)
{
if ($result -eq 0)
{
Write-Host "L'agente è stato aggiornato correttamente".
}
else
{
Write-Error "ERRORE: aggiornamento agente non riuscito."
}
exit $result
}
Write-Host "Sigillare l'agente..."
& $agentCtlPath seal
if (-not $?)
{
Errore di scrittura "ERRORE: impossibile sigillare l'agente!"
exit -1
}
if ($result -eq 0)
{
Write-Host "L'agente è stato aggiornato e sigillato correttamente".
}
exit $result
(@ECHO OFF
set pw=supersecret
set logfile=C:\ProgramData\Ivanti\Ivanti Cloud Agent\Logs\agentkeyrestore.log
set certFile=C:\Program Files\Ivanti\Ivanti Cloud Agent\agent.pfx
set scriptPath=%0%
ECHO %date% %time% Agent key restore started >> "%logfile%"
IF EXIST "%certFile%" (
certutil -f -p "%pw%" -privatekey -importPFX "Ivanti Cloud Agent Agent" "%certFile%" NoCert,NoExport >> "%logfile%" 2>&1
IF %ERRORLEVEL% NEQ 0 (
ECHO Impossibile importare la chiave agente >> "%logfile%"
)
ECHO Rimozione file chiave agente >> "%logfile%"
del "%certFile%" >> "%logfile%" 2>&1
IF %ERRORLEVEL% NEQ 0 (
ECHO Impossibile eliminare file chiave agente >> "%logfile%"
)
Ripristino chiave Agente ECHO %date% %time% completato >> "%logfile%"
) ELSE (
Ripristino chiave Agente ECHO %date% %time% non riuscito: nessun file chiave agente trovato >> "%logfile%"
)
ECHO Rimozione script >> "%logfile%"
del "%scriptPath%" >> "%logfile%" 2>&1
"REM non è possibile eseguire ulteriori comandi da questo punto perché il file script è stato eliminato"