about_Scopes

Deskripsi singkat

Menjelaskan konsep cakupan di PowerShell dan menunjukkan cara mengatur dan mengubah cakupan elemen.

Deskripsi panjang

PowerShell melindungi akses ke variabel, alias, fungsi, dan drive PowerShell (PSDrives) dengan membatasi tempat mereka dapat dibaca dan diubah. PowerShell menggunakan aturan cakupan untuk memastikan bahwa Anda tidak secara tidak sengaja mengubah item yang tidak boleh diubah.

Berikut ini adalah aturan dasar cakupan:

  • Cakupan mungkin bersarang. Cakupan luar disebut sebagai cakupan induk. Cakupan berlapis apa pun adalah cakupan anak dari induk tersebut.

  • Item terlihat dalam cakupan tempat item dibuat dan dalam cakupan anak apa pun, kecuali Anda secara eksplisit menjadikannya privat.

  • Anda dapat mendeklarasikan variabel, alias, fungsi, dan drive PowerShell untuk cakupan di luar cakupan saat ini.

  • Item yang Anda buat dalam cakupan hanya dapat diubah dalam cakupan tempat item dibuat, kecuali Anda secara eksplisit menentukan cakupan yang berbeda.

Jika Anda membuat item dalam cakupan, dan item berbagi namanya dengan item dalam cakupan yang berbeda, item asli mungkin disembunyikan di bawah item baru, tetapi tidak ditimpa atau diubah.

Cakupan PowerShell

PowerShell mendukung cakupan berikut:

  • Global: Cakupan yang berlaku saat PowerShell dimulai atau saat Anda membuat sesi atau runspace baru. Variabel dan fungsi yang ada saat PowerShell dimulai telah dibuat dalam cakupan global, seperti variabel otomatis dan variabel preferensi. Variabel, alias, dan fungsi di profil PowerShell Anda juga dibuat dalam cakupan global. Cakupan global adalah cakupan induk akar dalam sesi.

  • Lokal: Cakupan saat ini. Cakupan lokal dapat menjadi cakupan global atau cakupan lainnya.

  • Skrip: Cakupan yang dibuat saat file skrip berjalan. Hanya perintah dalam skrip yang dijalankan dalam cakupan skrip. Untuk perintah dalam skrip, cakupan skrip adalah cakupan lokal.

Cakupan Induk dan Anak

Anda dapat membuat cakupan anak baru dengan memanggil skrip atau fungsi. Cakupan panggilan adalah cakupan induk. Skrip atau fungsi yang disebut adalah cakupan anak. Fungsi atau skrip yang Anda panggil dapat memanggil fungsi lain, membuat hierarki cakupan anak yang cakupan akarnya adalah cakupan global.

Kecuali Anda secara eksplisit membuat item menjadi privat, item dalam cakupan induk tersedia untuk cakupan anak. Namun, item yang Anda buat dan ubah dalam cakupan anak tidak memengaruhi cakupan induk, kecuali Anda secara eksplisit menentukan cakupan saat Membuat item.

Catatan

Fungsi dari modul tidak berjalan dalam cakupan anak dari cakupan panggilan. Modul memiliki status sesi mereka sendiri yang ditautkan ke cakupan global. Semua kode modul berjalan dalam hierarki cakupan khusus modul yang memiliki cakupan akarnya sendiri.

Warisan

Cakupan anak tidak mewarisi variabel, alias, dan fungsi dari cakupan induk. Kecuali item bersifat privat, cakupan anak dapat melihat item dalam lingkup induk. Dan, ini dapat mengubah item dengan secara eksplisit menentukan cakupan induk, tetapi item bukan bagian dari cakupan anak.

Namun, cakupan anak dibuat dengan sekumpulan item. Biasanya, ini mencakup semua alias yang memiliki opsi AllScope . Opsi ini dibahas nanti dalam artikel ini. Ini termasuk semua variabel yang memiliki opsi AllScope , ditambah beberapa variabel otomatis.

Untuk menemukan item dalam cakupan tertentu, gunakan parameter Get-Variable Cakupan atau Get-Alias.

Misalnya, untuk mendapatkan semua variabel dalam cakupan lokal, ketik:

Get-Variable -Scope local

Untuk mendapatkan semua variabel dalam cakupan global, ketik:

Get-Variable -Scope global

Pengubah Cakupan

Variabel, alias, atau nama fungsi dapat menyertakan salah satu pengubah cakupan opsional berikut:

  • global: - Menentukan bahwa nama ada dalam cakupan Global .

  • local: - Menentukan bahwa nama ada dalam cakupan Lokal . Cakupan saat ini selalu merupakan Cakupan lokal .

  • private: - Menentukan bahwa namanya Privat dan hanya terlihat oleh cakupan saat ini.

    Catatan

    private bukan cakupan. Ini adalah opsi yang mengubah visibilitas item di luar lingkup tempat item ditentukan.

  • script: - Menentukan bahwa nama ada dalam cakupan Skrip . Cakupan skrip adalah cakupan file skrip leluhur terdekat atau Global jika tidak ada file skrip leluhur terdekat.

  • using: - Digunakan untuk mengakses variabel yang ditentukan dalam cakupan lain saat menjalankan skrip melalui cmdlet seperti Start-Job dan Invoke-Command.

  • workflow: - Menentukan bahwa nama ada dalam alur kerja. Catatan: Alur kerja tidak didukung di PowerShell v6 dan yang lebih tinggi.

  • <variable-namespace> - Pengubah yang dibuat oleh penyedia PowerShell PSDrive. Contohnya:

    Ruang nama Deskripsi
    Alias: Alias yang ditentukan dalam cakupan saat ini
    Env: Variabel lingkungan yang ditentukan dalam cakupan saat ini
    Function: Fungsi yang ditentukan dalam cakupan saat ini
    Variable: Variabel yang ditentukan dalam cakupan saat ini

Cakupan default untuk skrip adalah cakupan skrip. Cakupan default untuk fungsi dan alias adalah cakupan lokal, bahkan jika didefinisikan dalam skrip.

Menggunakan pengubah cakupan

Untuk menentukan cakupan variabel, alias, atau fungsi baru, gunakan pengubah cakupan.

Sintaks untuk pengubah cakupan dalam variabel adalah:

$[<scope-modifier>:]<name> = <value>

Sintaks untuk pengubah cakupan dalam fungsi adalah:

function [<scope-modifier>:]<name> {<function-body>}

Perintah berikut, yang tidak menggunakan pengubah cakupan, membuat variabel dalam cakupan saat ini atau lokal :

$a = "one"

Untuk membuat variabel yang sama dalam cakupan global , gunakan pengubah cakupan global: :

$global:a = "one"
Get-Variable a | Format-List *

Perhatikan nilai properti Visibilitas dan Opsi .

Name        : a
Description :
Value       : one
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

Bandingkan dengan variabel privat:

$private:pVar = 'Private variable'
Get-Variable pVar | Format-List *

Menggunakan pengubah private cakupan mengatur properti Opsi ke Private.

Name        : pVar
Description :
Value       : Private variable
Visibility  : Public
Module      :
ModuleName  :
Options     : Private
Attributes  : {}

Untuk membuat variabel yang sama dalam cakupan skrip , gunakan pengubah script: cakupan:

$script:a = "one"

Anda juga dapat menggunakan pengubah cakupan dengan fungsi. Definisi fungsi berikut membuat fungsi dalam lingkup global :

function global:Hello {
  Write-Host "Hello, World"
}

Anda juga dapat menggunakan pengubah cakupan untuk merujuk ke variabel dalam cakupan yang berbeda. Perintah berikut mengacu pada $test variabel , pertama-tama dalam cakupan lokal lalu dalam cakupan global:

$test
$global:test

Pengubah cakupan Using:

Menggunakan adalah pengubah cakupan khusus yang mengidentifikasi variabel lokal dalam perintah jarak jauh. Tanpa pengubah, PowerShell mengharapkan variabel dalam perintah jarak jauh ditentukan dalam sesi jarak jauh.

Pengubah Using cakupan diperkenalkan di PowerShell 3.0.

Untuk skrip atau perintah apa pun yang dijalankan di luar sesi, Anda memerlukan Using pengubah cakupan untuk menyematkan nilai variabel dari cakupan sesi panggilan, sehingga kode di luar sesi dapat mengaksesnya. Pengubah Using cakupan didukung dalam konteks berikut:

  • Perintah yang dijalankan dari jarak jauh, dimulai dengan Invoke-Command menggunakan parameter ComputerName, HostName, SSHConnection , atau Sesi (sesi jarak jauh)
  • Pekerjaan latar belakang, dimulai dengan Start-Job (sesi di luar proses)
  • Pekerjaan utas, dimulai melalui Start-ThreadJob atau ForEach-Object -Parallel (sesi utas terpisah)

Bergantung pada konteksnya, nilai variabel yang disematkan adalah salinan independen dari data dalam cakupan pemanggil atau referensi ke dalamnya. Dalam sesi jarak jauh dan di luar proses, mereka selalu merupakan salinan independen.

Untuk informasi selengkapnya, lihat about_Remote_Variables.

Dalam sesi utas, mereka diteruskan oleh referensi. Ini berarti dimungkinkan untuk memodifikasi variabel cakupan panggilan dalam utas yang berbeda. Untuk memodifikasi variabel dengan aman memerlukan sinkronisasi utas.

Untuk informasi selengkapnya, lihat:

Serialisasi nilai variabel

Perintah yang dijalankan dari jarak jauh dan pekerjaan latar belakang berjalan di luar proses. Sesi di luar proses menggunakan serialisasi dan deserialisasi berbasis XML untuk membuat nilai variabel tersedia di seluruh batas proses. Proses serialisasi mengonversi objek menjadi PSObject yang berisi properti objek asli tetapi bukan metodenya.

Untuk sekumpulan jenis terbatas, deserialisasi merehidrasi objek kembali ke jenis aslinya. Objek yang direhidrasi adalah salinan instans objek asli. Ini memiliki jenis properti dan metode. Untuk jenis sederhana, seperti System.Version, salinannya tepat. Untuk jenis kompleks, salinannya tidak sempurna. Misalnya, objek sertifikat yang direhidrasi tidak menyertakan kunci privat.

Instans dari semua jenis lainnya adalah instans PSObject . Properti PSTypeNames berisi nama jenis asli yang diawali dengan Deserialized, misalnya, Deserialized.System.Data.DataTable

Opsi AllScope

Variabel dan alias memiliki properti Opsi yang dapat mengambil nilai AllScope. Item yang memiliki properti AllScope menjadi bagian dari cakupan anak apa pun yang Anda buat, meskipun tidak diwarisi secara retroaktif oleh cakupan induk.

Item yang memiliki properti AllScope terlihat dalam cakupan anak, dan merupakan bagian dari cakupan tersebut. Perubahan pada item dalam cakupan apa pun memengaruhi semua cakupan di mana variabel ditentukan.

Mengelola Cakupan

Beberapa cmdlet memiliki parameter Cakupan yang memungkinkan Anda mendapatkan atau mengatur (membuat dan mengubah) item dalam cakupan tertentu. Gunakan perintah berikut untuk menemukan semua cmdlet dalam sesi Anda yang memiliki parameter Cakupan :

Get-Help * -Parameter scope

Untuk menemukan variabel yang terlihat dalam cakupan tertentu, gunakan Scope parameter .Get-Variable Variabel yang terlihat termasuk variabel global, variabel dalam lingkup induk, dan variabel dalam cakupan saat ini.

Misalnya, perintah berikut mendapatkan variabel yang terlihat dalam cakupan lokal:

Get-Variable -Scope local

Untuk membuat variabel dalam cakupan tertentu, gunakan pengubah cakupan atau parameter Cakupan .Set-Variable Perintah berikut membuat variabel dalam lingkup global:

New-Variable -Scope global -Name a -Value "One"

Anda juga dapat menggunakan parameter Cakupan cmdlet New-Alias, , Set-Aliasatau Get-Alias untuk menentukan cakupan. Perintah berikut membuat alias dalam lingkup global:

New-Alias -Scope global -Name np -Value Notepad.exe

Untuk mendapatkan fungsi dalam cakupan tertentu, gunakan Get-Item cmdlet saat Anda berada dalam cakupan. Get-Item Cmdlet tidak memiliki parameter Cakupan.

Catatan

Untuk cmdlet yang menggunakan parameter Cakupan , Anda juga dapat merujuk ke cakupan menurut angka. Angka tersebut menjelaskan posisi relatif satu cakupan ke cakupan lainnya. Cakupan 0 mewakili cakupan saat ini, atau lokal. Cakupan 1 menunjukkan cakupan induk langsung. Cakupan 2 menunjukkan induk cakupan induk, dan sebagainya. Cakupan bernomor berguna jika Anda telah membuat banyak cakupan rekursif.

Menggunakan Notasi Sumber Titik dengan Cakupan

Skrip dan fungsi mengikuti semua aturan cakupan. Anda membuatnya dalam cakupan tertentu, dan hanya memengaruhi cakupan tersebut kecuali Anda menggunakan parameter cmdlet atau pengubah cakupan untuk mengubah cakupan tersebut.

Tetapi, Anda dapat menambahkan skrip atau fungsi ke cakupan saat ini dengan menggunakan notasi sumber titik. Kemudian, ketika skrip berjalan dalam cakupan saat ini, fungsi, alias, dan variabel apa pun yang dibuat skrip tersedia dalam cakupan saat ini.

Untuk menambahkan fungsi ke cakupan saat ini, ketik titik (.) dan spasi sebelum jalur dan nama fungsi dalam panggilan fungsi.

Misalnya, untuk menjalankan skrip Sample.ps1 dari direktori C:\Scripts dalam lingkup skrip (default untuk skrip), gunakan perintah berikut:

c:\scripts\sample.ps1

Untuk menjalankan skrip Sample.ps1 dalam cakupan lokal, gunakan perintah berikut:

. c:\scripts.sample.ps1

Saat Anda menggunakan operator panggilan (&) untuk menjalankan fungsi atau skrip, operator panggilan tidak ditambahkan ke cakupan saat ini. Contoh berikut menggunakan operator panggilan:

& c:\scripts.sample.ps1

Anda dapat membaca selengkapnya tentang operator panggilan di about_operators.

Alias, fungsi, atau variabel apa pun yang dibuat skrip Sample.ps1 tidak tersedia dalam cakupan saat ini.

Membatasi Tanpa Cakupan

Beberapa konsep PowerShell mirip dengan cakupan atau berinteraksi dengan cakupan. Konsep-konsep ini mungkin bingung dengan cakupan atau perilaku cakupan.

Sesi, modul, dan perintah berlapis adalah lingkungan mandiri, tetapi bukan cakupan anak dari cakupan global dalam sesi tersebut.

Sesi

Sesi adalah lingkungan tempat PowerShell berjalan. Saat Anda membuat sesi di komputer jarak jauh, PowerShell membuat koneksi persisten ke komputer jarak jauh. Koneksi persisten memungkinkan Anda menggunakan sesi untuk beberapa perintah terkait.

Karena sesi adalah lingkungan yang terkandung, sesi memiliki cakupannya sendiri, tetapi sesi bukanlah cakupan anak dari sesi tempat sesi dibuat. Sesi dimulai dengan cakupan globalnya sendiri. Cakupan ini independen dari cakupan global sesi. Anda dapat membuat cakupan anak dalam sesi. Misalnya, Anda dapat menjalankan skrip untuk membuat cakupan anak dalam sesi.

Modul

Anda dapat menggunakan modul PowerShell untuk berbagi dan mengirimkan alat PowerShell. Modul adalah unit yang dapat berisi cmdlet, skrip, fungsi, variabel, alias, dan item berguna lainnya. Kecuali ditentukan secara eksplisit, item dalam modul tidak dapat diakses di luar modul. Oleh karena itu, Anda dapat menambahkan modul ke sesi Anda dan menggunakan item publik tanpa khawatir bahwa item lain mungkin mengambil alih cmdlet, skrip, fungsi, dan item lainnya dalam sesi Anda.

Secara default, modul dimuat ke tingkat atas status sesi saat ini bukan cakupan saat ini. Status sesi saat ini bisa menjadi status sesi modul atau status sesi global. Menambahkan modul ke sesi tidak mengubah cakupan. Jika Anda berada dalam cakupan global, maka modul dimuat ke dalam status sesi global. Setiap ekspor ditempatkan ke dalam tabel global. Jika Anda memuat modul2 dari dalam module1, module2 dimuat ke dalam status sesi module1 bukan status sesi global. Setiap ekspor dari module2 ditempatkan di bagian atas status sesi module1. Jika Anda menggunakan Import-Module -Scope local, maka ekspor ditempatkan ke dalam objek cakupan saat ini daripada di tingkat atas. Jika Anda berada dalam modul dan menggunakan Import-Module -Scope global (atau Import-Module -Global) untuk memuat modul lain, modul tersebut dan ekspornya dimuat ke dalam status sesi global alih-alih status sesi lokal modul. Fitur ini dirancang untuk menulis modul yang memanipulasi modul. Modul WindowsCompatibility melakukan ini untuk mengimpor modul proksi ke status sesi global.

Dalam status sesi, modul memiliki cakupannya sendiri. Pertimbangkan modul C:\temp\mod1.psm1berikut:

$a = "Hello"

function foo {
    "`$a = $a"
    "`$global:a = $global:a"
}

Sekarang kita membuat variabel $aglobal , memberinya nilai dan memanggil fungsi foo.

$a = "Goodbye"
foo

Modul mendeklarasikan variabel $a dalam cakupan modul, kemudian fungsi foo menghasilkan nilai variabel di kedua cakupan.

$a = Hello
$global:a = Goodbye

Perintah Berlapis

Perintah berlapis tidak memiliki cakupannya sendiri. Saat Anda memasukkan perintah berlapis, perintah berlapis adalah subset lingkungan. Tapi, Anda tetap dalam cakupan lokal.

Skrip memang memiliki cakupannya sendiri. Jika Anda men-debug skrip, dan mencapai titik henti dalam skrip, Anda memasukkan cakupan skrip.

Opsi Privat

Alias dan variabel memiliki properti Opsi yang dapat mengambil nilai Private. Item yang memiliki Private opsi dapat dilihat dan diubah dalam cakupan tempat item dibuat, tetapi tidak dapat dilihat atau diubah di luar cakupan tersebut.

Misalnya, jika Anda membuat variabel yang memiliki opsi privat dalam lingkup global lalu menjalankan skrip, Get-Variable perintah dalam skrip tidak menampilkan variabel privat. Menggunakan pengubah cakupan global dalam instans ini tidak menampilkan variabel privat.

Anda dapat menggunakan parameter Opsi cmdlet New-Variable, , New-AliasSet-Variable, dan Set-Alias untuk mengatur nilai properti Opsi ke Privat.

Visibilitas

Properti Visibilitas variabel atau alias menentukan apakah Anda dapat melihat item di luar kontainer, tempat item dibuat. Kontainer bisa berupa modul, skrip, atau snap-in. Visibilitas dirancang untuk kontainer dengan cara yang Private sama seperti nilai properti Option dirancang untuk cakupan.

Properti Visibilitas mengambil Public nilai dan Private . Item yang memiliki visibilitas privat hanya dapat dilihat dan diubah dalam kontainer tempat item dibuat. Jika kontainer ditambahkan atau diimpor, item yang memiliki visibilitas privat tidak dapat dilihat atau diubah.

Karena visibilitas dirancang untuk kontainer, ia bekerja secara berbeda dalam cakupan.

  • Jika Anda membuat item yang memiliki visibilitas privat dalam lingkup global, Anda tidak dapat melihat atau mengubah item dalam cakupan apa pun.
  • Jika Anda mencoba menampilkan atau mengubah nilai variabel yang memiliki visibilitas privat, PowerShell mengembalikan pesan kesalahan.

Anda dapat menggunakan New-Variable cmdlet dan Set-Variable untuk membuat variabel yang memiliki visibilitas privat.

Contoh

Contoh 1: Ubah Nilai Variabel Hanya dalam Skrip

Perintah berikut mengubah nilai $ConfirmPreference variabel dalam skrip. Perubahan tidak memengaruhi cakupan global.

Pertama, untuk menampilkan nilai $ConfirmPreference variabel dalam cakupan lokal, gunakan perintah berikut:

PS>  $ConfirmPreference
High

Buat skrip Scope.ps1 yang berisi perintah berikut:

$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."

Jalankan skrip. Skrip mengubah nilai $ConfirmPreference variabel lalu melaporkan nilainya dalam cakupan skrip. Output harus menyerupai output berikut:

The value of $ConfirmPreference is Low.

Selanjutnya, uji nilai $ConfirmPreference variabel saat ini dalam cakupan saat ini.

PS>  $ConfirmPreference
High

Contoh ini menunjukkan bahwa perubahan pada nilai variabel dalam cakupan skrip tidak memengaruhi nilai variabel dalam cakupan induk.

Contoh 2: Melihat Nilai Variabel dalam Cakupan Yang Berbeda

Anda dapat menggunakan pengubah cakupan untuk melihat nilai variabel dalam cakupan lokal dan dalam cakupan induk.

Pertama, tentukan $test variabel dalam cakupan global.

$test = "Global"

Selanjutnya, buat skrip Sample.ps1 yang menentukan $test variabel . Dalam skrip, gunakan pengubah cakupan untuk merujuk ke versi $test global atau lokal variabel.

Dalam Sample.ps1:

$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."

Saat Anda menjalankan Sample.ps1, output harus menyerupai output berikut:

The local value of $test is Local.
The global value of $test is Global.

Ketika skrip selesai, hanya nilai global yang $test ditentukan dalam sesi.

PS>  $test
Global

Contoh 3: Mengubah Nilai Variabel dalam Cakupan Induk

Kecuali Anda melindungi item dengan menggunakan opsi Privat atau metode lain, Anda dapat melihat dan mengubah nilai variabel dalam cakupan induk.

Pertama, tentukan $test variabel dalam cakupan global.

$test = "Global"

Selanjutnya, buat skrip Sample.ps1 yang menentukan $test variabel . Dalam skrip, gunakan pengubah cakupan untuk merujuk ke versi $test global atau lokal variabel.

Dalam Sample.ps1:

$global:test = "Local"
"The global value of `$test is $global:test."

Ketika skrip selesai, nilai $test global diubah.

PS>  $test
Local

Contoh 4: Membuat Variabel Privat

Variabel privat adalah variabel yang memiliki properti Opsi yang memiliki nilai Private. Private Variabel diwariskan oleh cakupan anak, tetapi hanya dapat dilihat atau diubah dalam cakupan tempat variabel dibuat.

Perintah berikut membuat variabel privat yang disebut $ptest dalam cakupan lokal.

New-Variable -Name ptest -Value 1 -Option Private

Anda dapat menampilkan dan mengubah nilai $ptest dalam cakupan lokal.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

Selanjutnya, buat skrip Sample.ps1 yang berisi perintah berikut. Perintah mencoba menampilkan dan mengubah nilai $ptest.

Dalam Sample.ps1:

"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."

Variabel $ptest tidak terlihat dalam cakupan skrip, output kosong.

"The value of $Ptest is ."
"The value of $Ptest is ."

Contoh 5: Menggunakan Variabel Lokal dalam Perintah Jarak Jauh

Untuk variabel dalam perintah jarak jauh yang dibuat di sesi lokal, gunakan pengubah Using cakupan. PowerShell mengasumsikan bahwa variabel dalam perintah jarak jauh dibuat dalam sesi jarak jauh.

Sintaksnya adalah:

$Using:<VariableName>

Misalnya, perintah berikut membuat $Cred variabel di sesi lokal lalu menggunakan $Cred variabel dalam perintah jarak jauh:

$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}

Cakupan Menggunakan diperkenalkan di PowerShell 3.0. Di PowerShell 2.0, untuk menunjukkan bahwa variabel dibuat dalam sesi lokal, gunakan format perintah berikut.

$Cred = Get-Credential
Invoke-Command $s {
  param($c)
  Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred

Lihat juga