在函数中创建数组并使用另一个函数

时间:2016-10-06 13:16:09

标签: powershell

我有一个程序可以获取给定用户的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

1 个答案:

答案 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:)的范围