azurepowershellazure-automationrunbook

Failed when running powershell code in azure automation


I set an azure policy adding two tags, which are CreatedTime and Type. The value of CreatedTime is utcNow(), which default format is 'yyyy-MM-ddTHH:mm:ss.fffffffZ'.

My goal is to delete all resources whose Type is private and created time is longer than 2 days by running powershell code in azure automation.

I have done it in power shell locally, but when I run the code in automation, it failed. I will post the code and the error page below.

Anybody can tell me what's wrong with my code? Or I miss something?

This is my code in Azure Automation:

   $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
    }
}

    $AllRes = (get-AzureRMResource).ResourceId
    $TimeOutDays=2
    foreach ($Res in $AllRes){
    $Resource = Get-AzureRMResource -ResourceId $Res
    $Tags=$Resource.Tags
    $TypeInTags=$Tags['Type']
    $CreatedTimeInTags=$Tags['CreatedTime']
try{
    $CreatedTime=[Datetime]::ParseExact($CreatedTimeInTags, 'MM/dd/yyyy HH:mm:ss', $null)
}
catch{
    $CreatedTime=[Datetime]::ParseExact($CreatedTimeInTags, 'yyyy-MM-ddTHH:mm:ss.fffffffZ', $null)
}
finally
{
    $CreatedTime
}
    $daypan=((get-date)-$CreatedTime).Days
    if($TypeInTags -eq 'private')
    {
    if($daypan -gt $TimeOutDays)
        {
            $daypan
            Remove-AzureRMResource -ResourceId $Res -Force
        }
    }
}

This is the error page: Suspended

The runbook job was attempted 3 times, but it failed each time.  Common reasons that runbook jobs fail can be found here:  https://learn.microsoft.com/en-us/azure/automation/automation-troubleshooting-automation-errors

enter image description here

A piece of error message:

Get-AzureRMResource : ResourceNotFound : The Resource 
'microsoft.alertsmanagement/smartDetectorAlertRules/Failure+Anomalies+-+arrowbottest2-config' under resource group 
'arrowbot2' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix
At line:28 char:17
+     $Resource = Get-AzureRMResource -ResourceId $Res
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-AzureRmResource], ErrorResponseMessageException
    + FullyQualifiedErrorId : 
ResourceNotFound,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet
 
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At line:34 char:5
+     $CreatedTime=[Datetime]::ParseExact($Tags['CreatedTime'], 'yyyy-M ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
 
Cannot find an overload for "op_Subtraction" and the argument count: "2".
At line:35 char:5
+     $daypan=((get-date)-$CreatedTime).Days
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
 

Cannot find an overload for "op_Subtraction" and the argument count: "2".
At line:35 char:5
+     $daypan=((get-date)-$CreatedTime).Days
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
 
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At line:34 char:5
+     $CreatedTime=[Datetime]::ParseExact($Tags['CreatedTime'], 'yyyy-M ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

For the type of $Tags['CreatedTime'], I did this for a test: $Tags['CreatedTime'].GetType().FullName.

enter image description here


Solution

  • There are two things wrong.

    1.Didn't specify the resource I need.

    Detailes:

    That's the reason for the error message: Can not index to a null array. I traverse the entire resource in my subscription, but the resources created before I set the policy do not have a Tag named "CreatedTime" or "Type", so when I run $Tags=$Resource.Tags, it said Can not index to a null array.

    My solution:

    Do $AllRes = (get-AzResource -TagName "CreatedTime").ResourceId other than $AllRes = (get-AzureRMResource).ResourceId. I found that AzureRM module don't recognize -TagName as a variable, so I import the Az module and change every AzureRM module to Az module.

    2.Confused with utcNow().

    Details:

    As I said, with utcNow() function I get a DateTime object with default format 'yyyy-MM-ddTHH:mm:ss.fffffffZ', after testing a lot, I found some special resources like application insight' tag value is not formated with 'yyyy-MM-ddTHH:mm:ss.fffffffZ', and when I call it, it comes to a string.

    My solution:

    So when I use it comparing to get-date, I need to do two things:

    (1)Change the string to DateTime object;

    (2)Use try-catch to meet two kinds of formats.