Informazioni sugli ambiti
Breve descrizione
Viene illustrato il concetto di ambito in PowerShell e viene illustrato come impostare e modificare l'ambito degli elementi.
Descrizione lunga
PowerShell protegge l'accesso a variabili, alias, funzioni e unità PowerShell (PSDrive) limitando la posizione in cui possono essere letti e modificati. PowerShell usa le regole di ambito per assicurarsi di non modificare inavvertitamente un elemento che non deve essere modificato.
Di seguito sono riportate le regole di base dell'ambito:
Gli ambiti possono annidare. Un ambito esterno viene definito ambito padre. Gli ambiti annidati sono ambiti figlio di tale elemento padre.
Un elemento è visibile nell'ambito in cui è stato creato e in qualsiasi ambito figlio, a meno che non venga esplicitamente impostato come privato. È possibile inserire variabili, alias, funzioni o unità di PowerShell in uno o più ambiti.
Un elemento creato all'interno di un ambito può essere modificato solo nell'ambito in cui è stato creato, a meno che non si specifichi in modo esplicito un ambito diverso.
Se si crea un elemento in un ambito e l'elemento condivide il nome con un elemento in un ambito diverso, l'elemento originale potrebbe essere nascosto sotto il nuovo elemento, ma non viene sottoposto a override o modificato.
Ambiti di PowerShell
PowerShell supporta gli ambiti seguenti:
Globale: ambito attivo all'avvio di PowerShell. Variabili e funzioni presenti all'avvio di PowerShell nell'ambito globale, ad esempio variabili automatiche e variabili di preferenza. Anche le variabili, gli alias e le funzioni nei profili di PowerShell vengono create nell'ambito globale.
Local: ambito corrente. L'ambito locale può essere l'ambito globale o qualsiasi altro ambito.
Script: ambito creato durante l'esecuzione di un file script. Solo i comandi nello script vengono eseguiti nell'ambito dello script. Per i comandi in uno script, l'ambito dello script è l'ambito locale.
Nota
Private non è un ambito. È un'opzione che modifica la visibilità di un elemento all'esterno dell'ambito in cui è definito l'elemento.
Ambiti padre e figlio
È possibile creare un nuovo ambito eseguendo uno script o una funzione, creando una sessione o avviando una nuova istanza di PowerShell. Quando si crea un nuovo ambito, il risultato è un ambito padre (ambito originale) e un ambito figlio (ambito creato).
In PowerShell tutti gli ambiti sono ambiti figlio dell'ambito globale, ma è possibile creare molti ambiti e molti ambiti ricorsivi.
A meno che non si rendano esplicitamente privati gli elementi nell'ambito padre, gli elementi nell'ambito padre sono disponibili per l'ambito figlio. Tuttavia, gli elementi creati e modificati nell'ambito figlio non influiscono sull'ambito padre, a meno che non si specifichi in modo esplicito l'ambito quando si creano gli elementi.
Ereditarietà
Un ambito figlio non eredita le variabili, gli alias e le funzioni dall'ambito padre. A meno che un elemento non sia privato, l'ambito figlio può visualizzare gli elementi nell'ambito padre. Inoltre, può modificare gli elementi specificando in modo esplicito l'ambito padre, ma gli elementi non fanno parte dell'ambito figlio.
Tuttavia, viene creato un ambito figlio con un set di elementi. In genere, include tutti gli alias con l'opzione AllScope . Questa opzione è illustrata più avanti in questo articolo. Include tutte le variabili con l'opzione AllScope , oltre ad alcune variabili automatiche.
Per trovare gli elementi in un ambito specifico, usare il parametro Scope di Get-Variable
o Get-Alias
.
Ad esempio, per ottenere tutte le variabili nell'ambito locale, digitare:
Get-Variable -Scope local
Per ottenere tutte le variabili nell'ambito globale, digitare:
Get-Variable -Scope global
Modificatori di ambito
Una variabile, un alias o un nome di funzione può includere uno dei modificatori di ambito facoltativi seguenti:
global:
- Specifica che il nome esiste nell'ambito globale .local:
- Specifica che il nome esiste nell'ambito Locale . L'ambito corrente è sempre l'ambito Locale .private:
- Specifica che il nome è Privato e visibile solo all'ambito corrente.script:
- Specifica che il nome esiste nell'ambito script . L'ambito dello script è l'ambito del file di script predecessore più vicino o globale se non è presente alcun file di script predecessore più vicino.using:
- Usato per accedere alle variabili definite in un altro ambito durante l'esecuzione di script tramite cmdlet comeStart-Job
eInvoke-Command
.workflow:
- Specifica che il nome esiste all'interno di un flusso di lavoro. Nota: i flussi di lavoro non sono supportati in PowerShell Core.<variable-namespace>
- Modificatore creato da un provider PSDrive di PowerShell. Ad esempio:Spazio dei nomi Descrizione Alias:
Alias definiti nell'ambito corrente Env:
Variabili di ambiente definite nell'ambito corrente Function:
Funzioni definite nell'ambito corrente Variable:
Variabili definite nell'ambito corrente
L'ambito predefinito per gli script è l'ambito dello script. L'ambito predefinito per funzioni e alias è l'ambito locale, anche se sono definiti in uno script.
Uso dei modificatori di ambito
Per specificare l'ambito di una nuova variabile, un alias o una funzione, usare un modificatore di ambito.
La sintassi per un modificatore di ambito in una variabile è:
$[<scope-modifier>:]<name> = <value>
La sintassi per un modificatore di ambito in una funzione è:
function [<scope-modifier>:]<name> {<function-body>}
Il comando seguente, che non usa un modificatore di ambito, crea una variabile nell'ambito corrente o locale :
$a = "one"
Per creare la stessa variabile nell'ambito globale , usare il modificatore di ambito global:
:
$global:a = "one"
Per creare la stessa variabile nell'ambito dello script , usare il script:
modificatore di ambito:
$script:a = "one"
È anche possibile usare un modificatore di ambito con funzioni. La definizione di funzione seguente crea una funzione nell'ambito globale :
function global:Hello {
Write-Host "Hello, World"
}
È anche possibile usare i modificatori di ambito per fare riferimento a una variabile in un ambito diverso.
Il comando seguente fa riferimento alla $test
variabile, prima nell'ambito locale e quindi nell'ambito globale:
$test
$global:test
Modificatore dell'ambito Using:
Using è un modificatore di ambito speciale che identifica una variabile locale in un comando remoto. Senza un modificatore, PowerShell prevede che le variabili nei comandi remoti vengano definite nella sessione remota.
Il modificatore Using scope è stato introdotto in PowerShell 3.0.
Per altre informazioni, vedere about_Remote_Variables.
Opzione AllScope
Le variabili e gli alias hanno una proprietà Option che può accettare il valore AllScope. Gli elementi con la proprietà AllScope diventano parte di tutti gli ambiti figlio creati, anche se non vengono ereditati retroattivamente dagli ambiti padre.
Un elemento con la proprietà AllScope è visibile nell'ambito figlio e fa parte di tale ambito. Le modifiche apportate all'elemento in qualsiasi ambito influiscono su tutti gli ambiti in cui è definita la variabile.
Gestione dell'ambito
Diversi cmdlet hanno un parametro Scope che consente di ottenere o impostare (creare e modificare) elementi in un determinato ambito. Usare il comando seguente per trovare tutti i cmdlet nella sessione con un parametro Scope :
Get-Help * -Parameter scope
Per trovare le variabili visibili in un determinato ambito, usare il Scope
parametro di Get-Variable
. Le variabili visibili includono variabili globali, variabili nell'ambito padre e variabili nell'ambito corrente.
Ad esempio, il comando seguente ottiene le variabili visibili nell'ambito locale:
Get-Variable -Scope local
Per creare una variabile in un particolare ambito, usare un modificatore di ambito o il parametro Scope di Set-Variable
. Il comando seguente crea una variabile nell'ambito globale:
New-Variable -Scope global -Name a -Value "One"
È anche possibile usare il parametro Scope dei New-Alias
cmdlet , Set-Alias
o Get-Alias
per specificare l'ambito. Il comando seguente crea un alias nell'ambito globale:
New-Alias -Scope global -Name np -Value Notepad.exe
Per ottenere le funzioni in un determinato ambito, usare il Get-Item
cmdlet quando si è nell'ambito. Il Get-Item
cmdlet non ha un parametro Scope .
Nota
Per i cmdlet che usano il parametro Scope , è anche possibile fare riferimento agli ambiti per numero. Il numero descrive la posizione relativa di un ambito a un altro. L'ambito 0 rappresenta l'ambito corrente, o locale. L'ambito 1 indica l'ambito padre immediato. L'ambito 2 indica l'elemento padre dell'ambito padre e così via. Gli ambiti numerati sono utili se sono stati creati molti ambiti ricorsivi.
Uso della notazione origine punto con ambito
Gli script e le funzioni seguono tutte le regole dell'ambito. Vengono creati in un particolare ambito e influiscono solo su tale ambito, a meno che non si usi un parametro cmdlet o un modificatore di ambito per modificare tale ambito.
È tuttavia possibile aggiungere uno script o una funzione all'ambito corrente usando la notazione dell'origine punto. Quindi, quando uno script viene eseguito nell'ambito corrente, tutte le funzioni, gli alias e le variabili creati dallo script sono disponibili nell'ambito corrente.
Per aggiungere una funzione all'ambito corrente, digitare un punto (.) e uno spazio prima del percorso e del nome della funzione nella chiamata di funzione.
Ad esempio, per eseguire lo script Sample.ps1 dalla directory C:\Scripts nell'ambito dello script (impostazione predefinita per gli script), usare il comando seguente:
c:\scripts\sample.ps1
Per eseguire lo script Sample.ps1 nell'ambito locale, usare il comando seguente:
. c:\scripts.sample.ps1
Quando si usa l'operatore di chiamata (&) per eseguire una funzione o uno script, non viene aggiunto all'ambito corrente. Nell'esempio seguente viene usato l'operatore di chiamata:
& c:\scripts.sample.ps1
Per altre informazioni sull'operatore di chiamata, vedere about_operators.
Gli alias, le funzioni o le variabili creati dallo script Sample.ps1 non sono disponibili nell'ambito corrente.
Limitazione senza ambito
Alcuni concetti di PowerShell sono simili all'ambito o all'interazione con l'ambito. Questi concetti possono essere confusi con l'ambito o il comportamento dell'ambito.
Sessioni, moduli e prompt annidati sono ambienti autonomi, ma non sono ambiti figlio dell'ambito globale nella sessione.
Sessioni
Una sessione è un ambiente in cui viene eseguito PowerShell. Quando si crea una sessione in un computer remoto, PowerShell stabilisce una connessione permanente al computer remoto. La connessione permanente consente di usare la sessione per più comandi correlati.
Poiché una sessione è un ambiente indipendente, ha un proprio ambito, ma una sessione non è un ambito figlio della sessione in cui è stata creata. La sessione inizia con il proprio ambito globale. Questo ambito è indipendente dall'ambito globale della sessione. È possibile creare ambiti figlio nella sessione. Ad esempio, è possibile eseguire uno script per creare un ambito figlio in una sessione.
Moduli
È possibile usare un modulo di PowerShell per condividere e distribuire strumenti di PowerShell. Un modulo è un'unità che può contenere cmdlet, script, funzioni, variabili, alias e altri elementi utili. A meno che non venga definito in modo esplicito, gli elementi di un modulo non sono accessibili all'esterno del modulo. È quindi possibile aggiungere il modulo alla sessione e usare gli elementi pubblici senza preoccuparsi che gli altri elementi possano eseguire l'override dei cmdlet, degli script, delle funzioni e di altri elementi della sessione.
La privacy di un modulo si comporta come un ambito, ma l'aggiunta di un modulo a una sessione non modifica l'ambito. Inoltre, il modulo non ha un proprio ambito, anche se gli script nel modulo, come tutti gli script di PowerShell, hanno un proprio ambito.
Per impostazione predefinita, i moduli vengono caricati nel livello superiore dello stato della sessione corrente non nell'ambito corrente. Può trattarsi di uno stato di sessione del modulo o dello stato della sessione globale. Se si è nell'ambito globale, i moduli vengono caricati nello stato della sessione globale. Le esportazioni vengono inserite nelle tabelle globali.
Se si carica module2 dall'interno di module1, module2 viene caricato nello stato sessione di module1, non nello stato della sessione globale. Qualsiasi esportazione da module2 viene inserita nella parte superiore dello stato della sessione di module1. Se si usa Import-Module -Scope local
, le esportazioni vengono inserite nell'oggetto ambito corrente anziché al livello superiore. Se si usa un modulo e si usa Import-Module -Scope global
(o Import-Module -Global
) per caricare un altro modulo, tale modulo e le esportazioni vengono caricate nello stato della sessione globale anziché nello stato della sessione locale del modulo. Questa funzionalità è stata progettata per la scrittura di moduli che modificano i moduli. Il modulo WindowsCompatibility esegue questa operazione per importare i moduli proxy nell'ambito globale.
Richieste annidate
Analogamente, le richieste annidate non hanno un proprio ambito. Quando si immette un prompt annidato, il prompt annidato è un subset dell'ambiente. Tuttavia, si rimane all'interno dell'ambito locale.
Gli script hanno un proprio ambito. Se si esegue il debug di uno script e si raggiunge un punto di interruzione nello script, immettere l'ambito dello script.
Opzione privata
Gli alias e le variabili hanno una proprietà Option che può accettare un valore Private. Gli elementi con l'opzione Private possono essere visualizzati e modificati nell'ambito in cui vengono creati, ma non possono essere visualizzati o modificati all'esterno di tale ambito.
Ad esempio, se si crea una variabile con un'opzione privata nell'ambito globale e quindi si esegue uno script, Get-Variable
i comandi nello script non visualizzano la variabile privata. L'uso del modificatore di ambito globale in questa istanza non visualizza la variabile privata.
È possibile usare il parametro Option dei New-Variable
cmdlet , Set-Variable
, New-Alias
e Set-Alias
per impostare il valore della proprietà Option su Private.
Visibilità
La proprietà Visibility di una variabile o di un alias determina se è possibile visualizzare l'elemento all'esterno del contenitore, in cui è stato creato. Un contenitore può essere un modulo, uno script o uno snap-in. La visibilità è progettata per i contenitori nello stesso modo in cui il valore Privato della proprietà Option è progettato per gli ambiti.
La proprietà Visibility accetta i valori Public e Private . Gli elementi con visibilità privata possono essere visualizzati e modificati solo nel contenitore in cui sono stati creati. Se il contenitore viene aggiunto o importato, gli elementi con visibilità privata non possono essere visualizzati o modificati.
Poiché la visibilità è progettata per i contenitori, funziona in modo diverso in un ambito.
- Se si crea un elemento con visibilità privata nell'ambito globale, non è possibile visualizzare o modificare l'elemento in alcun ambito.
- Se si tenta di visualizzare o modificare il valore di una variabile con visibilità privata, PowerShell restituisce un messaggio di errore.
È possibile usare i New-Variable
cmdlet e Set-Variable
per creare una variabile con visibilità privata.
Esempio
Esempio 1: Modificare un valore variabile solo in uno script
Il comando seguente modifica il valore della $ConfirmPreference
variabile in uno script. La modifica non influisce sull'ambito globale.
Per visualizzare prima di tutto il valore della $ConfirmPreference
variabile nell'ambito locale, usare il comando seguente:
PS> $ConfirmPreference
High
Create uno script di Scope.ps1 che contiene i comandi seguenti:
$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."
Eseguire lo script. Lo script modifica il valore della $ConfirmPreference
variabile e quindi ne segnala il valore nell'ambito dello script. L'output dovrebbe essere simile all'output seguente:
The value of $ConfirmPreference is Low.
Testare quindi il valore corrente della $ConfirmPreference
variabile nell'ambito corrente.
PS> $ConfirmPreference
High
Questo esempio mostra che le modifiche apportate al valore di una variabile nell'ambito dello script non influiscono sul valore della variabile nell'ambito padre.
Esempio 2: Visualizzare un valore di variabile in ambiti diversi
È possibile usare i modificatori di ambito per visualizzare il valore di una variabile nell'ambito locale e in un ambito padre.
Definire prima di tutto una $test
variabile nell'ambito globale.
$test = "Global"
Creare quindi uno script Sample.ps1 che definisce la $test
variabile. Nello script usare un modificatore di ambito per fare riferimento alle versioni globali o locali della $test
variabile.
In Sample.ps1:
$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."
Quando si esegue Sample.ps1, l'output dovrebbe essere simile all'output seguente:
The local value of $test is Local.
The global value of $test is Global.
Al termine dello script, nella sessione viene definito solo il valore globale di $test
.
PS> $test
Global
Esempio 3: Modificare il valore di una variabile in un ambito padre
A meno che non si protegga un elemento usando l'opzione Private o un altro metodo, è possibile visualizzare e modificare il valore di una variabile in un ambito padre.
Definire prima di tutto una $test
variabile nell'ambito globale.
$test = "Global"
Creare quindi uno script Sample.ps1 che definisce la $test
variabile. Nello script usare un modificatore di ambito per fare riferimento alle versioni globali o locali della $test
variabile.
In Sample.ps1:
$global:test = "Local"
"The global value of `$test is $global:test."
Al termine dello script, il valore globale di $test
viene modificato.
PS> $test
Local
Esempio 4: Creazione di una variabile privata
Una variabile privata è una variabile con una proprietà Option con valore Private. Le variabili private vengono ereditate dall'ambito figlio, ma possono essere visualizzate o modificate solo nell'ambito in cui sono state create.
Il comando seguente crea una variabile privata denominata $ptest
nell'ambito locale.
New-Variable -Name ptest -Value 1 -Option private
È possibile visualizzare e modificare il valore di $ptest
nell'ambito locale.
PS> $ptest
1
PS> $ptest = 2
PS> $ptest
2
Creare quindi uno script Sample.ps1 contenente i comandi seguenti. Il comando tenta di visualizzare e modificare il valore di $ptest
.
In Sample.ps1:
"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."
La $ptest
variabile non è visibile nell'ambito dello script, l'output è vuoto.
"The value of $Ptest is ."
"The value of $Ptest is ."
Esempio 5: Uso di una variabile locale in un comando remoto
Per le variabili in un comando remoto creato nella sessione locale, usare il Using
modificatore di ambito. PowerShell presuppone che le variabili nei comandi remoti siano state create nella sessione remota.
La sintassi è:
$Using:<VariableName>
Ad esempio, i comandi seguenti creano una $Cred
variabile nella sessione locale e quindi usano la $Cred
variabile in un comando remoto:
$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}
L'ambito Using è stato introdotto in PowerShell 3.0. In PowerShell 2.0, per indicare che una variabile è stata creata nella sessione locale, usare il formato di comando seguente.
$Cred = Get-Credential
Invoke-Command $s {
param($c)
Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred