我有一个程序可以获取给定用户的VM信息。它使用一个菜单系统,函数REFRESH_LIST
创建一个数组,创建一个包含VM信息(ip地址,名称等)的对象并将其放入数组中,这样数组就是一个对象数组作为用户拥有的VM数量。
然后我使用此数组填充表格以显示要筛选的所有信息。我有另一个函数START_INSTANCE
,它将根据VM的名称启动VM,但是为了检查并确保用户只启动分配给它们的VM我想回到数组并检查他们输入的VM名称存在于数组中。
我遇到的问题是数组是在一个函数中构建的,我需要在另一个函数中。在阅读中,我发现它是一个范围问题$script:var
我构建了简单的测试函数并获得了一个变量,当我将相同的$script:var
应用于数组时,它仍然无法在其他任何地方使用。
阵列有什么特别之处还是除了范围之外还有什么特别之处?
FUNCTION GET_HELP {
ECHO ""
ECHO " refresh : REFRESH VM LIST"
ECHO " start : START INSTANCE : start <instance-id>"
ECHO " stop : STOP INSTANCE : stop <instance-id>"
ECHO " q : QUIT"
ECHO ""
}
FUNCTION INSTANCE_START {
$i=0
$CHECK=""
$a.Length
While ($i -le $a.Length) {
echo $CHECK
If ($a[$i].INSTANCEID -contains $INSTANCEID) {
$CHECK = "TRUE"}
$i = $i+1
Echo $CHECK
}
echo $CHECK
IF ($CHECK = "TRUE") {
#Start-EC2Instance -InstanceId
"STARTING " + $INSTANCEID
ECHO $CHECK}
ELSE {
$CHECK=""
"NO"}
$INSTANCEID = ""
}
FUNCTION INSTANCE_STOP {
#Stop-EC2Instance -InstanceId
}
FUNCTION REFRESH_LIST {
Clear-Host
" LOADING VM LIST FOR "+$USERNAME
$date = get-date -format "MM/dd/yyyy HH:mm:ss"
$Global:a = @()
(Get-EC2Instance).instances | ? {$_.Tags.Key -eq "NAME" -and $_.Tags.Value -eq $TEST_USER} | ForEach-Object {
$instobj = New-Object System.Object
$instobj | Add-Member -Type NoteProperty -Name STATE -value $_.state.name
$instobj | Add-Member -type NoteProperty -name INSTANCEID -value $_.InstanceID
$instobj | Add-Member -type NoteProperty -name IPADDRESS -value $_.PublicIPAddress
IF ($_.state.name -eq 'running'){
$time=New-TimeSpan -Start $_.LaunchTime -End $date
$val="{0}d {1}h {2}m" -f $time.Days, $time.Hours, $time.Minutes
$instobj | Add-Member -Type NoteProperty -Name TIME -value $val}
else{$instobj | Add-Member -Type NoteProperty -Name TIME -value ""}
$a += $instobj}
For ($i=0; $i -le $a.Length-1; $i++){
$instanceTags = Get-EC2Tag -Filter @{ Name="resource-id"; Values=$a[$i].INSTANCEID }
$a[$i] | Add-Member -type NoteProperty -name PROJECT -value $instanceTags.Where({$_.Key -eq "Project"}).Value
$a[$i] | Add-Member -type NoteProperty -name NAME -value $instanceTags.Where({$_.Key -eq "Name"}).Value
$a[$i] | Add-Member -type NoteProperty -name SOFTWARE -value $instanceTags.Where({$_.Key -eq "Oracle SW"}).Value
}
Clear-Host
echo $date
$a | sort STATE, PROJECT, NAME |Format-Table STATE, INSTANCEID, IPADDRESS, PROJECT, NAME, SOFTWARE, TIME -AutoSize
}
#REGION MAIN
REFRESH_LIST
DO {
$SELECTION = Read-Host ">"
$COMMAND,$INSTANCEID = $SELECTION.split(' ',2)
SWITCH ($COMMAND) {
'-h' {GET_HELP}
'refresh' {REFRESH_LIST}
'start' {INSTANCE_START}
'stop' {'STOPPING INTANCE'}
'q' {BREAK}
DEFAULT {'ENTER -h FOR HELP'}
}}
until ($COMMAND -eq 'q')
#ENDREGION
答案 0 :(得分:1)
解决此问题的一种方法是在$Global:
范围内分配数组:
$Global:arr
一些示例代码:
function one {
$Global:arr = @(1, 2, 3)
}
function two {
one
$arr
}
two
输出:
1
2
3
有关详细信息,请参阅ss64或运行help about_Scopes
。
在您发布的代码中,您可以尝试:
$Global:a = @()
中的 REFRESH_LIST
这个小例子更能反映您的代码:
function one {
$Global:a = @(1,2,3)
}
function two {
echo $a.Length
}
one
two
输出为3
正如评论中所提到的,这也适用于$Script
,在您的情况下更为可取。但是,为了确保每次都在调用相同的数组实例,每次使用时如果需要在其前面加上您决定将其声明为($Global:
或$Script:
)的范围{ p>