Gli ingegneri di rete si trovano spesso a dover copiare e incollare determinati frammenti da un notepad alla console. Di solito è necessario copiare diversi parametri: nome utente/password e qualcos'altro. L'uso di script consente di velocizzare questo processo. TUTTAVIA, la scrittura e l'esecuzione dello script devono richiedere complessivamente meno tempo della configurazione manuale, altrimenti gli script sono inutili.
A cosa serve questo articolo. Questo articolo è parte della serie Fast Start ed è progettato per risparmiare tempo agli ingegneri di rete durante la configurazione di apparecchiature (un compito) su più dispositivi. Viene utilizzato il software SecureCRT e la funzionalità integrata di esecuzione degli script.
Contenuto
Introduzione
Il programma SecureCRT include un meccanismo di esecuzione degli script predefinito. A cosa servono gli script nel terminale:
- Immissione e output automatizzati, e verifica minima della correttezza di input/output.
- Accelerare l'esecuzione delle attività di routine – riduzione delle pause durante la configurazione dell'apparecchiatura. (De facto riduzione delle pause causate dal tempo necessario per eseguire operazioni di copia/incolla sulla stessa apparecchiatura, con 3 o più frammenti di comandi da applicare all'apparecchiatura.)
In questo documento vengono trattate le seguenti attività:
- Creazione di semplici script.
- Esecuzione di script su SecureCRT.
- Esempi di utilizzo di script semplici e avanzati. (Pratica dalla vita reale.)
Creazione di semplici script.
I semplici script utilizzano solo due comandi: Send e WaitForString. Questa funzionalità è sufficiente per il 90% (e più) delle attività eseguite.
Gli script possono essere scritti in Python, JS, VBS (Visual Basic), Perl, ecc.
Python
# $language = "Python"
# $interface = "1.0"
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("r")
crt.Screen.WaitForString("name")
crt.Screen.Send("adminr")
crt.Screen.WaitForString("Password:")
crt.Screen.Send("Password")
crt.Screen.Synchronous = False
main()
Di solito, un file con estensione «*.py»
VBS
# $language = "VBScript"
# $interface = "1.0"
Sub Main
crt.Screen.Synchronous = True
crt.Screen.Send vbcr
crt.Screen.WaitForString "name"
crt.Screen.Send "cisco" & vbcr
crt.Screen.WaitForString "assword"
crt.Screen.Send "cisco" & vbcr
crt.Screen.Synchronous = False
End Sub
Di solito, un file con estensione «*.vbs»
Creazione di uno script utilizzando la registrazione dello script.
Permette di automatizzare il processo di scrittura dello script. Avviate la registrazione dello script. SecureCRT registra i comandi, le risposte dell'hardware e vi restituisce lo script pronto.
a. Avviare la registrazione dello script:
Menu SecureCRT => Script => Inizia registrazione script
b. Eseguire azioni nella console (effettuare le configurazioni nel CLI).
c. Terminare la registrazione dello script:
Menu SecureCRT => Script => Ferma registrazione script…
Salvare il file con lo script.
Esempio di comandi eseguiti e script salvato:

Esecuzione di script su SecureCRT.
Dopo la creazione/modifica dello script, sorge la domanda: come applicare lo script?
Ci sono diversi metodi:
- Esecuzione manuale dal menu Script
- Esecuzione automatica dopo la connessione (logon script)
- Accesso automatico senza utilizzo dello script
- Esecuzione manuale tramite un pulsante in SecureCRT (il pulsante deve ancora essere creato e aggiunto in SecureCRT)
Esecuzione manuale dal menu Script
Menu SecureCRT => Script => Esegui…
— Gli ultimi 10 script vengono memorizzati e sono disponibili per un avvio veloce:
Menu SecureCRT => Script => 1 «Nome del file dello script»
Menu SecureCRT => Script => 2 «Nome del file dello script»
Menu SecureCRT => Script => 3 «Nome del file dello script»
Menu SecureCRT => Script => 4 «Nome del file dello script»
Menu SecureCRT => Script => 5 «Nome del file dello script»
Esecuzione automatica dopo la connessione (logon script)
Le impostazioni dello script di accesso automatico sono configurate per la sessione salvata: Connection => Logon Actions => Logon script

Accesso automatico senza utilizzo dello script
È possibile inserire automaticamente il nome utente e la password senza scrivere uno script, utilizzando solo le funzionalità integrate di SecureCRT. Nelle impostazioni di connessione «Connection» => Logon Actions => Automate logon è necessario compilare alcune coppie che rappresentano: «Testo atteso» + «Simboli inviati per questo testo». Queste coppie possono essere molte. (Esempio: 1a coppia attesa per l'inserimento del nome utente, 2a attesa per l'inserimento della password, 3a attesa per il prompt in modalità privilegiata, 4a password per la modalità privilegiata.)
Esempio di accesso automatico su Cisco ASA:

Esecuzione manuale tramite un pulsante in SecureCRT (il pulsante deve ancora essere creato e aggiunto in SecureCRT)
In SecureCRT è possibile assegnare uno script a un pulsante. Il pulsante viene aggiunto a una barra creata appositamente per questo scopo.
a. Aggiungiamo la barra all'interfaccia: Menu SecureCRT => View => Button Bar
b. Aggiungiamo un pulsante alla barra e poi lo script. – Clic destro sulla barra Button Bar e nel menu contestuale selezionare «New button…».
c. Nella finestra di dialogo «Map Button» nel campo «Action» selezioniamo l'azione (function) «Run Script».
Indichiamo il testo del pulsante. Colore per l'icona del pulsante. Completiamo le impostazioni premendo Ok.

Nota:
La barra dei pulsanti è una funzionalità molto utile.
1. È possibile specificare quale pannello aprire per impostazione predefinita a questa scheda durante il Logon a una sessione specifica.
2. È possibile definire azioni preimpostate per le operazioni standard con l'hardware: mostrare show version, show running-config, salvare la configurazione.

A questi pulsanti non è associato alcuno script. Solo una riga con le azioni:

La configurazione – affinché, al passaggio alla sessione, si apra il pannello dei pulsanti necessario, deve essere effettuata nelle impostazioni della sessione:

Per il cliente ha senso configurare script personalizzati per il Login e passare al pannello con i comandi frequenti per il fornitore.
![]()
Premendo il pulsante Go Cisco – il pannello cambia nella Cisco Button Bar.

Esempi di utilizzo di script semplici e avanzati. (Pratica dalla vita reale.)
Gli script semplici sono sufficienti per quasi tutte le situazioni. Ma una volta ho avuto bisogno di complicare leggermente lo script per velocizzare il lavoro. Questo complicamento consisteva semplicemente nel richiedere dati aggiuntivi all'utente tramite una finestra di dialogo.
Richiesta di dati all'utente tramite finestra di dialogo
Nel mio script di richiesta di dati c'erano 2 elementi. Questi erano il Nome Host e il quarto ottetto dell'indirizzo IP. Per eseguire questa azione, ho cercato online come farlo e ho trovato sul sito ufficiale di SecureCRT (vandyke) una funzionalità chiamata prompt.
crt.Screen.WaitForString("-Vlanif200]")
hostnamestr = crt.Dialog.Prompt("Inserisci il nome host:", "hostname", "", False)
ipaddressstr = crt.Dialog.Prompt("Inserisci l'indirizzo IP:", "ip", "", False)
crt.Screen.Send("ip address 10.10.10.")
crt.Screen.Send(ipaddressstr)
crt.Screen.Send(" 23r")
crt.Screen.Send("quitr")
crt.Screen.Send("sysname ")
crt.Screen.Send(hostnamestr)
crt.Screen.Send("r")
Questa parte dello script richiedeva il Nome Host e i numeri dall'ultimo ottetto. Poiché c'erano 15 dispositivi e i dati erano presentati in una tabella, ho copiato i valori dalla tabella e li ho incollati nelle finestre di dialogo. Successivamente, lo script funzionava autonomamente.
Copia FTP su dispositivo di rete.
Questo script apriva una finestra di comando (shell) e copiava i dati tramite FTP. Al termine chiudeva la sessione. Non è possibile usare il blocco note per questo, poiché la copia è molto lenta e i dati nel buffer FTP non rimarranno per tutto quel tempo.
# $language = "Python"
# $interface = "1.0"
# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("ftp 192.168.1.1r")
crt.Screen.WaitForString("Name")
crt.Screen.Send("adminr")
crt.Screen.WaitForString("Password:")
crt.Screen.Send("Passwordr")
crt.Screen.WaitForString("ftp")
crt.Screen.Send("binaryr")
crt.Screen.WaitForString("ftp")
crt.Screen.Send("put S5720LI-V200R011SPH016.patr")
crt.Screen.WaitForString("ftp")
crt.Screen.Send("quitr")
crt.Screen.Synchronous = False
main()
Immissione di username/password tramite script
Un cliente aveva l'accesso diretto all'attrezzatura di rete bloccato. Si poteva accedere all'attrezzatura collegandosi prima al Gateway predefinito e da lì poi all'attrezzatura collegata. Per la connessione veniva utilizzato un client SSH integrato nell'IOS/software dell'attrezzatura. Di conseguenza, il nome utente e la password venivano richiesti nella console. Con lo script sottostante, il nome utente e la password venivano inseriti automaticamente:
# $language = "Python"
# $interface = "1.0"
# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("snmpadminr")
crt.Screen.WaitForString("assword:")
crt.Screen.Send("Passwordr")
crt.Screen.Synchronous = False
main()
Nota: C'erano 2 script. Uno per l'account amministratore, l'altro per l'account eSIGHT.
Script con la possibilità di aggiungere dati durante l'esecuzione dello script.
L'obiettivo era aggiungere un percorso statico su tutta l'attrezzatura di rete. Tuttavia, il gateway per Internet su ciascun dispositivo era diverso (e differente dal gateway predefinito). Il seguente script restituiva una tabella di routing, entrava in modalità di configurazione e scriveva parzialmente il comando (l'indirizzo IP del gateway per Internet) – questa parte la completavo io. Dopo aver premuto Invio, lo script continuava l'esecuzione del comando.
# $language = "Python"
# $interface = "1.0"
# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("Zdes-mogla-bit-vasha-reklamar")
crt.Screen.WaitForString("#")
crt.Screen.Send("show run | inc ip router")
crt.Screen.WaitForString("#")
crt.Screen.Send("conf tr")
crt.Screen.WaitForString("(config)#")
crt.Screen.Send("ip route 10.10.10.8 255.255.255.252 ")
crt.Screen.WaitForString("(config)#")
crt.Screen.Send("endr")
crt.Screen.WaitForString("#")
crt.Screen.Send("copy run star")
crt.Screen.WaitForString("[startup-config]?")
crt.Screen.Send("r")
crt.Screen.WaitForString("#")
crt.Screen.Send("exitr")
crt.Screen.Synchronous = False
main()
In questo script, nella riga: crt.Screen.Send(«ip route 10.10.10.8 255.255.255.252 „) l'indirizzo IP del gateway non è stato specificato e manca il carattere di ritorno a capo. Lo script attende l'apparizione della riga successiva con i caratteri «(config)#». Questi caratteri apparivano dopo che avevo inserito l'indirizzo IP e premuto invio.
Conclusione:
Quando si scrive e si esegue uno script, deve sempre essere rispettata la regola: Il tempo di scrittura e di esecuzione dello script non deve mai essere superiore al tempo teoricamente necessario per svolgere la stessa operazione manualmente (copia/incolla da un blocco note, scrittura e debugging di un playbook per Ansible, scrittura e debugging di uno script Python). In altre parole, l'uso dello script deve risparmiare tempo, non richiederne di più per un'automazione una tantum (cioè, quando lo script è unico e non ci saranno ulteriori ripetizioni). Tuttavia, se lo script è unico e l'automazione tramite lo script e la scrittura/debug dello script richiedono meno tempo rispetto all'esecuzione con qualsiasi altro metodo (Ansible, finestra dei comandi), allora lo script è la soluzione migliore.
Debugging dello script. Lo script cresce gradualmente; il debug avviene attraverso una fase di test sui primi tre dispositivi e con il quarto lo script sarà probabilmente completamente operativo.
L'esecuzione dello script (con l'inserimento di username e password) tramite mouse è generalmente più veloce del copia e incolla da un blocco note per Username e Password. Tuttavia, non è sicuro dal punto di vista della sicurezza.
Un altro esempio (reale) di utilizzo dello script: Non hai accesso diretto all'hardware di rete, ma è necessario configurare ulteriormente tutto l'hardware di rete (inserirlo nel sistema di monitoraggio, configurare username/password/addizionale snmpv3username/password). Hai accesso quando accedi allo switch Core, da cui apri SSH su altro hardware. Perché non utilizzare strumenti Ansible? — Perché ci scontriamo con il limite del numero di sessioni simultanee consentite sull'hardware di rete (line vty 0 4, user-interface vty 0 4) (un'altra questione è come in Ansible configurare diversi dispositivi con lo stesso SSH come primo hop).
Lo script riduce il tempo nelle operazioni prolungate, come il trasferimento di file tramite FTP. Una volta completato il trasferimento, lo script inizia a lavorare immediatamente. Una persona deve prima vedere il termine del trasferimento, poi rendersi conto che è finito e infine inserire i comandi corrispondenti. Lo script svolge tutto questo in modo oggettivamente più veloce.
Gli script sono utili quando non è possibile utilizzare strumenti di distribuzione dati di massa: Console. Oppure quando una parte dei dati per l'attrezzatura è unica: hostname, indirizzo IP di gestione. O quando scrivere un programma e fare il debug è più difficile che semplicemente estendere i dati ottenuti dall'attrezzatura durante l'esecuzione dello script. — Un esempio con uno script per la configurazione della rotta, dove ogni attrezzatura ha un proprio indirizzo IP fornito da un Internet provider. (I miei colleghi hanno scritto tali script quando i DMVPN spoke erano oltre trecento. Era necessario modificare le impostazioni del DMVPN).
Esempio dalla pratica: Assegnazione delle impostazioni iniziali su un nuovo switch tramite porte console:
A. Ho inserito il cavo della console nel dispositivo.
B. Ho avviato lo script.
C. Ho atteso il completamento dello script.
D. Ho scollegato il cavo della console nel successivo dispositivo.
D. Se lo switch non è l'ultimo, passare al punto B.
Risultato finale dell'esecuzione dello script:
- è stata impostata una password iniziale sul dispositivo.
- Username inserito
- è stato inserito un indirizzo IP univoco per il dispositivo.
P. S. è stata necessaria una ripetizione dell'operazione. Poiché per impostazione predefinita SSH non era configurato/spento. (Sì, è stato un mio errore.)
Fonti utilizzate.
1.
2.
Applicazione 1: Esempi di script.
Esempio di lungo script, con due richieste: Nome host e indirizzo IP. Creato per la configurazione iniziale dell'attrezzatura tramite console (9600 baud). E anche per la preparazione della connessione dell'attrezzatura alla rete.
# $language = "Python"
# $interface = "1.0"
# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("r")
crt.Screen.WaitForString("name")
crt.Screen.Send("adminr")
crt.Screen.WaitForString("Password:")
crt.Screen.Send("Passwordr")
crt.Screen.Send("sysr")
crt.Screen.WaitForString("]")
crt.Screen.Send("interface Vlanif 1r")
crt.Screen.WaitForString("Vlanif1]")
crt.Screen.Send("undo ip addressr")
crt.Screen.Send("shutdownr")
crt.Screen.Send("vlan 100r")
crt.Screen.Send(" description description1r")
crt.Screen.Send(" name description1r")
crt.Screen.Send("vlan 110r")
crt.Screen.Send(" description description2r")
crt.Screen.Send(" name description2r")
crt.Screen.Send("vlan 120r")
crt.Screen.Send(" description description3r")
crt.Screen.Send(" name description3r")
crt.Screen.Send("vlan 130r")
crt.Screen.Send(" description description4r")
crt.Screen.Send(" name description4r")
crt.Screen.Send("vlan 140r")
crt.Screen.Send(" description description5r")
crt.Screen.Send(" name description5r")
crt.Screen.Send("vlan 150r")
crt.Screen.Send(" description description6r")
crt.Screen.Send(" name description6r")
crt.Screen.Send("vlan 160r")
crt.Screen.Send(" description description7r")
crt.Screen.Send(" name description7r")
crt.Screen.Send("vlan 170r")
crt.Screen.Send(" description description8r")
crt.Screen.Send(" name description8r")
crt.Screen.Send("vlan 180r")
crt.Screen.Send(" description description9r")
crt.Screen.Send(" name description9r")
crt.Screen.Send("vlan 200r")
crt.Screen.Send(" description description10r")
crt.Screen.Send(" name description10r")
crt.Screen.Send("vlan 300r")
crt.Screen.Send(" description description11r")
crt.Screen.Send(" name description11r")
crt.Screen.Send("quitr")
crt.Screen.WaitForString("]")
crt.Screen.Send("stp region-configurationr")
crt.Screen.Send("region-name descr")
crt.Screen.Send("active region-configurationr")
crt.Screen.WaitForString("mst-region]")
crt.Screen.Send("quitr")
crt.Screen.Send("stp instance 0 priority 57344r")
crt.Screen.WaitForString("]")
crt.Screen.Send("interface range GigabitEthernet 0/0/1 to GigabitEthernet 0/0/42r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("description Usersr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port link-type hybridr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("voice-vlan 100 enabler")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("voice-vlan legacy enabler")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port hybrid pvid vlan 120r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port hybrid tagged vlan 100r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port hybrid untagged vlan 120r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("stp edged-port enabler")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("trust 8021pr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control action blockr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control enable trapr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("quitr")
crt.Screen.Send("interface range GigabitEthernet 0/0/43 to GigabitEthernet 0/0/48r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("description Printersr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port link-type accessr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port default vlan 130r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("stp edged-port enabler")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("trust 8021pr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control action blockr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control enable trapr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("quitr")
crt.Screen.Send("interface range XGigabitEthernet 0/0/1 to XGigabitEthernet 0/0/2r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("description uplinkr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port link-type trunkr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port trunk allow-pass vlan 100 110 120 130 140 150 160 170 180 200r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("port trunk allow-pass vlan 300r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control action blockr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("storm-control enable trapr")
crt.Screen.WaitForString("port-group]")
crt.Screen.Send("quitr")
crt.Screen.Send("ntp-service unicast-server 10.10.10.4r")
crt.Screen.Send("ntp-service unicast-server 10.10.10.2r")
crt.Screen.Send("ntp-service unicast-server 10.10.10.134r")
crt.Screen.Send("ip route-static 0.0.0.0 0.0.0.0 10.10.10.254r")
crt.Screen.Send("interface Vlanif 200r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
crt.Screen.Send("r")
crt.Screen.WaitForString("-Vlanif200]")
hostnamestr = crt.Dialog.Prompt("Enter hostname:", "hostname", "", False)
ipaddressstr = crt.Dialog.Prompt("Enter ip address:", "ip", "", False)
crt.Screen.Send("ip address 10.10.10.")
crt.Screen.Send(ipaddressstr)
crt.Screen.Send(" 24r")
crt.Screen.Send("quitr")
crt.Screen.Send("sysname ")
crt.Screen.Send(hostnamestr)
crt.Screen.Send("r")
crt.Screen.WaitForString("]")
crt.Screen.Synchronous = False
main()
Tali script di solito non sono necessari, ma il numero di attrezzature – 15 pezzi. Ha permesso di accelerare la configurazione. Successivamente, è stata più veloce la configurazione dell'attrezzatura utilizzando la finestra dei comandi di SecureCRT.
Configurazione dell'account per ssh.
Un altro esempio. Configurazione anche tramite console.
# $language = "Python"
# $interface = "1.0"
# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.
def main():
crt.Screen.Synchronous = True
crt.Screen.Send("r")
crt.Screen.WaitForString("name")
crt.Screen.Send("adminr")
crt.Screen.WaitForString("Password:")
crt.Screen.Send("Passwordr")
crt.Screen.WaitForString(">")
crt.Screen.Send("sysr")
crt.Screen.Send("stelnet server enabler")
crt.Screen.Send("aaar")
crt.Screen.Send("local-user admin service-type terminal ftp http sshr")
crt.Screen.Send("quitr")
crt.Screen.Send("user-interface vty 0 4r")
crt.Screen.Send("authentication-mode aaar")
crt.Screen.Send("quitr")
crt.Screen.Send("quitr")
crt.Screen.Synchronous = False
main()
Su SecureCRT:Software a pagamento: a partire da 99$ (il prezzo più basso per SecureCRT per un anno)
La licenza del software viene acquistata una sola volta, con supporto (per aggiornamenti), poi il software può essere utilizzato con questa licenza per un tempo illimitato.
Funziona su sistemi operativi Mac OS X e Windows.
C'è supporto per script (questo articolo)
Sì
Seriale/Telnet/SSH1/SSH2/Shell del sistema operativo
Fonte: habr.com
