【问题标题】:Stop/Start VM's In a specific Resource Group on Azure在 Azure 上的特定资源组中停止/启动 VM
【发布时间】:2020-12-17 04:25:06
【问题描述】:

这是脚本:因为我对云基础设施自动化完全陌生,所以我被困在这个问题上。我基本上是在尝试将收集到的 VM 的详细信息添加到单独的列表中,具体取决于它们的电源状态。

工作流程 rg-startstop {

param(
    [string]$power,
    [string]$azureResourceGroup
    )
       
    $connectionName = "AzureRunAsConnection"
    try
    {
        # Get the connection "AzureRunAsConnection "
        $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         
    
        "Logging in to Azure..."
        Add-AzureRmAccount `
            -ServicePrincipal `
            -TenantId $servicePrincipalConnection.TenantId `
            -ApplicationId $servicePrincipalConnection.ApplicationId `
            -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
    }
    catch 
    {
        if (!$servicePrincipalConnection)
        {
            $ErrorMessage = "Connection $connectionName not found."
            throw $ErrorMessage
        } else{
            Write-Error -Message $_.Exception
            throw $_.Exception
        }
    }
    
   
    $vms = Get-AzureRMVM -ResourceGroupName $azureResourceGroup  
    $vmrunninglist = @()
    $vmstoppedlist = @()
    
    
    Foreach($vm in $vms)
        {
            $vmstatus = Get-AzureRMVM -ResourceGroupName $azureResourceGroup -name $vm.name -Status       
            $PowerState = (get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code.split("/")[1])
              
          
            if ($Powerstate -eq 'Running')
            {  
                $vmrunninglist = $vmrunninglist + $vm.name
            }
            if ($Powerstate -eq 'Deallocated')
            {
                $vmstoppedlist = $vmstoppedlist + $vm.name
            } 
        }
    
                
    if ($power -eq 'start') {
       
       foreach ($vm in $vmrunninglist) {
        Start-AzureRmVM -ResourceGroupName $azureResourceGroup -Name $vm.name -Verbose
       }

    }
        
    
    if ($power -eq 'stop') {
        foreach ($vm in $vmstoppedlist) {
            Stop-AzureRmVM -ResourceGroupName $azureResourceGroup -Name $vm.name -Verbose -Force
           }
    }
         
    
}
    
    
    
    

错误是:您不能在空值表达式上调用方法。 那么,请问有人可以修改吗?

【问题讨论】:

  • Edit 问题并包含整个错误消息。它包含有关脚本失败的部分的信息。
  • 通过添加try catch检查$vms$vmstatus(get-culture)(get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1](get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code(get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code.split("/")[1]$vm的值。其中一个/几个是/是空的。

标签: azure powershell automation


【解决方案1】:

请通过添加 try catch 来检查 $vms$vmstatus(get-culture)(get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1](get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code(get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code.split("/")[1] 中的 $vm 的值。其中一个/几个是/是空的。

【讨论】:

    【解决方案2】:

    一般来说,如果您尝试使用任何方法对空值表达式执行某些操作,则会生成错误“you cannot call a method on a null-valued expression”。我相信在这种情况下,表达式是($vmstatus.statuses)[1].code,方法是split

    出于测试目的,如果您尝试拆分不存在的($vmstatus.statuses)[2].code,那么您将看到相同的空值表达式错误,如下所示。

    因此,要回答您有关如何修改此设置的问题,请在下面找到适用于我的设置的更新脚本。

    param(
        [string]$power,
        [string]$azureResourceGroup
        )
           
        $connectionName = "AzureRunAsConnection"
        try
        {
            # Get the connection "AzureRunAsConnection "
            $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         
        
            "Logging in to Azure..."
            Add-AzureRmAccount `
                -ServicePrincipal `
                -TenantId $servicePrincipalConnection.TenantId `
                -ApplicationId $servicePrincipalConnection.ApplicationId `
                -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
        }
        catch 
        {
            if (!$servicePrincipalConnection)
            {
                $ErrorMessage = "Connection $connectionName not found."
                throw $ErrorMessage
            } else{
                Write-Error -Message $_.Exception
                throw $_.Exception
            }
        }
        
       
        $vms = Get-AzureRMVM -ResourceGroupName $azureResourceGroup  
        $vmrunninglist = @()
        $vmstoppedlist = @()
        
        
        Foreach($vm in $vms)
            {
                $vmstatus = Get-AzureRMVM -ResourceGroupName $azureResourceGroup -name $vm.name -Status       
                
                #$PowerState = (get-culture).TextInfo.ToTitleCase(($vmstatus.statuses)[1].code.split("/")[1])
                $vmstatusescodes = $vmstatus.Statuses.code
                
                Foreach($vmstatusescode in $vmstatusescodes)
                {
                    if($vmstatusescode -eq "PowerState/deallocated")
                    {
                        $vmstoppedlist = $vmstoppedlist + $vm.name
                    }
                    elseif($vmstatusescode -eq "PowerState/running")
                    {
                        $vmrunninglist = $vmrunninglist + $vm.name
                    }
                }
            }
        
                    
        if ($power -eq 'start') {
           
           foreach ($vm in $vmrunninglist) {
            Start-AzureRmVM -ResourceGroupName $azureResourceGroup -Name $vm.name -Verbose
           }
    
        }
            
        
        if ($power -eq 'stop') {
            foreach ($vm in $vmstoppedlist) {
                Stop-AzureRmVM -ResourceGroupName $azureResourceGroup -Name $vm.name -Verbose -Force
               }
        }
             
        
    }
    

    这里脚本的变化是,我们去掉了对

    的依赖
    1. $vmstatus.statuses.code 数组(因为不存在的第一个数组元素是您看到空值表达式错误的原因)
    2. split方法
    3. Get-Culture cmdlet(在这种情况下实际上不需要使用)

    您始终可以通过添加越来越多的错误处理元素来增强或升级您的脚本,例如,您可以在脚本的每个点将日志条目添加到单独的 .log 文件中,并利用 try catch finally 块处理异常并将详细的异常消息记录到异常文件等。有关更多信息,请查看this 和其他有关文件。

    另一方面,如果您还不知道,那么看看您是否可以利用 this 启动停止解决方案而不是使用自定义脚本。

    最后,我建议您使用 Az PowerShell 而不是 AzureRM PowerShell,因为按照 here 的指示,从 2018 年 12 月开始,Azure PowerShell Az 模块是一般版本,现在是用于与 Azure 交互的预期 PowerShell 模块。因此,Az 模块是最新推荐使用的模块,而 AzureRM 模块是较旧的模块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      相关资源
      最近更新 更多