Learning Your Environment
// read-only recon · week 1 playbook
The rule: First week — read everything, change nothing. Every command here is a list/show/get. No create, delete, update, assign, or set.
listshowget
createdeleteassign
Day 1
Structure
- List subscriptions
- Management groups
- Resource group naming
- Tags & ownership
Day 2
Networking
- VNETs & address spaces
- Peerings & topology
- NSG rules
- Private endpoints
Day 3
Compute
- VM inventory
- VMSS / scale sets
- Extensions baseline
- Orphaned resources
Day 4
Identity
- RBAC assignments
- Who has Owner?
- Service principals
- Managed identities
Day 5
Monitoring
- Log Analytics WS
- Alert rules
- Diagnostic settings
- Policy assignments
Questions to Ask the Team (Can't Get from CLI)
What broke last month and why? — more valuable than any doc.
What's the deployment process? — IaC pipeline, manual, or someone's script?
Is there a change management process? — or do people just make changes?
Where are the runbooks? — on-call rotation, escalation path.
What monitoring alerts are active? — and who actually gets paged?
Any known technical debt? — every environment has skeletons.
What's the deployment process? — IaC pipeline, manual, or someone's script?
Is there a change management process? — or do people just make changes?
Where are the runbooks? — on-call rotation, escalation path.
What monitoring alerts are active? — and who actually gets paged?
Any known technical debt? — every environment has skeletons.
What Naming Conventions Tell You
prod-eastus-web-vm-01 → mature environment, thought-through naming.
MyVM3 / TestServer / johns-vm → click-ops, no governance, changes are riskier.
No tags on resources → no cost tracking, no ownership — audit this fast.
Everything in one resource group → no environment separation, high blast radius.
MyVM3 / TestServer / johns-vm → click-ops, no governance, changes are riskier.
No tags on resources → no cost tracking, no ownership — audit this fast.
Everything in one resource group → no environment separation, high blast radius.
CLI Commands
// all read-only · safe to runAccount & Structure READ-ONLY
# Who am I logged in as az account show # All subscriptions I have access to az account list --output table # Switch to a specific subscription az account set --subscription "<subscription-id-or-name>" # Management group hierarchy az account management-group list --output table # All resource groups — name, location, tags az group list --query "[].{Name:name, Location:location, Tags:tags}" -o table # All resources in a resource group az resource list -g <resource-group> --query "[].{Name:name, Type:type}" -o table
Networking READ-ONLY
# All VNETs and address spaces az network vnet list --query "[].{Name:name, RG:resourceGroup, Space:addressSpace.addressPrefixes}" -o table # Subnets in a VNET az network vnet subnet list --vnet-name <vnet> -g <rg> --query "[].{Name:name, Prefix:addressPrefix}" -o table # VNET peerings (how VNETs talk to each other) az network vnet peering list --vnet-name <vnet> -g <rg> -o table # All NSGs az network nsg list -o table # NSG rules for a specific NSG az network nsg show -n <nsg-name> -g <rg> --query "securityRules[]" -o table # Private endpoints (signals locked-down architecture) az network private-endpoint list --query "[].{Name:name, RG:resourceGroup, Connection:privateLinkServiceConnections[0].name}" -o table # VPN Gateways (on-prem connectivity) az network vnet-gateway list -o table # Public IPs (anything internet-facing) az network public-ip list --query "[].{Name:name, IP:ipAddress, Associated:ipConfiguration.id}" -o table
Compute — VMs & Scale Sets READ-ONLY
# Full VM inventory — name, size, OS, state, RG az vm list --show-details --query "[].{Name:name, RG:resourceGroup, Size:hardwareProfile.vmSize, OS:storageProfile.osDisk.osType, State:powerState}" -o table # VMs with no tags (unowned resources) az vm list --query "[?tags==null].{Name:name, RG:resourceGroup}" -o table # Extensions installed on a specific VM az vm extension list --vm-name <vm-name> -g <rg> -o table # All VM scale sets az vmss list --query "[].{Name:name, RG:resourceGroup, Capacity:sku.capacity, Tier:sku.tier}" -o table # Stopped/deallocated VMs (cost waste candidates) az vm list --show-details --query "[?powerState=='VM deallocated'].{Name:name, RG:resourceGroup}" -o table # Export full VM list to JSON for audit az vm list --show-details -o json > vm-audit.json
RBAC & Identity READ-ONLY
# My own role assignments az role assignment list --assignee <your-upn@company.com> --all -o table # Everyone with Owner at subscription scope (should be 2-3 max) az role assignment list --role Owner --scope /subscriptions/<sub-id> -o table # All role assignments — full audit az role assignment list --all --query "[].{Principal:principalName, Type:principalType, Role:roleDefinitionName, Scope:scope}" -o table # Role assignments for a specific resource group az role assignment list -g <resource-group> --query "[].{Principal:principalName, Role:roleDefinitionName}" -o table # All role definitions (built-in + custom) az role definition list --query "[].{Name:roleName, Description:description}" -o table # Custom roles only az role definition list --custom-role-only true --query "[].{Name:roleName, Description:description}" -o table # Full permissions of a specific role az role definition list --name "Virtual Machine Contributor" --query "[].permissions[].actions[]" -o tsv # Service principals (app identities) az ad sp list --all --query "[].{Name:displayName, AppId:appId, Enabled:accountEnabled}" -o table # Managed identities az identity list --query "[].{Name:name, RG:resourceGroup, Type:type}" -o table # Export RBAC audit to JSON az role assignment list --all --query "[].{Principal:principalName, Type:principalType, Role:roleDefinitionName, Scope:scope}" -o json > rbac-audit.json
Monitoring & Logs READ-ONLY
# Log Analytics workspaces az monitor log-analytics workspace list --query "[].{Name:name, RG:resourceGroup, Location:location}" -o table # Alert rules az monitor alert list -o table # Activity log — recent changes in subscription az monitor activity-log list --max-events 50 --query "[].{Time:eventTimestamp, Caller:caller, Operation:operationName.localizedValue, Status:status.value}" -o table # Diagnostic settings on a resource az monitor diagnostic-settings list --resource <resource-id> -o table # Azure Policy assignments az policy assignment list --query "[].{Name:name, Policy:policyDefinitionId, Scope:scope}" -o table # Policy compliance state az policy state list --query "[?complianceState=='NonCompliant'].{Resource:resourceId, Policy:policyDefinitionName}" -o table
Key Vault & Storage READ-ONLY
# List all Key Vaults az keyvault list --query "[].{Name:name, RG:resourceGroup, Location:location}" -o table # Key Vault access policies (who has access) az keyvault show -n <vault-name> --query "properties.accessPolicies[].{ObjectId:objectId, Keys:permissions.keys, Secrets:permissions.secrets}" -o table # List secret names (not values — you can't read values with Reader) az keyvault secret list --vault-name <vault-name> --query "[].{Name:name, Enabled:attributes.enabled, Expires:attributes.expires}" -o table # All storage accounts az storage account list --query "[].{Name:name, RG:resourceGroup, Kind:kind, Tier:sku.tier, PublicAccess:allowBlobPublicAccess}" -o table # Storage accounts with public blob access (security risk) az storage account list --query "[?allowBlobPublicAccess==true].{Name:name, RG:resourceGroup}" -o table
AuthorizationFailed error? That just means your role doesn't cover that scope — Azure blocks it, no damage done. Common with
az ad sp list --all which needs Entra Directory Reader, separate from Azure subscription Reader.
Core Concepts
// reference while learningAzure Resource Hierarchy
Everything in Azure lives in this hierarchy. RBAC and Policy assigned at any level inherit downward.
Management Group
— groups multiple subscriptions; top-level governance
Subscription
— billing boundary; usually separated by env or business unit
Resource Group
— logical container; lifecycle boundary (delete RG = delete everything in it)
Resource
— actual thing: VM, VNET, Storage Account, Key Vault, etc.
Key insight: A role assigned at Subscription scope applies to all Resource Groups and Resources inside it. A role at Resource Group scope only applies within that RG. This is how you grant "view everything" vs "manage only this one app's resources."
RBAC — Role-Based Access Control
What it is: The system controlling who can do what to which Azure resources.
Three components of every assignment:
Security Principal — who: user, group, service principal, or managed identity
Role Definition — what: a collection of allowed/denied actions
Scope — where: management group, subscription, resource group, or resource
Most common built-in roles:
Three components of every assignment:
Security Principal — who: user, group, service principal, or managed identity
Role Definition — what: a collection of allowed/denied actions
Scope — where: management group, subscription, resource group, or resource
Most common built-in roles:
| Role | What it can do | Typical use |
|---|---|---|
| Owner | Everything, including grant access to others | 2-3 admins max at sub scope |
| Contributor | Create/manage all resources, cannot grant access | DevOps teams, automation |
| Reader | View everything, change nothing | Auditors, new hires recon |
| User Access Administrator | Manage access only, cannot touch resources | IAM team delegation |
| VM Contributor | Manage VMs, not the VNET or storage they're on | Ops teams |
| Network Contributor | Manage networking resources | Network team |
| Key Vault Reader | View vault metadata, not secret values | Auditors |
Entra roles ≠ Azure resource roles. "Global Reader" in Entra ID controls reading directory objects (users, groups, apps). "Reader" in Azure controls reading Azure resources (VMs, storage, etc.). They're separate systems that overlap but don't replace each other.
Entra ID (formerly Azure Active Directory)
What it is: Microsoft's cloud identity platform. Every person, app, or service that authenticates to Azure goes through Entra ID.
Key objects you'll deal with:
Key objects you'll deal with:
| Object | What it is | What to watch for |
|---|---|---|
| User | A person's identity | Guest users with high permissions, stale accounts |
| Group | Collection of users; assign roles to group not individuals | Nested groups, old groups with no members |
| Service Principal | Identity for an application or automation | Expired credentials, overprivileged SPs, orphaned ones |
| Managed Identity | Auto-managed SP; no password to rotate | Preferred over service principals — use this when possible |
| App Registration | Registers an app in the tenant so it can authenticate | Old apps nobody owns, excessive API permissions |
| Conditional Access | Rules that control when/how auth succeeds | MFA requirements, compliant device policies |
Managed Identity vs Service Principal: A Service Principal needs a secret or certificate that expires and must be rotated. A Managed Identity is handled entirely by Azure — no password, no rotation headache. If you see apps still using SP passwords, that's technical debt worth flagging.
Networking — The Skeleton
| Concept | What it is | Key fact |
|---|---|---|
| VNET | Virtual network — isolated address space in Azure | VMs in the same VNET can talk by default |
| Subnet | Subdivision of a VNET; NSGs attach here | Separate subnets = separate blast radius |
| NSG | Network Security Group — stateful firewall rules | Applied at subnet or NIC level; last-rule-wins |
| VNET Peering | Connects two VNETs directly | Not transitive — A↔B, B↔C does NOT mean A↔C |
| Private Endpoint | Brings a PaaS service (like Storage) into your VNET | Traffic never leaves Azure backbone |
| VPN Gateway | Encrypted tunnel to on-premises | Site-to-site or point-to-site |
| ExpressRoute | Dedicated private connection to Azure (not internet) | Faster, more reliable, more expensive than VPN |
| Hub-Spoke | Topology: central hub VNET with spoke VNETs peered to it | Shared services (firewall, DNS) live in hub |
| UDR | User-Defined Route — force traffic through a specific path | Used to route all traffic through a firewall |
Monitoring Stack
| Service | What it does | Think of it as |
|---|---|---|
| Azure Monitor | Umbrella for all monitoring data | The platform everything reports to |
| Log Analytics | Centralized log storage; query with KQL | Your log database + query engine |
| KQL | Kusto Query Language — query logs | SQL but for logs; quick to learn |
| Metrics | Numeric time-series data (CPU %, memory, etc.) | Grafana-style dashboards |
| Alerts | Rules that fire when a metric/log crosses a threshold | PagerDuty equivalent |
| Diagnostic Settings | Configure what a resource sends to Log Analytics | Per-resource logging toggle |
| Activity Log | Audit trail of every control-plane change | "Who changed what and when" |
| Azure Policy | Rules enforced on resources (deny, audit, auto-fix) | Governance guardrails |
Mnemonics
// memory hooks for Azure concepts
"Many Silly Rabbits Run"
// Azure Resource Hierarchy — top to bottom
M
Management Groups
Top-level governance containers. Apply policy & RBAC here to cascade everywhere below.
S
Subscriptions
Billing & isolation boundary. Usually split by env (prod/dev) or business unit.
R
Resource Groups
Logical bucket for related resources. Delete the group = delete everything in it.
R
Resources
The actual stuff: VMs, VNETs, Storage Accounts, Key Vaults, etc.
"Pretty Smart Sysadmins"
// The 3 parts of every RBAC assignment
P
Principal
Who — user, group, service principal, or managed identity.
S
Scope
Where — management group, subscription, resource group, or resource.
S
Set (Role Definition)
What — the collection of allowed/denied actions. Owner, Contributor, Reader, or custom.
"Very Spicy Noodles Perfectly Verify Everything"
// Core networking objects — recon order
V
VNETs
The address spaces — what IP ranges exist and where.
S
Subnets
How each VNET is divided — workloads live in subnets.
N
NSGs
The firewall rules — what traffic is allowed/blocked.
P
Peerings
How VNETs connect to each other. Not transitive.
V
VPN/ExpressRoute
On-prem connectivity. VPN = internet tunnel. ExpressRoute = dedicated line.
E
Endpoints (Private)
PaaS services pulled inside the VNET. Sign of mature security posture.
"Good Sysadmins Make Apps"
// Entra ID identity object types
G
Groups
Assign roles to groups, not individuals. Easier to manage at scale.
S
Service Principals
App identity with a password or cert. Needs manual rotation. Old pattern.
M
Managed Identities
Auto-managed app identity. No password to rotate. Modern, preferred pattern.
A
App Registrations
Registers an external app with the tenant so it can authenticate via OAuth/OIDC.
"All Logs Keep Metrics Alerting Daily"
// Azure Monitor stack — what feeds what
A
Azure Monitor
The umbrella platform everything flows into.
L
Log Analytics
The log database. Everything queries through here.
K
KQL
The query language. Like SQL for logs — learn this early.
M
Metrics
Numeric time-series. CPU, memory, disk — the dashboard numbers.
A
Alerts
Rules that page/email/webhook when thresholds are crossed.
D
Diagnostic Settings
Per-resource toggle: what gets sent to Log Analytics.
"Low Numbers Win, High Numbers Lose"
// NSG rule priority — lower number = higher priority
NSG rules are numbered 100–4096. Rule 100 beats rule 200 — lower number wins. Azure processes rules from lowest to highest and stops at the first match. The default rules at 65000+ (AllowVnetInBound, DenyAllInbound) are always there at the bottom as a backstop. When you see a rule at 100 that allows something and a rule at 200 that denies it — the allow wins.
"Peering is NOT a Chain"
// VNET peering is not transitive
If VNET-A is peered to VNET-B, and VNET-B is peered to VNET-C — VNET-A CANNOT talk to VNET-C. Peering is a direct 1-to-1 link, not a network. To connect A to C, you need an explicit peering between A and C, or route through a hub with a firewall/NVA (Network Virtual Appliance). This trips up most people new to Azure networking.
Intune — Learning Your MDM Environment
// device management reconWhat Intune Is
Microsoft Intune is the MDM (Mobile Device Management) and MAM (Mobile Application Management) platform in Microsoft 365. It controls what devices can access company resources, what apps are deployed, and enforces security baselines.
Think of it as Group Policy for the cloud — except it works on Windows, macOS, iOS, Android, and Linux without requiring domain join.
Think of it as Group Policy for the cloud — except it works on Windows, macOS, iOS, Android, and Linux without requiring domain join.
Device
Win/Mac/iOS/Android
→
Enrollment
Joins Intune via Entra ID
→
Config Profiles
Settings pushed to device
→
Compliance
Pass/Fail policies
→
Conditional Access
Compliant = gets in
What to Read First in Intune (Intune Portal → intune.microsoft.com)
1. Devices → All Devices
→ How many devices are enrolled? Windows vs Mac vs mobile?
→ Are there stale devices (last check-in months ago)?
→ Compliance status — what % are compliant vs non-compliant?
2. Devices → Configuration Profiles
→ What settings are being pushed? (Wi-Fi, VPN, certificates, BitLocker)
→ Are profiles assigned to groups or all devices?
→ Any profiles with errors or assignment failures?
3. Devices → Compliance Policies
→ What are the pass/fail rules? (min OS version, BitLocker required, etc.)
→ What happens on non-compliance? (block access, notify, grace period?)
→ Are compliance policies linked to Conditional Access?
4. Apps → All Apps
→ What apps are deployed via Intune?
→ Required vs Available — required installs automatically, available is self-service
→ Any apps with high failure rates?
5. Endpoint Security → Security Baselines
→ Are Microsoft Security Baselines applied? (pre-built hardened settings)
→ Defender for Endpoint integration active?
→ Firewall and Antivirus profiles deployed?
6. Tenant Administration → Enrollment
→ How are devices enrolled? (Autopilot, BYOD, manual, bulk?)
→ Is Windows Autopilot configured? (means new laptops self-configure out of box)
→ Enrollment restrictions — who can enroll, what device types are allowed?
→ How many devices are enrolled? Windows vs Mac vs mobile?
→ Are there stale devices (last check-in months ago)?
→ Compliance status — what % are compliant vs non-compliant?
2. Devices → Configuration Profiles
→ What settings are being pushed? (Wi-Fi, VPN, certificates, BitLocker)
→ Are profiles assigned to groups or all devices?
→ Any profiles with errors or assignment failures?
3. Devices → Compliance Policies
→ What are the pass/fail rules? (min OS version, BitLocker required, etc.)
→ What happens on non-compliance? (block access, notify, grace period?)
→ Are compliance policies linked to Conditional Access?
4. Apps → All Apps
→ What apps are deployed via Intune?
→ Required vs Available — required installs automatically, available is self-service
→ Any apps with high failure rates?
5. Endpoint Security → Security Baselines
→ Are Microsoft Security Baselines applied? (pre-built hardened settings)
→ Defender for Endpoint integration active?
→ Firewall and Antivirus profiles deployed?
6. Tenant Administration → Enrollment
→ How are devices enrolled? (Autopilot, BYOD, manual, bulk?)
→ Is Windows Autopilot configured? (means new laptops self-configure out of box)
→ Enrollment restrictions — who can enroll, what device types are allowed?
Key Intune Concepts
| Concept | What it is | What to check |
|---|---|---|
| Enrollment | The process of registering a device with Intune | How it's triggered; Autopilot vs manual vs BYOD |
| Configuration Profile | Settings pushed to a device (like GPO) | Assignment groups, success/failure rate |
| Compliance Policy | Rules a device must meet to be "compliant" | What triggers non-compliance, grace period length |
| Conditional Access | Entra ID gate — compliant device = access granted | Which apps require compliant device, which don't |
| Autopilot | Zero-touch Windows provisioning OOB | Is it set up? What profile do new machines get? |
| Required App | Pushed automatically to assigned devices | Deployment failure rate per app |
| Available App | User can install from Company Portal | Self-service catalog of approved software |
| Security Baseline | Pre-built hardened settings from Microsoft | Which baseline version, what's overridden |
| Hybrid Join | Device is both domain-joined AND Entra-joined | Common in enterprise — means legacy AD + modern cloud |
| Entra Joined | Device joined only to Entra ID (cloud-only) | Modern setup; no on-prem AD dependency |
Intune via Microsoft Graph CLI READ-ONLY
Intune doesn't have a full
az CLI. Use Microsoft Graph CLI (mgc) or PowerShell.
# Install Graph CLI (one-time) dotnet tool install --global Microsoft.Graph.Cli # Or use PowerShell module Install-Module Microsoft.Graph -Scope CurrentUser Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All" # List all managed devices Get-MgDeviceManagementManagedDevice -All | Select-Object DeviceName, OperatingSystem, ComplianceState, LastSyncDateTime # Non-compliant devices Get-MgDeviceManagementManagedDevice -Filter "complianceState eq 'noncompliant'" | Select-Object DeviceName, UserDisplayName, LastSyncDateTime # List configuration profiles Get-MgDeviceManagementDeviceConfiguration -All | Select-Object DisplayName, OdataType, LastModifiedDateTime # List compliance policies Get-MgDeviceManagementDeviceCompliancePolicy -All | Select-Object DisplayName, OdataType # List deployed apps Get-MgDeviceAppManagementMobileApp -All | Select-Object DisplayName, OdataType, PublishingState # Devices that haven't checked in for 30+ days (stale) $cutoff = (Get-Date).AddDays(-30) Get-MgDeviceManagementManagedDevice -All | Where-Object { $_.LastSyncDateTime -lt $cutoff } | Select-Object DeviceName, UserDisplayName, LastSyncDateTime
"Every Compliant Computer Accesses Safely"
// The Intune flow in order
E
Enrollment
Device registers with Intune (manual, Autopilot, BYOD).
C
Configuration Profiles
Settings pushed to device — Wi-Fi, VPN, certs, BitLocker, etc.
C
Compliance Policies
Pass/fail check — is the device meeting security requirements?
A
App Deployment
Required apps pushed automatically; available apps in Company Portal.
S
Security + Conditional Access
Compliant device = access granted. Non-compliant = blocked from resources.