停止/启动VM';Azure上特定资源组中的

停止/启动VM';Azure上特定资源组中的,azure,powershell,automation,Azure,Powershell,Automation,这里是脚本:由于我对云基础设施自动化完全陌生,我被困在这一点上。我基本上是想把收集到的VM的详细信息添加到单独的列表中,具体取决于它们的状态 工作流rg startstop{ param( [string]$power, [string]$azureResourceGroup ) $connectionName = "AzureRunAsConnection" try { # Get the co

这里是脚本:由于我对云基础设施自动化完全陌生,我被困在这一点上。我基本上是想把收集到的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
           }
    }
         
    
}
    
    
    
    
错误是:不能对空值表达式调用方法。
那么,有人可以修改这个吗?

请检查
$vms
$vmstatus
(获取文化)
(获取文化)。TextInfo.ToTitleCase($vmstatus.status)[1],
(获取文化)。TextInfo.ToTitleCase($vmstatus.status)[1]。code
(获取文化)。TextInfo.ToTitleCase(($vmstatus.statuses)[1].code.split(“/”)
[1]通过添加try-catch。其中一个/几个是空的。

通常,如果您试图使用任何方法对空值表达式执行某些操作,则会生成错误“
您无法对空值表达式调用方法”
。我相信在这种情况下,表达式是
($vmstatus.status)[1]。代码
,方法是
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
           }
    }
         
    
}
这里脚本的变化是,我们已经删除了对

  • $vmstatus.statuses.code
    数组(因为不存在第一个数组元素是您看到空值表达式错误的原因)
  • 方法
  • cmdlet(在这种情况下实际上不需要使用)
  • 您始终可以通过添加越来越多的错误处理元素来增强或升级您的脚本,例如,在脚本的每个点上,您可以向单独的.log文件添加日志项,还可以利用try-catch-finally块来处理异常,并将详细的异常消息记录到异常文件等,以获取更多信息确认、检查和其他关于文件的信息

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


    最后,我建议您使用Az PowerShell而不是AzureRM PowerShell,因为根据指示,从2018年12月开始,Azure PowerShell Az模块已正式发布,现在是与Azure交互的预期PowerShell模块。因此Az模块是最新推荐使用的模块,AzureRM模块是较旧的模块。

    询问并包括整个错误消息。它包含脚本失败的部分的信息。请检查
    $vms
    $vmstatus
    (获取区域性)
    (获取区域性)
    (获取区域性)。TextInfo.ToTitleCase($vmstatus.status)[1]
    (获取区域性)。TextInfo.ToTitleCase($vmstatus.status)[1].code
    (获取区域性).TextInfo.ToTitleCase(($vmstatus.status)[1]。code.split(“/”[1]
    ),通过添加try-catch。其中一个或几个为空。