在 PowerShell 中面臨幾個后勤問題 - 顯然我缺少一個基本概念:
設定:創建 menu.ps1 檔案(如下所示),啟動 PowerShell 7.2.2 并在本地呼叫該檔案。
問題:
- 第一次為 ArrayList ( ) 選擇選項 1 時
$psArrayList,它不會顯示(盡管我們從初始螢屏加載中看到專案已填充)。如果您回傳選單并再次選擇選項 1,它將在第二遍時顯示。($psArray第一次嘗試加載正常,所以這是型別問題。?) - 當腳本結束時,
$psArrayList并且$psArray仍在當前會話變數中,如:Get-Variable psArray*。即使我用它們實體化它們$script:psArrayList = [System.Collections.ArrayList]@()并且$script:psArray = @()它們似乎仍然在會話范圍內。當 ps1 結束時,是否有“正確”的方法來清除它們?
menu.ps1 內容:
$psArrayList = [System.Collections.ArrayList]@()
# example of populating later in function etc...
$psArrayList.Add([pscustomobject]@{name="bird";color="blue"})
$psArrayList.Add([pscustomobject]@{name="cat";color="orange"})
$psArrayList.Add([pscustomobject]@{name="bear";color="brown"})
$psArray = @()
# example of populating later in function etc...
$psArray = "dog"
$psArray = "fish"
$psArray = "squirrel"
function End-Script {
Remove-Variable psArray*
Exit
}
function Display-Menu {
[int]$choice=-1
Write-Host "This is a menu..." -ForegroundColor Green
Write-Host "Here are your options:"
Write-Host
Write-Host "`t1 - ArrayList"
Write-Host "`t2 - Array"
Write-Host "`t0 - quit (do nothing)"
Write-Host
while ($choice -lt 0) { $choice= Read-Host -Prompt "Choose 1-2 (or 0 to quit)" }
Process-Menu($choice)
}
function Process-Menu([int]$choice) {
switch($choice) {
1 { Write-Host "You chose ArrayList:"; Write-Output $psArrayList }
2 { Write-Host "You chose Array:"; Write-Output $psArray }
0 { Write-Host "You chose to quit. Exiting."; End-Script }
}
$yn=""
while ($yn -eq "") { $yn= Read-Host -Prompt "Return to main menu? (y/n)" }
if ($yn -eq "y") { Display-Menu } else { Write-Host "Ending..."; End-Script }
}
Display-Menu
uj5u.com熱心網友回復:
關于第一個問題,您需要使用Out-HostorOut-Default以便將兩個輸出(Write-Host連同陣列)正確顯示到控制臺。有關詳細資訊,請參閱這些有用的答案:
- https://stackoverflow.com/a/50416448/15339544
- https://stackoverflow.com/a/34858911/15339544
關于第二個問題,您的End-Script函式將有一個范圍問題,Remove-Variable正在嘗試洗掉在函式范圍內定義的變數(Local),如果您想定位在它之外定義的變數(Script),您需要使用-Scope引數,因為例子:
function End-Script {
Get-Variable psArray* | Remove-Variable -Scope Script
# `Remove-Variable psArray* -Scope Script` would be valid too
}
從 cmdlet 的引數部分,我們可以讀取引數的以下內容-Scope:
一個相對于當前作用域的數字(0 到作用域的數量,其中 0 是當前作用域,1 是其父作用域)
從這個意義上說,-Scope 1也可以。
您可以在下面看到一個帶有一些改進和輸入驗證的腳本示例:
$psArrayList = [System.Collections.ArrayList]@()
$psArrayList.AddRange(@(
[pscustomobject]@{name="bird";color="blue"}
[pscustomobject]@{name="cat";color="orange"}
[pscustomobject]@{name="bear";color="brown"}
))
$psArray = "dog", "fish", "squirrel"
function End-Script {
Get-Variable psArray* | Remove-Variable -Scope Script
}
function Display-Menu {
Write-Host "This is a menu..." -ForegroundColor Green
Write-Host "Here are your options:"
Write-Host
Write-Host "`t1 - ArrayList"
Write-Host "`t2 - Array"
Write-Host "`t0 - quit (do nothing)"
Write-Host
# one of many methods for input validation is a Recursive Script Block:
$tryInput = {
try {
[ValidateSet(0, 1, 2)] $choice = Read-Host "Choose 1-2 (or 0 to quit)"
$choice
}
catch {
Write-Warning 'Invalid choice!'
& $tryInput
}
}
Process-Menu (& $tryInput)
}
function Process-Menu([int] $choice) {
switch($choice) {
1 {
Write-Host "You chose ArrayList:"
$psArrayList | Out-Host
}
2 {
Write-Host "You chose Array:"
$psArray | Out-Host
}
0 {
Write-Host "You chose to quit. Exiting."
End-Script
Return # => Exit this function
}
}
$tryInput = {
try {
[ValidateSet('y', 'n')] $choice = Read-Host "Return to main menu? (y/n)"
$choice
}
catch {
Write-Warning 'Invalid choice!'
& $tryInput
}
}
# No need to check for `N`
if((& $tryInput) -eq 'y') { Display-Menu }
}
Display-Menu
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/454117.html
標籤:电源外壳
