Ошибка передачи свойства из объекта в командлет Stop-EC2Instance
Я пишу ряд функций для запуска и остановки экземпляров EC2 с помощью тега name, а не ID. Сначала я написал функцию отчетности, которую можно найти ниже.
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
Любая помощь будет принята с благодарностью. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.
Дальнейший прогресс.
Правильно, не решена, почему возникает ошибка, и откройте ее на форуме AWS на сайте amazon https://forums.aws.amazon.com/thread.jspa?threadID=143319
Но желаемое поведение можно создать, изменив функцию на приведенную ниже.
Функция Stop-EC2InstanceByName ([строка]$Name){ If((Get-Module -Name AWSPowerShell).Name -ne 'AWSPowerShell'){ Throw 'Модуль AWSPowerShell не загружен' } [объект]$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{
$_
}
}
3 ответа
Просто конвертировать через .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
вы бы предпочли использовать строковый идентификатор экземпляра. Документация 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, )
Союзник,
Я полагаю, у вас есть ошибка в вашем синтаксисе для остановки.
Ваша стартовая команда (рабочая):
Start-EC2Instance -InstanceId $EC2Instance[0].InstanceId
Ваша команда остановки (не работает):
Stop-EC2Instance -Instance $EC2Instance[0].InstanceID
Попробуйте обновить флаг '-Instance' до '-InstanceId' и посмотрите, как это происходит.:-)
-Тим
Правильно, не решена, почему возникает ошибка, и откройте ее на форуме AWS на сайте amazon https://forums.aws.amazon.com/thread.jspa?threadID=143319
Но желаемое поведение можно создать, изменив функцию на приведенную ниже.
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{
$_
}
}