Check if Azure Storage Account Keys are Older Than 180 Days

This GitHub Action Workflow can be used to check if Azure Storage Account Keys have been rotated within the last 180 days and scheduled to run automatically. You can add on to the script to rotate the keys if they are older than 180 days or whatever threshold you decide to set.

name: Maint- Check and Rotate Storage Keys
'on':
  workflow_dispatch:
    inputs:
      environment:
        description: Run on Subscription
        required: true
        default: PROD
        type: choice
        options:
          - NONPROD
          - DEV
          - PROD
  schedule:
    - cron: '0 3 15 * *' # Run on the 15th of the month at 3:00 AM UTC
jobs:
  Check_sa_keys:
    runs-on: ubuntu-latest
    environment: '${{ github.event.inputs.environment}}'
    name: Start Process
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Login to Azure
        uses: azure/login@v1
        with:
          creds: '${{secrets.A}}'
          enable-AzPSSession: true
      - name: Check Storage Account Key1 and Key2 and Rotate
        id: task-check-Licenses
        uses: azure/powershell@v1
        with:
          azPSVersion: latest
          errorActionPreference: stop
          inlineScript: |
              # Define the threshold for key age (180 days)
              $threshold = (Get-Date).AddDays(-180)
              Write-Host "Threshold: $threshold"

              # Object to store the results
              $result = @()

              # Iterate through the storage accounts
              foreach ($account in $storageAccounts) {
                  Write-Host "Processing Account: $($account.StorageAccountName)"

                  # Get the storage account keys
                  $keys = Get-AzStorageAccountKey -ResourceGroupName $account.ResourceGroupName -Name 
                  $account.StorageAccountName

                  foreach ($key in $keys) {
                      Write-Host "Key: $($key.KeyName), CreationTime: $($key.CreationTime)"

                      # Check if the CreationTime is not null or empty
                      if ($null -ne $key.CreationTime) {
                          # Convert the key's creation time to a DateTime object
                          $lastRotated = [datetime]$key.CreationTime
                          Write-Host "Last Rotated: $lastRotated"

                          # Check if the key's creation time is older than the threshold
                          if ($lastRotated -lt $threshold) {
                              Write-Host "Adding to result"

                              $result += [PSCustomObject]@{
                                  StorageAccountName = $account.StorageAccountName
                                  KeyName            = $key.KeyName
                                  LastRotated        = $lastRotated
                              }
                          }
                      } else {
                          Write-Host "Warning: CreationTime is null for key $($key.KeyName) in storage 
                          account $($account.StorageAccountName)"
                      }
                  }
              }

              # Print the results
              $result | Format-Table

If you wanted to send the results you can do something like this and use Logic App to send and email or Teams message. The code below will send the payload data to Logic App and Logic App will handle the notification email or Teams message.

                  # Prepare the JSON payload
                  $payload = @{
                      #These need to be defined in your Logic App JSON 
                      EmailSubject = "Storage Account Key Rotation Alert"
                      StorageAccountName = $account.StorageAccountName
                      KeyName = $key.KeyName
                      LastRotated = $lastRotated
                      BCCField = "Email@onmicrosoft.com"
                      NotificationType = "ToOwner"
                  }

                  # Convert the payload to JSON
                  $payloadJson = $payload | ConvertTo-Json -Depth 100

                  # Prepare the headers
                  $headers = @{
                      'Content-Type' = 'application/json'
                  }

                  # Send the data to Logic App
                  Invoke-RestMethod -Uri 'https://LOGICAPPURL:443/' -Method POST -Headers $headers -Body 
                  $payloadJson
              }
Share or Save this:
Share