Azure Cheat Sheet
Generic
Powershell
Login to Azure (Azure Powershell)
param(
[Parameter(Mandatory = $false)]
[bool]$UseServicePrincipal = $false,
[Parameter(Mandatory = $false)]
[string]$ClientId,
[Parameter(Mandatory = $false)]
[string]$TenantId,
[Parameter(Mandatory = $false)]
[string]$ClientSecret,
[Parameter(Mandatory = $false)]
[string]$SubscriptionId = $null,
[Parameter(Mandatory = $false)]
[switch]$IsDebugMode
)
if ($IsDebugMode)
{
$IsDebugMode = $true
}
else
{
$IsDebugMode = $false
}
function _LogMessage
{
param(
[string]$Level,
[string]$Message,
[string]$InvocationName
)
$timestamp = Get-Date -Format "HH:mm:ss"
if ($Level -eq "DEBUG" -and -not $IsDebugMode)
{
return
}
switch ($Level)
{
"INFO" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Cyan
}
"DEBUG" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Yellow
}
"WARNING" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor DarkYellow
}
"ERROR" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Red
}
default {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message"
}
}
}
#region Auth Functions
function Connect-AzureUser
{
try
{
$context = Get-AzContext
if ($null -eq $context -or $null -eq $context.Account)
{
_LogMessage -Level "INFO" -Message "No existing Azure context found. Authenticating to Azure..." -InvocationName $MyInvocation.MyCommand.Name
Connect-AzAccount -ErrorAction Stop
_LogMessage -Level "INFO" -Message "Authentication successful." -InvocationName $MyInvocation.MyCommand.Name
if ($SubscriptionId)
{
_LogMessage -Level "INFO" -Message "Setting subscription to $SubscriptionId..." -InvocationName $MyInvocation.MyCommand.Name
Set-AzContext -Subscription $SubscriptionId
}
}
else
{
_LogMessage -Level "INFO" -Message "Already authenticated to Azure as $( $context.Account.Id )." -InvocationName $MyInvocation.MyCommand.Name
}
}
catch
{
_LogMessage -Level "ERROR" -Message "Authentication failed. $( $_.Exception.Message )" -InvocationName $MyInvocation.MyCommand.Name
throw
}
}
function Connect-ToAzureSpn
{
param(
[bool]$UseSPN,
[string]$ClientId,
[string]$TenantId,
[string]$ClientSecret
)
if ($UseSPN -eq $true)
{
_LogMessage -Level "INFO" -Message "Connecting with Service Principal (Client Secret flow)..." -InvocationName $MyInvocation.MyCommand.Name
$securePassword = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($ClientId, $securePassword)
Connect-AzAccount -ServicePrincipal -Tenant $TenantId -Credential $credential
if ($SubscriptionId)
{
_LogMessage -Level "INFO" -Message "Setting subscription to $SubscriptionId..." -InvocationName $MyInvocation.MyCommand.Name
Set-AzContext -Subscription $SubscriptionId
}
}
elseif ($UseSPN -eq $false)
{
Connect-AzureUser
}
else
{
_LogMessage -Level "ERROR" -Message "Invalid authentication combination. Check parameters." -InvocationName $MyInvocation.MyCommand.Name
throw "Invalid authentication method. Use SPN w/ Secret or Interactive User."
}
}
try
{
_LogMessage -Level "INFO" -Message "Starting script..." -InvocationName $MyInvocation.MyCommand.Name
# 1. Connect to Azure
Connect-ToAzureSpn `
-UseSPN $UseServicePrincipal `
-ClientId $ClientId `
-TenantId $TenantId `
-ClientSecret $ClientSecret
}
catch
{
_LogMessage -Level "ERROR" -Message "A terminating error occurred: $( $_.Exception.Message )" -InvocationName $MyInvocation.MyCommand.Name
exit 1
}
Connect to Azure (Azure-CLI)
param(
[Parameter(Mandatory = $false)]
[bool]$UseServicePrincipal = $false,
[Parameter(Mandatory = $false)]
[string]$ClientId,
[Parameter(Mandatory = $false)]
[string]$TenantId,
[Parameter(Mandatory = $false)]
[string]$ClientSecret,
[Parameter(Mandatory = $false)]
[string]$SubscriptionId = $null,
[Parameter(Mandatory = $false)]
[string]$FedToken, # Unused, but left here if you plan to do federated login in future
[Parameter(Mandatory = $false)]
[switch]$IsDebugMode
)
if ($IsDebugMode)
{
$IsDebugMode = $true
}
else
{
$IsDebugMode = $false
}
function _LogMessage
{
param(
[string]$Level,
[string]$Message,
[string]$InvocationName
)
$timestamp = Get-Date -Format "HH:mm:ss"
if ($Level -eq "DEBUG" -and -not $IsDebugMode)
{
return
}
switch ($Level)
{
"INFO" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Cyan
}
"DEBUG" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Yellow
}
"WARNING" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor DarkYellow
}
"ERROR" {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message" -ForegroundColor Red
}
default {
Write-Host "$( $Level ): $timestamp - [$InvocationName] $Message"
}
}
}
#region Auth Functions
function Connect-AzureUser
{
<#
Checks if you’re already logged in by calling:
az account show --output json
If this fails, we assume no existing context and prompt interactive login.
#>
try
{
$azContext = $null
try
{
# Attempt to retrieve current context
$azJson = az account show --output json 2>$null
if ($LASTEXITCODE -eq 0 -and $azJson)
{
$azContext = $azJson | ConvertFrom-Json
}
}
catch
{
# Means not currently logged in, so just fall through
}
if ($null -eq $azContext)
{
_LogMessage -Level "INFO" -Message "No existing Azure CLI login found. Authenticating to Azure (interactive)..." -InvocationName $MyInvocation.MyCommand.Name
# Interactive login
$output = az login 2>&1
if ($LASTEXITCODE -ne 0)
{
_LogMessage -Level "ERROR" -Message "Authentication failed: $output" -InvocationName $MyInvocation.MyCommand.Name
throw "Azure CLI interactive login failed."
}
else
{
_LogMessage -Level "INFO" -Message "Authentication successful." -InvocationName $MyInvocation.MyCommand.Name
}
if ($SubscriptionId)
{
_LogMessage -Level "INFO" -Message "Setting subscription to $SubscriptionId..." -InvocationName $MyInvocation.MyCommand.Name
$output = az account set --subscription $SubscriptionId 2>&1
if ($LASTEXITCODE -ne 0)
{
_LogMessage -Level "ERROR" -Message "Subscription set failed: $output" -InvocationName $MyInvocation.MyCommand.Name
throw "Failed to set subscription."
}
}
}
else
{
# Already logged in – optionally set the subscription
_LogMessage -Level "INFO" -Message "Already authenticated to Azure CLI as $($azContext.user.name)." -InvocationName $MyInvocation.MyCommand.Name
}
}
catch
{
_LogMessage -Level "ERROR" -Message "Authentication failed. $($_.Exception.Message)" -InvocationName $MyInvocation.MyCommand.Name
throw
}
}
function Connect-ToAzureSpn
{
param(
[bool]$UseSPN,
[string]$ClientId,
[string]$TenantId,
[string]$ClientSecret,
[string]$FedToken
)
if ($UseSPN -eq $true)
{
_LogMessage -Level "INFO" -Message "Connecting with Service Principal (Client Secret flow)..." -InvocationName $MyInvocation.MyCommand.Name
# Perform SP login using Azure CLI
$output = az login --service-principal --username $ClientId --password $ClientSecret --tenant $TenantId 2>&1
if ($LASTEXITCODE -ne 0)
{
_LogMessage -Level "ERROR" -Message "Service principal authentication failed: $output" -InvocationName $MyInvocation.MyCommand.Name
throw "Azure CLI SPN login failed."
}
if ($SubscriptionId)
{
_LogMessage -Level "INFO" -Message "Setting subscription to $SubscriptionId..." -InvocationName $MyInvocation.MyCommand.Name
$output = az account set --subscription $SubscriptionId 2>&1
if ($LASTEXITCODE -ne 0)
{
_LogMessage -Level "ERROR" -Message "Subscription set failed: $output" -InvocationName $MyInvocation.MyCommand.Name
throw "Failed to set subscription."
}
}
}
elseif ($UseSPN -eq $false)
{
Connect-AzureUser
}
else
{
_LogMessage -Level "ERROR" -Message "Invalid authentication combination. Check parameters." -InvocationName $MyInvocation.MyCommand.Name
throw "Invalid authentication method. Use SPN w/ Secret or Interactive User."
}
}
#endregion
try
{
_LogMessage -Level "INFO" -Message "Starting script..." -InvocationName $MyInvocation.MyCommand.Name
# 1. Connect to Azure using Azure CLI
Connect-ToAzureSpn `
-UseSPN $UseServicePrincipal `
-ClientId $ClientId `
-TenantId $TenantId `
-ClientSecret $ClientSecret
}
catch
{
_LogMessage -Level "ERROR" -Message "A terminating error occurred: $( $_.Exception.Message )" -InvocationName $MyInvocation.MyCommand.Name
exit 1
}
Get Az Policy Assignments
$TenantId = "01b9e453-84bc-4dc5-88de-a97a1fd42455"
$CurrentDir = $(Get-Location).Path
$PolicyFile = "$($CurrentDir)\Policy_Definitions_Assignment.csv"
if(Test-Path $PolicyFile){Remove-Item $PolicyFile -Force}
"PolicyAssignmentName,PolicyDefinitionId" | Out-File $PolicyFile -append -encoding ASCII
function Get-AllPolicyDefinitionAssignments {
param (
[CmdletBinding()]
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory=$true)]
[String]$TenantId = $TenantId
)
Begin {
$PolicyAssignment = $PolicyDefinitionId = ""
Set-AzContext -TenantId $TenantId -Verbose | Out-Null
$allSubscriptions = @()
$allManagementGroups = @()
$allMgAssignments = @()
$allSubAssignments = @()
$allSubscriptions = Get-AzSubscription -TenantId $TenantId -Verbose
$allManagementGroups = Get-AzManagementGroup -Verbose
foreach($item in $allManagementGroups){
$allMgAssignments += @{
Name = $item.DisplayName
Id = $item.Id
Assignments = Get-AzPolicyAssignment -Scope $item.Id -WarningAction SilentlyContinue -Verbose
}
}
foreach($item in $allSubscriptions){
Select-AzSubscription $item -WarningAction SilentlyContinue -Verbose | Set-AzContext -Verbose | Out-Null
$allSubAssignments += @{
Name = $item.Name
Id = $item.Id
Assignments = Get-AzPolicyAssignment -Scope "/subscriptions/$($item.Id)" -IncludeDescendent -WarningAction SilentlyContinue -Verbose
}
}
}
Process {
foreach ($item in $allMgAssignments){
foreach($assignment in $item.Assignments){
[array]$allAssignedDefinitions += $assignment.Properties.PolicyDefinitionId
}
[array]$allAssignedMgDefinitions += @{
Name = $item.Name
Id = $item.Id
Definitions = $allAssignedDefinitions | Select-Object -Unique
}
}
foreach ($item in $allSubAssignments){
$allAssignedDefinitions = @()
foreach($assignment in $item.Assignments){
[array]$allAssignedDefinitions += $assignment.Properties.PolicyDefinitionId
}
[array]$allAssignedSubDefinitions += @{
Name = $item.Name
Id = $item.Id
Definitions = $allAssignedDefinitions | Select-Object -Unique
}
}
foreach($item in $allAssignedMgDefinitions){
$assignments = ($allMgAssignments | Where-Object {$_.Id -eq $item.Id}).Assignments
$matchingAssignments = @()
foreach($definitionId in $item.Definitions){
$matchingAssignments += @{
DefinitionId = $definitionId
Assignments = @(($assignments | Where-Object {$_.Properties.PolicyDefinitionId -eq $definitionId}).ResourceId)
}
}
[array]$mgResults += @{
Name = $item.Name
Id = $item.Id
Policies = $matchingAssignments
}
}
foreach($item in $allAssignedSubDefinitions){
$assignments = ($allSubAssignments | Where-Object {$_.Id -eq $item.Id}).Assignments
$matchingAssignments = @()
foreach($definitionId in $item.Definitions){
$matchingAssignments += @{
DefinitionId = $definitionId
Assignments = @(($assignments | Where-Object {$_.Properties.PolicyDefinitionId -eq $definitionId}).ResourceId)
}
}
[array]$subResults += @{
Name = $item.Name
Id = $item.Id
Policies = $matchingAssignments
}
}
}
End {
foreach($item in $mgResults){
$definitionCount = $item.Policies.Count
$assignmentCount = 0
foreach($policy in $item.Policies){
$assignmentCount += $policy.Assignments.Count
Write-Verbose "[DefinitionId] $($policy.DefinitionId)"
foreach($assignment in $policy.Assignments){
Write-Verbose "[AssignmentId] $($assignment)"
}
}
Write-Verbose "Found '$definitionCount' unique definitions with an active assignmentin Management Group '$($item.Name)' with Id '$($item.Id)'"
Write-Verbose "Found '$assignmentCount' total assignments in Management Group '$($item.Name)' with Id '$($item.Id)'"
}
foreach($item in $subResults){
$definitionCount = $item.Policies.Count
$assignmentCount = 0
foreach($policy in $item.Policies){
$assignmentCount += $policy.Assignments.Count
Write-Verbose "[DefinitionId] $($policy.DefinitionId)"
foreach($assignment in $policy.Assignments){
Write-Verbose "[AssignmentId] $($assignment)"
}
}
Write-Verbose "Found '$definitionCount' unique definitions with an active assignment in Subscription '$($item.Name)' with Id '$($item.Id)'"
Write-Verbose "Found '$assignmentCount' total assignments in Subscription '$($item.Name)' with Id '$($item.Id)'"
}
return @{
managementGroups = $mgResults
subscriptions = $subResults
}
}
}
Connect-AzAccount
$TenantId = $TenantId
$Result = Get-AllPolicyDefinitionAssignments -TenantId $TenantId -Verbose
Bash
Login to Azure (Azure CLI)
#!/usr/bin/env bash
##############################################################################
# Set safe defaults
##############################################################################
set -euo pipefail
##############################################################################
# Default parameter values
##############################################################################
UseServicePrincipal=false
ClientId=""
TenantId=""
ClientSecret=""
SubscriptionId=""
FedToken="" # Not used in current logic, but included for completeness
IsDebugMode=false
##############################################################################
# CLI argument parsing
# You can supply:
# --use-service-principal (true|false)
# --client-id <string>
# --tenant-id <string>
# --client-secret <string>
# --subscription-id <string>
# --fed-token <string>
# --debug (true|false)
##############################################################################
while [[ $# -gt 0 ]]; do
case $1 in
--use-service-principal)
UseServicePrincipal="$2"
shift 2
;;
--client-id)
ClientId="$2"
shift 2
;;
--tenant-id)
TenantId="$2"
shift 2
;;
--client-secret)
ClientSecret="$2"
shift 2
;;
--subscription-id)
SubscriptionId="$2"
shift 2
;;
--fed-token)
FedToken="$2"
shift 2
;;
--debug)
IsDebugMode="$2"
shift 2
;;
*)
echo "Unknown parameter: $1"
exit 1
;;
esac
done
##############################################################################
# Simple colour definitions for console output
##############################################################################
COLOUR_RED='\033[0;31m'
COLOUR_YELLOW='\033[0;33m'
COLOUR_CYAN='\033[0;36m'
COLOUR_RESET='\033[0m'
##############################################################################
# _LogMessage function
# Usage: _LogMessage "DEBUG|INFO|WARNING|ERROR" "Message text" "InvocationName"
##############################################################################
_LogMessage() {
local Level="$1"
local Message="$2"
local InvocationName="$3"
local timestamp
timestamp="$(date +"%H:%M:%S")"
# If it's a DEBUG message but debug mode is off, skip
if [[ "$Level" == "DEBUG" && "$IsDebugMode" != "true" ]]; then
return
fi
local prefix="${Level}: ${timestamp} - [${InvocationName}]"
case "$Level" in
"INFO")
echo -e "${COLOUR_CYAN}${prefix} ${Message}${COLOUR_RESET}"
;;
"DEBUG")
echo -e "${COLOUR_YELLOW}${prefix} ${Message}${COLOUR_RESET}"
;;
"WARNING")
echo -e "${COLOUR_YELLOW}${prefix} ${Message}${COLOUR_RESET}"
;;
"ERROR")
echo -e "${COLOUR_RED}${prefix} ${Message}${COLOUR_RESET}"
;;
*)
echo -e "${prefix} ${Message}"
;;
esac
}
##############################################################################
# Connect-AzureUser
# 1. Check if already logged in (az account show).
# 2. If not, do az login (interactive).
# 3. If SubscriptionId is set, do az account set.
##############################################################################
Connect-AzureUser() {
local InvocationName="Connect-AzureUser"
# Try to see if we have an existing login
if ! az account show --output json &>/dev/null; then
# Not logged in; do interactive login
_LogMessage "INFO" "No existing Azure CLI login found. Authenticating (interactive)..." "$InvocationName"
if ! output=$(az login 2>&1); then
_LogMessage "ERROR" "Authentication failed: $output" "$InvocationName"
return 1
fi
_LogMessage "INFO" "Authentication successful." "$InvocationName"
if [[ -n "$SubscriptionId" ]]; then
_LogMessage "INFO" "Setting subscription to $SubscriptionId..." "$InvocationName"
if ! sub_output=$(az account set --subscription "$SubscriptionId" 2>&1); then
_LogMessage "ERROR" "Subscription set failed: $sub_output" "$InvocationName"
return 1
fi
fi
else
# Already logged in
local currentUser
currentUser=$(az account show --output tsv --query user.name 2>/dev/null || echo "")
_LogMessage "INFO" "Already authenticated to Azure CLI as $currentUser." "$InvocationName"
fi
}
##############################################################################
# Connect-ToAzureSpn
# 1. If UseServicePrincipal == true, do az login --service-principal.
# 2. Otherwise, call Connect-AzureUser for interactive approach.
# 3. If SubscriptionId is set, do az account set.
##############################################################################
Connect-ToAzureSpn() {
local UseSPN="$1"
local ClientId="$2"
local TenantId="$3"
local ClientSecret="$4"
local FedToken="$5" # not used, but we keep for structure
local InvocationName="Connect-ToAzureSpn"
if [[ "$UseSPN" == "true" ]]; then
_LogMessage "INFO" "Connecting with Service Principal (Client Secret flow)..." "$InvocationName"
if ! spn_output=$(az login \
--service-principal \
--username "$ClientId" \
--password "$ClientSecret" \
--tenant "$TenantId" 2>&1); then
_LogMessage "ERROR" "Service principal authentication failed: $spn_output" "$InvocationName"
return 1
fi
if [[ -n "$SubscriptionId" ]]; then
_LogMessage "INFO" "Setting subscription to $SubscriptionId..." "$InvocationName"
if ! sub_output=$(az account set --subscription "$SubscriptionId" 2>&1); then
_LogMessage "ERROR" "Subscription set failed: $sub_output" "$InvocationName"
return 1
fi
fi
elif [[ "$UseSPN" == "false" ]]; then
Connect-AzureUser
else
_LogMessage "ERROR" "Invalid authentication combination. Check parameters." "$InvocationName"
return 1
fi
}
##############################################################################
# Main Logic
##############################################################################
main() {
local InvocationName="main"
_LogMessage "INFO" "Starting script..." "$InvocationName"
# 1. Connect to Azure using Azure CLI
if ! Connect-ToAzureSpn "$UseServicePrincipal" "$ClientId" "$TenantId" "$ClientSecret" "$FedToken"; then
_LogMessage "ERROR" "A terminating error occurred during Connect-ToAzureSpn." "$InvocationName"
exit 1
fi
}
main "$@"
```bash
Source: docs/cheatsheets/azure-cheatsheet.md