Phạm vi ảnh hưởng đến tập lệnh PowerShell
Trong các tập lệnh bó, các thay đổi đối với các biến môi trường có tác động toàn cầu đến phiên hiện tại theo mặc định. Đối với PowerShell, điều hoàn toàn ngược lại là đúng vì phạm vi được sử dụng để cô lập các sửa đổi của tập lệnh. Tại đây, chúng tôi sẽ khám phá cách phạm vi ảnh hưởng đến các tập lệnh PowerShell và cách làm việc trong và xung quanh chúng.
Phạm vi là gì?
Trong PowerShell, một phạm vi phạm vi hướng dẫn đề cập đến môi trường hiện tại trong đó tập lệnh hoặc shell lệnh đang hoạt động. Phạm vi được sử dụng để bảo vệ các đối tượng nhất định trong môi trường khỏi bị vô tình sửa đổi bởi các tập lệnh hoặc chức năng. Đặc biệt, những điều sau đây được bảo vệ khỏi sửa đổi bởi các lệnh chạy từ phạm vi khác, trừ khi được quy định khác bởi các tham số trong các lệnh đó:
- Biến
- Bí danh
- Chức năng
- Ổ đĩa PowerShell (PSDrive)
Phạm vi mới được tạo bất cứ khi nào bạn chạy tập lệnh hoặc hàm hoặc khi bạn tạo phiên hoặc phiên bản mới của PowerShell. Các phạm vi được tạo bằng cách chạy các tập lệnh và hàm có mối quan hệ cha mẹ / con con của Cameron với phạm vi mà chúng được tạo. Có một vài phạm vi có ý nghĩa đặc biệt và có thể được truy cập theo tên:
- Các Toàn cầu scope là phạm vi được tạo khi PowerShell khởi động. Nó bao gồm các biến, bí danh, hàm và PSDrive được tích hợp sẵn trong PowerShell cũng như bất kỳ biến nào được tạo bởi hồ sơ PowerShell của bạn.
- Các Địa phương phạm vi đề cập đến bất cứ điều gì phạm vi hiện tại là. Khi bạn khởi động PowerShell, nó sẽ đề cập đến phạm vi Toàn cầu, trong một tập lệnh, nó sẽ là phạm vi Tập lệnh, v.v..
- Các Kịch bản phạm vi được tạo khi một kịch bản được chạy. Các lệnh duy nhất hoạt động trong phạm vi này là các lệnh trong tập lệnh.
- Riêng tư phạm vi có thể được xác định trong phạm vi hiện tại, để ngăn các lệnh trong phạm vi khác không thể đọc hoặc sửa đổi các mục mà chúng có thể có quyền truy cập vào.
Phạm vi cũng có thể được gọi bằng số trong các lệnh nhất định, trong đó phạm vi hiện tại được gọi là 0 và tổ tiên của nó được tham chiếu bằng cách tăng số nguyên. Ví dụ: trong một tập lệnh chạy từ phạm vi Toàn cầu, phạm vi Tập lệnh sẽ là 0 và phạm vi Toàn cầu sẽ là 1. Phạm vi được lồng thêm trong phạm vi Tập lệnh, như hàm, sẽ đề cập đến phạm vi Toàn cầu là 2 Tuy nhiên, các số âm sẽ không hoạt động để tham chiếu phạm vi con - lý do cho điều này sẽ sớm xuất hiện.
Phạm vi ảnh hưởng đến các lệnh như thế nào
Như đã đề cập trước đó, các lệnh được thực thi trong một phạm vi sẽ không ảnh hưởng đến mọi thứ trong phạm vi khác trừ khi được yêu cầu cụ thể làm như vậy. Ví dụ: nếu $ MyVar tồn tại trong phạm vi Toàn cầu và tập lệnh chạy lệnh để đặt $ MyVar thành một giá trị khác, phiên bản Toàn cầu của $ MyVar sẽ vẫn không thay đổi trong khi bản sao của $ MyVar được đặt trong phạm vi Tập lệnh với mới giá trị. Nếu $ MyVar không tồn tại, tập lệnh sẽ tạo nó trong phạm vi Tập lệnh theo mặc định - không phải trong phạm vi Toàn cầu. Điều quan trọng cần nhớ khi bạn tìm hiểu về mối quan hệ cha mẹ / con cái thực sự giữa các phạm vi.
Mối quan hệ cha / con của phạm vi trong PowerShell là một chiều. Các lệnh có thể nhìn vào và tùy ý sửa đổi phạm vi hiện tại, cha mẹ của nó và bất kỳ phạm vi nào ở trên đó. Tuy nhiên, họ không thể nhìn thấy hoặc sửa đổi mọi thứ ở bất kỳ đứa trẻ nào trong phạm vi hiện tại. Điều này chủ yếu là vì, khi bạn đã chuyển sang phạm vi cha mẹ, phạm vi con đã bị hủy vì nó đã hoàn thành mục đích của nó. Ví dụ: tại sao bạn phải xem hoặc sửa đổi một biến trong phạm vi Tập lệnh, từ phạm vi Toàn cầu, sau khi tập lệnh kết thúc? Có rất nhiều trường hợp bạn cần thay đổi tập lệnh hoặc chức năng để tiếp tục vượt quá hoàn thành, nhưng không có nhiều trường hợp bạn cần thay đổi đối tượng trong phạm vi của tập lệnh hoặc chức năng trước hoặc sau khi tập lệnh được chạy. (Thông thường, những thứ như vậy sẽ được xử lý như một phần của tập lệnh hoặc chính chức năng.)
Tất nhiên, các quy tắc mà không có ngoại lệ là gì? Một ngoại lệ ở trên là phạm vi riêng tư. Các đối tượng trong phạm vi Riêng tư chỉ có thể truy cập đối với các lệnh chạy trong phạm vi mà chúng được tạo. Một ngoại lệ quan trọng khác là các vật phẩm có thuộc tính AllScope. Đây là các biến và bí danh đặc biệt mà sự thay đổi trong bất kỳ phạm vi nào sẽ ảnh hưởng đến tất cả các phạm vi. Các lệnh sau sẽ cho bạn thấy các biến và bí danh nào có thuộc tính AllScope:
Biến đổi | Where-Object $ _. Tùy chọn -match 'AllScope' Get-Alias | Trường hợp-Đối tượng $ _. Tùy chọn -match 'AllScope')
Phạm vi hoạt động
Để có cái nhìn đầu tiên về phạm vi hoạt động, chúng ta sẽ bắt đầu trong phiên PowerShell trong đó biến $ MyVar đã được đặt thành một chuỗi, 'Tôi là biến toàn cục!', Từ dòng lệnh. Sau đó, tập lệnh sau sẽ được chạy từ một tệp có tên Scope-Demo.ps1:
Chức năng FunctionScope 'Thay đổi $ MyVar bằng một chức năng.' $ MyVar = 'Tôi đã được thiết lập bởi một chức năng!' "MyVar nói $ MyVar" "Kiểm tra giá trị hiện tại của $ MyVar. ' "MyVar nói $ MyVar" "Thay đổi $ MyVar theo tập lệnh. ' $ MyVar = 'Tôi đã được thiết lập bởi một tập lệnh!' "MyVar nói $ MyVar" "FunctionScope" Kiểm tra giá trị cuối cùng của MyVar trước khi thoát tập lệnh. ' "MyVar nói $ MyVar" "
Nếu các tập lệnh PowerShell hoạt động giống như tập lệnh bó, chúng tôi sẽ mong đợi câu chuyện $ MyVar (hoặc% MyVar% theo cú pháp lô) thay đổi từ 'Tôi là biến toàn cục!', Thành 'Tôi đã được đặt bởi tập lệnh!' và cuối cùng là 'Tôi đã được thiết lập bởi một chức năng!' nơi nó sẽ ở lại cho đến khi nó thay đổi rõ ràng một lần nữa hoặc phiên kết thúc. Tuy nhiên, hãy xem điều gì thực sự xảy ra ở đây khi chúng ta di chuyển qua từng phạm vi - đặc biệt, sau khi hàm FunctionScope hoàn thành công việc của nó và chúng ta kiểm tra lại biến từ Script và sau đó là phạm vi Toàn cầu.
Như bạn có thể thấy biến có vẻ thay đổi khi chúng tôi chuyển qua tập lệnh bởi vì, cho đến khi chức năng FunctionScope hoàn thành, chúng tôi đã kiểm tra biến từ trong cùng phạm vi mà nó đã thay đổi lần cuối. Sau khi FunctionScope được hoàn thành, chúng tôi đã quay trở lại phạm vi Script nơi $ MyVar không bị ảnh hưởng bởi chức năng. Sau đó, khi tập lệnh kết thúc, chúng tôi đã quay trở lại phạm vi Toàn cầu nơi nó chưa được sửa đổi.
Vươn ra ngoài phạm vi địa phương
Vì vậy, đây là tất cả tốt và tốt để giúp bạn tránh vô tình áp dụng các thay đổi cho môi trường ngoài các tập lệnh và chức năng của bạn, nhưng nếu bạn thực sự muốn thực hiện các sửa đổi như vậy thì sao? Có một cú pháp đặc biệt và khá đơn giản để tạo và sửa đổi các đối tượng nằm ngoài phạm vi Cục bộ. Bạn chỉ cần đặt tên phạm vi ở đầu tên biến và đặt dấu hai chấm giữa tên phạm vi và tên biến. Như thế này:
$ toàn cầu: MyVar $ script: MyVar $ local: MyVar
Bạn có thể sử dụng các sửa đổi này cả khi xem và thiết lập các biến. Hãy xem điều gì xảy ra với kịch bản trình diễn này:
Function FunctionScope "Thay đổi $ MyVar trong phạm vi chức năng cục bộ '' local local: MyVar =" Đây là MyVar trong phạm vi cục bộ của chức năng. "'Thay đổi $ MyVar trong phạm vi tập lệnh' script script: MyVar = ' được thiết lập bởi một tập lệnh. Bây giờ được thiết lập bởi một chức năng. "Thay đổi $ MyVar trong phạm vi toàn cầu '$ global: MyVar =' MyVar được đặt trong phạm vi toàn cầu. Bây giờ được thiết lập bởi một chức năng. "Kiểm tra $ MyVar trong mỗi phạm vi. "MyVar nói $ MyVar" "Thay đổi $ MyVar theo tập lệnh. ' $ MyVar = 'Tôi đã được thiết lập bởi một tập lệnh!' "MyVar nói $ MyVar" FunctionScope 'Kiểm tra $ MyVar từ phạm vi tập lệnh trước khi thoát.' "MyVar nói $ MyVar" "
Như trước đây, chúng ta sẽ bắt đầu bằng cách đặt biến trong phạm vi Toàn cầu và kết thúc bằng việc kiểm tra kết quả Phạm vi toàn cầu cuối cùng.
Ở đây bạn có thể thấy rằng FunctionScope có thể thay đổi biến trong phạm vi Script và duy trì các thay đổi sau khi hoàn thành. Ngoài ra, sự thay đổi của biến trong phạm vi Toàn cầu vẫn tồn tại ngay cả sau khi tập lệnh đã thoát. Điều này có thể đặc biệt hữu ích nếu bạn phải liên tục thay đổi các biến trong tập lệnh hoặc trong phạm vi Toàn cầu, sử dụng cùng một mã - bạn chỉ cần xác định một hàm hoặc tập lệnh được viết để sửa đổi biến ở đâu và cách bạn cần thực hiện, và kêu gọi bất cứ khi nào những thay đổi đó là cần thiết.
Như đã đề cập trước đó, số phạm vi cũng có thể được sử dụng trong một số lệnh nhất định để sửa đổi biến ở các mức khác nhau liên quan đến phạm vi Địa phương. Đây là cùng một kịch bản được sử dụng trong ví dụ thứ hai ở trên, nhưng với chức năng được sửa đổi để sử dụng các lệnh Biến biến và Đặt biến với số phạm vi thay vì tham chiếu trực tiếp biến với phạm vi được đặt tên:
Function FunctionScope "Thay đổi $ MyVar trong phạm vi 0, liên quan đến MyVar Set-Var biến MyVar" Đây là MyVar trong phạm vi của hàm 0. "-Scope 0 'Thay đổi $ MyVar trong phạm vi 1, liên quan đến Biến số SetScope MyVar 'MyVar đã được thay đổi trong phạm vi 1, từ một chức năng.' -Scope 1 'Thay đổi $ MyVar trong phạm vi 2, liên quan đến Chức năng' Bộ biến đổi MyVar 'MyVar đã thay đổi trong phạm vi 2, từ một chức năng.' -Scope 2 "Kiểm tra $ MyVar trong mỗi phạm vi" Phạm vi 0: 'MyVar biến thiên 2 -ValueOnly "" Nhận giá trị hiện tại của $ MyVar. ' "MyVar nói $ MyVar" "Thay đổi $ MyVar theo tập lệnh. ' $ MyVar = 'Tôi đã được thiết lập bởi một tập lệnh!' "MyVar nói $ MyVar" FunctionScope 'Kiểm tra $ MyVar từ phạm vi tập lệnh trước khi thoát.' "MyVar nói $ MyVar" "
Tương tự như trước đây, chúng ta có thể thấy ở đây cách các lệnh trong một phạm vi có thể sửa đổi các đối tượng trong phạm vi cha của nó.
thông tin thêm
Vẫn còn nhiều điều có thể được thực hiện với phạm vi hơn mức có thể phù hợp trong bài viết này. Phạm vi ảnh hưởng đến nhiều hơn chỉ là các biến và vẫn còn nhiều điều cần tìm hiểu về Phạm vi riêng tư và các biến AllScope. Để biết thêm thông tin hữu ích, bạn có thể chạy lệnh sau từ bên trong PowerShell:
Nhận trợ giúp về_scopes
Tệp trợ giúp tương tự cũng có sẵn trên TechNet.
Phạm vi tín dụng hình ảnh: spadassin trên openclipart