1

我正在编写许多通过名称标签而不是 ID 来启动和停止 EC2 实例的函数。首先,我编写了一个报告功能,可以在下面找到。

Function Get-EC2InstanceReport{
    If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){
        Throw 'AWSPowerShell module is not loaded'
    }
    Get-EC2Tag | `
        Where-Object {$_.ResourceType -eq 'instance' -and $_.Key -eq 'Name'} | `
        Select-Object @{Name='InstanceID'; Expression={$_.ResourceID}}, @{Name='Name'; Expression={$_.Value}}, `
        @{Name='Status'; Expression={Get-EC2InstanceStatus -IncludeAllInstances $true -InstanceId $_.ResourceID | %     {$_.InstanceState.Name}}}
}

并且启动实例的功能可以正常工作。

Function Start-EC2InstanceByName ([string]$Name){
    If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){
        Throw 'AWSPowerShell module is not loaded'
    }
    [object]$EC2Instance = Get-EC2InstanceReport | Where-Object {$_.Name -eq $Name}

    Try{
        If($EC2Instance[0].Status -eq 'stopped'){
            Start-EC2Instance -InstanceId $EC2Instance[0].InstanceId | Out-Null
            Test-EC2InstanceStatus -Name $Name -EndState 'running'
        }
        Else{
            $ErrorMsg = "EC2 instance " + $EC2Instance[0].Name + " is not in the stopped state. It is " + $EC2Instance[0].Status + "."
            Throw $ErrorMsg
        }
    }
    Catch{
        $_
    }
}

但是当使用类似的方法停止实例时,我得到一个错误。

Function Stop-EC2InstanceByName ([string]$Name){
    If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){
        Throw 'AWSPowerShell module is not loaded'
    }
    [object]$EC2Instance = Get-EC2InstanceReport | Where-Object {$_.Name -eq $Name}

    Try{
        If($EC2Instance[0].Status -eq 'running'){
            Stop-EC2Instance -Instance $EC2Instance[0].InstanceID | Out-Null
            Test-EC2InstanceStatus -Name $Name -EndState 'stopped'
        }
        Else{
            $ErrorMsg = "EC2 instance " + $EC2Instance[0].Name + " is not in the running state. It is " + $EC2Instance[0].Status + "."
            Throw $ErrorMsg
        }
    }
    Catch{
        $_
    }
}

错误可以在下面找到。

Stop-EC2Instance : No instances specified
At C:\GitProjects\DBA\aws-powershell-scripts\AWSFunctions.psm1:61 char:4
+             Stop-EC2Instance -Instance $EC2Instance[0].InstanceID | Out-Null
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Stop-EC2Instance], AmazonEC2Exception
    + FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.StopEC2InstanceCmdlet

任何帮助将不胜感激。如果您需要任何进一步的信息,请告诉我。

进一步的进展。

是的,没有解决为什么会发生错误并在亚马逊https://forums.aws.amazon.com/thread.jspa?threadID=143319上的 AWS 论坛上打开它

但是可以通过将函数更改为下面的函数来创建所需的行为。

Function Stop-EC2InstanceByName ([string]$Name){ If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){ Throw 'AWSPowerShell module is not loaded' } [object]$EC2Instance = Get-EC2InstanceReport | Where-Object {$_.Name -eq $Name}

Try{
    If($EC2Instance[0].Status -eq 'running'){
        Get-EC2Instance -Filter @{Name="tag:Name"; Value=$Name} | Stop-EC2Instance | Out-Null
        Test-EC2InstanceStatus -Name $Name -EndState 'stopped'
    }
    Else{
        $ErrorMsg = "EC2 instance " + $EC2Instance[0].Name + " is not in the running state. It is " + $EC2Instance[0].Status + "."
        Throw $ErrorMsg
    }
}
Catch{
$_
}
}
4

3 回答 3

1

简单地转换 via.ToString()得到了我想要的结果,而不必通过管道传递输入。

# Failed attempt
PS C:\> Stop-EC2Instance -Instance $myInstance.InstanceId
Stop-EC2Instance : No instances specified
At line:1 char:17
+ Stop-EC2Instance <<<<  -Instance $myInstance.InstanceId
    + CategoryInfo          : NotSpecified: (:) [Stop-EC2Instance], AmazonEC2Exception
    + FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.StopEC2InstanceCmdlet

# Successful attempt
PS C:\> Stop-EC2Instance -Instance $myInstance.InstanceId.ToString()
# Goodnight instance...

这很奇怪,因为当我们Get-Member在您的实例对象上使用时,我们可以看到在 InstanceID 中定义了一个字符串:

   TypeName: Selected.Amazon.EC2.Model.ResourceTag

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
InstanceID  NoteProperty System.String InstanceID=i-abcd1234
Name        NoteProperty System.String Name=MyInstance
Status      NoteProperty  Status=null

通过管道输入传递 InstanceID 是有效的,因为它可以接受System.Object[],而似乎明确地使用-Instance宁愿您使用字符串 Instance ID。Stop-EC2Instance 文档证实了这一点:

-Instance <Object[]>
Identifies the set of instances to stop or terminate. Accepts a string instance ID or a collection of RunningInstance or Reservation objects. If a Reservation object is supplied, all of the instances in the reservation are processed.
Required?   False
Position?   1
Accept pipeline input?  True (ByValue, )
于 2014-01-07T19:09:51.947 回答
0

盟友,

我相信您的停止语法有错误。

您的启动命令(工作):

Start-EC2Instance -InstanceId $EC2Instance[0].InstanceId

您的停止命令(不起作用):

Stop-EC2Instance -Instance $EC2Instance[0].InstanceID

尝试将“-Instance”标志更新为“-InstanceId”,看看效果如何。:-)

-蒂姆

于 2014-01-07T14:15:57.577 回答
0

是的,没有解决为什么会发生错误并在亚马逊https://forums.aws.amazon.com/thread.jspa?threadID=143319上的 AWS 论坛上打开它

但是可以通过将函数更改为下面的函数来创建所需的行为。

Function Stop-EC2InstanceByName ([string]$Name){
    If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){
        Throw 'AWSPowerShell module is not loaded'
    }
    [object]$EC2Instance = Get-EC2InstanceReport | Where-Object {$_.Name -eq $Name}

    Try{
        If($EC2Instance[0].Status -eq 'running'){
            Get-EC2Instance -Filter @{Name="tag:Name"; Value=$Name} | Stop-EC2Instance | Out-Null
            Test-EC2InstanceStatus -Name $Name -EndState 'stopped'
        }
        Else{
            $ErrorMsg = "EC2 instance " + $EC2Instance[0].Name + " is not in the running state. It is " + $EC2Instance[0].Status + "."
            Throw $ErrorMsg
        }
    }
    Catch{
    $_
    }
}
于 2014-01-07T16:47:22.540 回答