Full Code of timothywarner/az500 for AI

main 6902b2fec1d2 cached
235 files
11.4 MB
144.7k tokens
1 requests
Download .txt
Showing preview only (652K chars total). Download the full file or copy to clipboard to get everything.
Repository: timothywarner/az500
Branch: main
Commit: 6902b2fec1d2
Files: 235
Total size: 11.4 MB

Directory structure:
gitextract_20_50j8_/

├── .github/
│   └── workflows/
│       └── check-readme-links.yml
├── .gitignore
├── AZ-500-Teaching-Punchlist.md
├── AZ-500-cert-study-resources.md
├── AZ-500-course-plan.md
├── GETTING-STARTED.md
├── LICENSE
├── README.md
├── az104-README.md
├── az500-objective-domain.md
├── azure-cli.azcli
├── azure-policy.json
├── azure-powershell.ps1
├── code-samples/
│   ├── README.md
│   ├── bicep/
│   │   └── deployment.bicep
│   ├── cli/
│   │   └── azure-cli.azcli
│   ├── json/
│   │   ├── azure-policy.json
│   │   ├── custom-rbac-role.json
│   │   └── deployment.json
│   ├── kusto/
│   │   └── kusto.kql
│   └── powershell/
│       └── azure-powershell.ps1
├── custom-rbac-role.json
├── deployment.bicep
├── deployment.json
├── docs/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   └── SECURITY.md
├── images/
│   └── visio/
│       ├── AZ-500.vsdx
│       ├── az300-topology.vsdx
│       ├── azure-classroom-reference-diagram.vsdx
│       └── drawings.vsdx
├── kusto.kql
├── labs/
│   ├── LAB-SETUP.md
│   └── README.md
├── scripts/
│   ├── blueprints/
│   │   ├── basic-networking-blueprint/
│   │   │   ├── Artifacts/
│   │   │   │   ├── 7ddd6a5f-4815-4526-aa69-40bbffd263d3.json
│   │   │   │   ├── 7ddd6a5f-4815-4526-aa69-40bbffd26cc7.json
│   │   │   │   ├── nsg-template.json
│   │   │   │   └── vnet-and-subnet-template.json
│   │   │   └── Blueprint.json
│   │   ├── blueprints-references.txt
│   │   ├── blueprints.ps1
│   │   ├── sample-blueprint/
│   │   │   ├── artifacts/
│   │   │   │   ├── policyStorageTags.json
│   │   │   │   ├── policyTags.json
│   │   │   │   ├── roleContributor.json
│   │   │   │   ├── roleOwner.json
│   │   │   │   ├── templateStorage.json
│   │   │   │   └── templateStorageParams.json
│   │   │   ├── blueprint.json
│   │   │   └── blueprintAssignment.json
│   │   ├── warner-azure-blueprints.pptx
│   │   └── warner-azure-blueprints.ps1
│   ├── key-vault.azcli
│   ├── powershell/
│   │   ├── Dockerfile.txt
│   │   ├── Update-AutomationAzureModulesForAccount.ps1
│   │   ├── aad-pim-powershell.ps1
│   │   ├── app-gateway-e2e-tls.ps1
│   │   ├── application-security-groups.ps1
│   │   ├── azcopy.txt
│   │   ├── azure-key-vault-powershell.ps1
│   │   ├── azuresql-database-tde.ps1
│   │   ├── backup-key-vault.ps1
│   │   ├── convert-vhd.ps1
│   │   ├── cosmos-container-rbac.ps1
│   │   ├── create-aks-cluster.ps1
│   │   ├── create-azure-bastion.ps1
│   │   ├── create-key-vault.ps1
│   │   ├── custom-azure-rbac-role.ps1
│   │   ├── custom-rbac-role.ps1
│   │   ├── customscriptextension.ps1
│   │   ├── enable-azuresql-database-tde.ps1
│   │   ├── enforce-tag-value-rg.json
│   │   ├── installWebServer.ps1
│   │   ├── linux-vm-ssh-keys.ps1
│   │   ├── managed-storage-account.ps1
│   │   ├── networking.ps1
│   │   ├── password-reset.ps1
│   │   ├── policy-enforce-tag-value-rg.json
│   │   ├── powershell-key-vault.ps1
│   │   ├── storage-account.ps1
│   │   ├── taxonomic-tags.ps1
│   │   ├── validate-deploy-arm-template.ps1
│   │   ├── vm-key-vault.parameters.json
│   │   ├── vm-key-vault.template.json
│   │   ├── vnet-peering.ps1
│   │   └── webjob.ps1
│   └── sql/
│       ├── azure-sql-database-firewall-rules.sql
│       ├── azure-sql-row-level-security.sql
│       └── azuresql-database-firewall.sql
├── study-resources/
│   ├── AZ-500-Teaching-Punchlist.md
│   ├── AZ-500-cert-study-resources.md
│   ├── AZ-500-course-plan.md
│   └── README.md
├── templates/
│   ├── 101-aci-vnet/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-aks/
│   │   ├── .ci_skip
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-application-gateway-v2-autoscale-create/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-functions-managed-identity/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-storage-account-create/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-vm-simple-windows/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-webapp-basic-windows/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 201-2-vms-loadbalancer-lbrules/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 201-sql-auditing-server-policy-to-blob-storage/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── AZ-300/
│   │   ├── AKS/
│   │   │   ├── AKS.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── AZ-300.sln
│   │   ├── App-Gateway/
│   │   │   ├── App-Gateway.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── AppService+Container/
│   │   │   ├── AppService+Container.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── Deploy-AzureResourceGroup.ps1
│   │   ├── Deployment.targets
│   │   ├── KeyVault/
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── KeyVault.deployproj
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── README.md
│   │   ├── VM Copy Loops.deployproj
│   │   ├── WebApp+SQL/
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── WebApp+SQL.deployproj
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── azuredeploy.json
│   │   └── azuredeploy.parameters.json
│   ├── Basic-ACR-AKS-Blueprint/
│   │   ├── Artifacts/
│   │   │   ├── 16985fcd-e84e-4310-8306-45c89bccc429.json
│   │   │   ├── 31e3b372-1efb-42e8-ac45-d938d00212d6.json
│   │   │   ├── 397ca67f-80f5-4da5-9484-f71ce2f58030.json
│   │   │   ├── a369d0c9-ab75-42b2-8677-2adb34f2757c.json
│   │   │   ├── d8a78686-485d-4956-96a6-64f305a7f822.json
│   │   │   ├── d8c28060-2804-4421-bed1-f61a5f456183.json
│   │   │   └── f465a2a1-0e85-439b-a9ac-3dcf94e066cf.json
│   │   └── Blueprint.json
│   ├── active-directory-new-domain-ha-2-dc/
│   │   ├── .gitignore
│   │   ├── DSC/
│   │   │   ├── ConfigureADBDC.ps1
│   │   │   ├── CreateADPDC.ps1
│   │   │   └── PrepareADBDC.ps1
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   ├── metadata.json
│   │   └── nestedtemplates/
│   │       ├── configureADBDC.json
│   │       ├── nic.json
│   │       ├── vnet-with-dns-server.json
│   │       └── vnet.json
│   ├── customscriptext.json
│   ├── customscriptext.param.json
│   ├── docker-containers.azcli
│   ├── generative-ai/
│   │   ├── azurecli.azcli
│   │   ├── azuredeploy.json
│   │   ├── kusto.kql
│   │   ├── main.bicep
│   │   └── powershell.ps1
│   ├── virtual-network/
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   ├── hub-vnet.bicep
│   │   └── vnets-deploy.bicep
│   └── ~arm-templates/
│       ├── S2S-VPN/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── app service-cosmos/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── application-gateway/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── azure-sql-aworks/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── bastion/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── container-registry/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── event-hub/
│       │   ├── eventhub.json
│       │   └── eventhub.parameters.json
│       ├── firewall/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── iot-hub/
│       │   ├── iothub.json
│       │   └── iothub.parameters.json
│       ├── linux-vm-password/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── linux-vm-ssh/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── load-balancer/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── multiple-vms/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── new-AD-forest/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── private-dns-zone/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── traffic-manager/
│       │   ├── trafficmanager.json
│       │   └── trafficmanager.parameters.json
│       ├── virtual-network/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       └── windows-vm-cse/
│           ├── azuredeploy.json
│           └── azuredeploy.parameters.json
└── warner-AZ500.pptx

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/check-readme-links.yml
================================================
name: Check Markdown Links

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  check-links:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check Links 🔍
        id: lychee
        uses: lycheeverse/lychee-action@v1.9.3
        with:
          args: --verbose --no-progress './*.md'
          fail: true
          format: markdown
          output: ./lychee/out.md
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Create Issue From File
        if: steps.lychee.outputs.exit_code != 0
        uses: peter-evans/create-issue-from-file@v4
        with:
          title: Link Checker Report 🔗
          content-filepath: ./lychee/out.md
          labels: report, automated issue
          body: |
            A link checker scan has found broken links in the repository's markdown files.
            
            ### Files Scanned
            - All markdown (*.md) files in the root directory
            
            ### Results
            See below for the detailed report of broken links:

================================================
FILE: .gitignore
================================================
# gcc coverage testing tool files

*.gcno
*.gcda
*.gcov
~$warner-AZ500.pptx
az500.code-workspace


================================================
FILE: AZ-500-Teaching-Punchlist.md
================================================
# AZ-500 Teaching Punchlist

## Segment 1: Identity and Access (10 AM - 11 AM)
- **Manage Entra Identities**
  - Users, groups, external identities
  - Entra ID Protection: MFA, passwordless, Conditional Access
  - Single sign-on (SSO), OAuth, and app registrations
  - Privileged Identity Management (PIM), custom roles, and permissions

## Segment 2: Secure Storage (11 AM - 12 PM)
- **Plan and Implement Storage Security**
  - Access control: Azure Blob, File, Table, Queue
  - Protect data: soft delete, versioning, immutable storage
  - Encryption: BYOK, double encryption, TDE (databases)
  - Auditing and compliance: Purview and dynamic masking

## Segment 3: Secure Compute (12 PM - 1 PM)
- **Plan and Implement Compute Security**
  - Azure Bastion, Just-in-Time (JIT) VM access
  - AKS security: network isolation, monitoring, and authentication
  - Disk encryption: ADE, encryption at host, confidential disk encryption

## Segment 4: Monitoring and Security Operations (1 PM - 2 PM)
- **Monitor and Secure Operations**
  - Microsoft Defender: Secure Score, compliance, and threat protection
  - Azure Key Vault: manage secrets, certificates, and keys
  - Azure Monitor: configure and evaluate alerts
  - Microsoft Sentinel: analytics, incidents, and automation

## Segment 5: Wrap-up and Q&A (2 PM - 3 PM)
- **Q&A and Additional Topics**
  - Recap of key topics: identity, storage, compute, and monitoring
  - Answer audience questions
  - Explore real-world use cases and advanced scenarios


================================================
FILE: AZ-500-cert-study-resources.md
================================================
# Exam AZ-500 Certification Study Resources

Last updated: March 2024

## Official Microsoft Learning Resources

* [AZ-500 Exam Page](https://learn.microsoft.com/en-us/certifications/exams/az-500)
* [Microsoft Learn AZ-500 Learning Paths](https://learn.microsoft.com/en-us/credentials/certifications/azure-security-engineer/)
* [Official Microsoft Practice Assessment](https://learn.microsoft.com/en-us/credentials/certifications/azure-security-engineer/practice/assessment)
* [Microsoft Security Technical Documentation](https://learn.microsoft.com/en-us/security/)
* [Microsoft Security Blog](https://www.microsoft.com/security/blog/)
* [Azure Security Center Documentation](https://learn.microsoft.com/en-us/azure/defender-for-cloud/)
* [Microsoft Defender for Cloud Documentation](https://learn.microsoft.com/en-us/azure/defender-for-cloud/)
* [Microsoft Sentinel Documentation](https://learn.microsoft.com/en-us/azure/sentinel/)

## Hands-on Labs & Practice

* [Microsoft Learn Labs](https://learn.microsoft.com/en-us/training/paths/manage-security-operations/)
* [Official AZ-500 Lab Exercises](https://microsoftlearning.github.io/AZ-500-AzureSecurityTechnologies/)
* [Microsoft Azure Free Account](https://azure.microsoft.com/free/)
* [Azure Citadel Security Labs](https://www.azurecitadel.com/security/)
* [Azure Log Analytics Query Playground](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/log-analytics-tutorial)

## Practice Exams & Test Prep

* [MeasureUp AZ-500 Practice Tests](https://www.measureup.com/az-500-microsoft-azure-security-technologies.html)
* [Whizlabs AZ-500 Practice Tests](https://www.whizlabs.com/microsoft-azure-certification-az-500/)

## Essential Tools

* [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/)
* [Azure PowerShell](https://learn.microsoft.com/en-us/powershell/azure/)
* [Azure Storage Explorer](https://azure.microsoft.com/features/storage-explorer/)
* [Microsoft Entra ID Portal](https://entra.microsoft.com/)
* Visual Studio Code Extensions:
  * [Azure Account](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
  * [Azure Security Center](https://marketplace.visualstudio.com/items?itemName=ms-azuresecurity.vscode-azuresecurity)
  * [Azure CLI Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azurecli)
  * [PowerShell](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)

## Security Community Resources

* [Microsoft Security Community](https://techcommunity.microsoft.com/t5/security-compliance-and-identity/ct-p/SecurityComplianceIdentity)
* [Azure Security Center Community](https://techcommunity.microsoft.com/t5/azure-security-center/bd-p/AzureSecurityCenter)
* [Microsoft Security Update Guide](https://msrc.microsoft.com/update-guide/)
* [Azure Security Podcast](https://azsecuritypodcast.net/)

## Exam Preparation Tips

* Focus on hands-on experience with Azure security features
* Practice implementing security controls across different Azure services
* Understand identity and access management deeply
* Master Azure security tools and monitoring capabilities
* Review real-world security scenarios and best practices

================================================
FILE: AZ-500-course-plan.md
================================================
# AZ-500 Crash Course: Key Discussion and Demo Topics

## Course Structure
- **Duration:** 5 hours (4 segments of ~1 hour each, 8 min break at the top of each hour)
- **Focus:** Concise discussion and demos of core AZ-500 topics
- **Style:** Interactive and practical 

---

## 🔐 Segment 1: Secure Identity and Access (15-20%)
- **🔑 Microsoft Entra Management**  
  - Manage security controls for identity and access
  - Implement multi-factor authentication (MFA)  
  - Configure Conditional Access policies  
  - Plan and manage resources in Privileged Identity Management

- **🗝️ Role Management**  
  - Manage Azure built-in role assignments
  - Create and manage custom roles
  - Implement Microsoft Entra Permissions Management

- **🔐 Application Access**  
  - Manage access to enterprise applications in Microsoft Entra ID  
  - Configure app registration permission scopes and consent
  - Manage and use service principals
  - Configure managed identities for Azure resources  

---

## 🌐 Segment 2: Secure Networking (20–25%)
- **🔒 Virtual Network Security**  
  - Configure Network Security Groups (NSGs) and Application Security Groups (ASGs)  
  - Manage networks with Azure Virtual Network Manager
  - Plan and implement user-defined routes (UDRs)
  - Configure VPN connectivity and peering
  - Implement Virtual WAN with secured virtual hub
  - Monitor security with Network Watcher  

- **🛡️ Private Access**  
  - Plan and implement virtual network Service Endpoints
  - Configure Private Endpoints and Private Link services  
  - Implement network integration for App Service and Functions
  - Configure network security for App Service Environment
  - Secure Azure SQL Managed Instance

- **🚀 Public Access Security**  
  - Implement TLS for applications
  - Configure Azure Firewall and Firewall Manager
  - Deploy Azure Application Gateway and Azure Front Door
  - Implement Web Application Firewall (WAF)  
  - Deploy Azure DDoS Protection Standard  

---

## 💾 Segment 3: Secure Compute, Storage, and Databases (20–25%)
- **🖥️ Compute Security**  
  - Configure remote access with Azure Bastion and just-in-time VM access
  - Secure Azure Kubernetes Service (AKS)
  - Configure security monitoring for containers (ACI, ACA)
  - Manage access to Azure Container Registry (ACR)
  - Implement disk encryption options
  - Secure Azure API Management

- **🗄️ Storage Security**  
  - Configure access control for storage accounts  
  - Manage storage account access keys
  - Configure secure access for Azure Files and Blob Storage
  - Protect data with soft delete, backups, versioning, and immutable storage
  - Configure Bring Your Own Key (BYOK)
  - Enable double encryption at the Azure Storage infrastructure level

- **📊 Database Security**  
  - Enable Microsoft Entra database authentication
  - Configure database auditing and dynamic masking
  - Implement Transparent Data Encryption (TDE)  
  - Configure Azure SQL Database Always Encrypted

---

## 🔍 Segment 4: Secure Azure using Microsoft Defender for Cloud and Microsoft Sentinel (30–35%)
- **⚙️ Cloud Governance Policies**  
  - Create and assign Azure Policy initiatives
  - Configure Key Vault network settings and access control
  - Manage certificates, secrets, and keys
  - Configure key rotation
  - Implement backup/recovery for sensitive data
  - Configure security controls for asset management

- **🛠️ Security Posture Management**  
  - Work with Microsoft Defender for Cloud Secure Score
  - Assess compliance against security frameworks
  - Manage compliance standards
  - Connect hybrid and multi-cloud environments
  - Implement Microsoft Defender External Attack Surface Management (EASM)

- **🔒 Threat Protection**  
  - Enable Microsoft Defender workload protection services
  - Configure Defender for Servers, Databases, and Storage
  - Implement agentless scanning for VMs
  - Configure Defender Vulnerability Management
  - Connect DevOps security for GitHub, Azure DevOps, and GitLab

- **📈 Security Monitoring and Automation**  
  - Manage security alerts in Defender for Cloud
  - Configure workflow automation
  - Set up data collection rules (DCRs) in Azure Monitor
  - Configure Microsoft Sentinel data connectors and analytics
  - Implement Microsoft Sentinel automation

---

## Resources
- [🔗 Microsoft Learn AZ-500 Documentation](https://learn.microsoft.com/en-us/certifications/exams/az-500/)
- [🛠️ GitHub for Azure Security](https://github.com/topics/azure-security)
- [🎥 Azure Security Demos](https://azure.microsoft.com/en-us/resources/videos/)

### Good luck, and let's secure the cloud! 🚀

## 🎯 Demo Scenario: Securing a Multi-tier Application
Follow along with this scenario to practice key security concepts covered in the course.

### Scenario Overview
You're a security engineer at Contoso Ltd, tasked with securing a new three-tier application:
- Web frontend (Azure App Service)
- API layer (Azure Functions) 
- Database (Azure SQL)

### 🔄 Implementation Steps

#### 1. Identity & Access Setup (30 mins)
- Configure Microsoft Entra authentication for the web app
- Set up managed identities for service-to-service communication
- Implement Conditional Access policy for admin access
- Configure Privileged Identity Management for just-in-time admin access

#### 2. Network Security (30 mins)
- Create network isolation using VNets, NSGs, and ASGs
- Implement Private Endpoints for the database
- Set up Azure Application Gateway with WAF
- Configure Azure Front Door with CDN

#### 3. Data Protection (30 mins)
- Enable TDE and Always Encrypted for sensitive data
- Configure Key Vault with RBAC and network restrictions
- Implement immutable storage and soft delete
- Configure double encryption for storage

#### 4. Security Monitoring & Protection (30 mins)
- Set up Microsoft Defender for Cloud workload protections
- Configure Microsoft Sentinel data connectors and analytics rules
- Create automation workflows for common security incidents
- Implement vulnerability scanning and management

### 🎯 Success Criteria
- ✅ All services use managed identities for authentication
- ✅ Private network connectivity between services
- ✅ All sensitive data encrypted at rest and in transit
- ✅ Comprehensive detection and response capabilities

## Additional Resources

### 🔨 Practice Labs
- [Azure Security Labs on Microsoft Learn](https://learn.microsoft.com/en-us/certifications/exams/az-500)
- [Whizlabs AZ-500 Hands-on Labs](https://www.whizlabs.com/blog/top-azure-hands-on-labs/)
- [Azure GOAT - Vulnerable Azure Environment for Practice](https://github.com/Akriti-S/AzGOAT)
- [425Show Secure Azure Function Samples](https://github.com/425show/SecureAzureFunctionMiW)

### 📚 Documentation
- [Azure Security Best Practices](https://learn.microsoft.com/en-us/azure/security/fundamentals/best-practices-and-patterns)
- [Microsoft Security Documentation](https://learn.microsoft.com/en-us/security/)
- [Azure Architecture Center - Security](https://learn.microsoft.com/en-us/azure/architecture/framework/security/overview)

### 🎥 Video Resources
- [Microsoft Security YouTube Channel](https://www.youtube.com/c/MicrosoftSecurity)
- [Azure Security Center in Action](https://www.youtube.com/playlist?list=PLLasX02E8BPBxGouWlJV-u_XVcXfkdscl)


================================================
FILE: GETTING-STARTED.md
================================================
# Getting Started with AZ-500 Course Materials

Welcome to the AZ-500 Microsoft Azure Security Technologies Crash Course! This guide will help you navigate the repository structure and make the most of these learning resources.

## Repository Structure

This repository is organized into several key directories:

- **[code-samples/](code-samples/)** - Security-focused code examples in Bicep, JSON, PowerShell, CLI, and KQL
- **[study-resources/](study-resources/)** - Additional study materials and exam preparation guides
- **[labs/](labs/)** - Hands-on lab exercises to practice security implementations
- **[images/](images/)** - Diagrams and visual aids for security concepts
- **[templates/](templates/)** - ARM templates and deployment examples
- **[scripts/](scripts/)** - Utility scripts for security configurations

## How to Use This Repository

### For Self-Study
1. Start with the [main README](README.md) to get an overview of exam topics and resources
2. Review the [study resources](study-resources/) for targeted learning materials
3. Practice with the [code samples](code-samples/) to understand implementation details
4. Complete the [labs](labs/) to gain hands-on experience

### For Instructors
1. Follow the [course plan](study-resources/AZ-500-course-plan.md) for session structure
2. Use the [teaching punchlist](study-resources/AZ-500-Teaching-Punchlist.md) for key topics
3. Leverage code samples for in-class demonstrations
4. Assign labs for student practice

## Setting Up Your Environment

To get the most from these materials, set up your environment with:

1. **Azure Subscription** - [Free account](https://azure.microsoft.com/en-us/free/) or paid subscription
2. **Development Tools**:
   - [Visual Studio Code](https://code.visualstudio.com/)
   - [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
   - [PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell) with [Az module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps)
   - [Git](https://git-scm.com/downloads)
3. **VS Code Extensions**:
   - Azure Account
   - Azure CLI Tools
   - Bicep
   - PowerShell

## Learning Path Recommendation

For the most effective learning experience:

1. **Week 1**: Identity and Access Management
   - Review Microsoft Learn modules on identity
   - Complete identity-related labs
   - Practice with Azure RBAC examples

2. **Week 2**: Platform Protection
   - Study network security fundamentals
   - Work through compute security labs
   - Implement container security samples

3. **Week 3**: Security Operations
   - Configure Azure Defender for Cloud
   - Set up Azure Sentinel
   - Practice with security monitoring

4. **Week 4**: Data and Application Security
   - Implement storage security
   - Configure database security
   - Work with Azure Key Vault

5. **Final Week**: Exam Preparation
   - Take practice tests
   - Review areas of weakness
   - Complete comprehensive labs

## Getting Help

If you have questions or need assistance:

- Review the [Microsoft Learn AZ-500 path](https://learn.microsoft.com/en-us/training/courses/az-500t00)
- Join the [Microsoft Security Community](https://techcommunity.microsoft.com/t5/security-compliance-and-identity/ct-p/SecurityComplianceandIdentity)
- Review Microsoft documentation for specific services

Good luck with your Azure security learning journey! 

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021, Tim Warner

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Exam AZ-500: Microsoft Azure Security Technologies Crash Course

<img src="images/az500-cover-slide-final.png" alt="AZ-500 Course Cover" width="700"/>

Welcome to the training hub for preparing for the **AZ-500 Microsoft Azure Security Technologies Exam**. Whether you're aiming for certification or deepening your Azure security knowledge, this guide is packed with the best tools, links, and tips to set you up for success.

👉 **New to this repo?** Check out the [Getting Started Guide](GETTING-STARTED.md) for navigation help!  
📋 **Looking for the course plan?** View the [AZ-500 Crash Course Plan](AZ-500-course-plan.md)!

*Last updated: March 18, 2025*

---

## 📬 **Contact Information**
- **[Website](https://techtrainertim.com)**
- **[GitHub](https://github.com/timothywarner)**
- **[LinkedIn](https://www.linkedin.com/in/timothywarner/)**
- **[YouTube Channel](https://www.youtube.com/channel/UCim7PFtynyPuzMHtbNyYOXA)**
- **[Bluesky](https://bsky.app/profile/techtrainertim.bsky.social)**
- **[Mastodon](https://mastodon.social/@techtrainertim)**

---

## 📆 **Course Plan Overview**
This crash course is structured into 4 segments, each approximately 1 hour:

1. **Secure Identity and Access (15-20%)**
   - Microsoft Entra ID management, MFA, Conditional Access
   - Role assignments, custom roles, Privileged Identity Management
   - Application access and managed identities

2. **Secure Networking (20-25%)**
   - NSGs, ASGs, Virtual Network Manager, UDRs
   - Private access via Service Endpoints and Private Link
   - Public access security with Azure Firewall, Front Door, WAF

3. **Secure Compute, Storage, and Databases (20-25%)**
   - VM and container security (AKS, ACI, ACA)
   - Storage security, access control, and encryption
   - SQL Database and Managed Instance security

4. **Defender for Cloud and Microsoft Sentinel (30-35%)**
   - Cloud governance policies and Key Vault
   - Security posture management with Defender for Cloud
   - Threat protection and security monitoring

💡 **See the full [detailed course plan](AZ-500-course-plan.md) for complete information!**

---

## 📋 **Exam Objective Domain**
*Skills measured as of January 31, 2025*

### Skills at a Glance
- **Secure identity and access** (15–20%)
- **Secure networking** (20–25%)
- **Secure compute, storage, and databases** (20–25%)
- **Secure Azure using Microsoft Defender for Cloud and Microsoft Sentinel** (30–35%)

### Audience Profile
As an Azure security engineer, you implement, manage, and monitor security for resources in Azure, multi-cloud, and hybrid environments as part of an end-to-end infrastructure. You implement and manage security components and configurations using Microsoft Defender for Cloud and other tools, ensuring infrastructure aligns with standards and best practices such as the Microsoft Cloud Security Benchmark (MCSB).

#### Your responsibilities include:
- Managing security posture
- Implementing threat protection
- Identifying and remediating vulnerabilities
- Implementing regulatory compliance controls

#### Required experience:
- Practical experience in administration of Microsoft Azure and hybrid environments
- Strong familiarity with Microsoft Entra ID, as well as compute, network, and storage in Azure

### Detailed Skill Outline

#### 1. Secure Identity and Access (15–20%)

##### 1.1 Manage security controls for identity and access
- Manage Azure built-in role assignments
- Manage custom roles, including Azure roles and Microsoft Entra roles
- Implement and manage Microsoft Entra Permissions Management
- Plan and manage Azure resources in Microsoft Entra Privileged Identity Management, including settings and assignments
- Implement multi-factor authentication (MFA) for access to Azure resources
- Implement Conditional Access policies for cloud resources in Azure

##### 1.2 Manage Microsoft Entra application access
- Manage access to enterprise applications in Microsoft Entra ID, including OAuth permission grants
- Manage Microsoft Entra app registrations
- Configure app registration permission scopes
- Manage app registration permission consent
- Manage and use service principals
- Manage managed identities

#### 2. Secure Networking (20–25%)

##### 2.1 Plan and implement security for virtual networks
- Plan and implement Network Security Groups (NSGs) and Application Security Groups (ASGs)
- Manage virtual networks by using Azure Virtual Network Manager
- Plan and implement user-defined routes (UDRs)
- Plan and implement Virtual Network peering or VPN gateway
- Plan and implement Virtual WAN, including secured virtual hub
- Secure VPN connectivity, including point-to-site and site-to-site
- Implement encryption over ExpressRoute
- Configure firewall settings on Azure resources
- Monitor network security by using Network Watcher

##### 2.2 Plan and implement security for private access to Azure resources
- Plan and implement virtual network Service Endpoints
- Plan and implement Private Endpoints
- Plan and implement Private Link services
- Plan and implement network integration for Azure App Service and Azure Functions
- Plan and implement network security configurations for an App Service Environment (ASE)
- Plan and implement network security configurations for an Azure SQL Managed Instance

##### 2.3 Plan and implement security for public access to Azure resources
- Plan and implement Transport Layer Security (TLS) to applications, including Azure App Service and API Management
- Plan, implement, and manage an Azure Firewall, including Azure Firewall Manager and firewall policies
- Plan and implement an Azure Application Gateway
- Plan and implement an Azure Front Door, including Content Delivery Network (CDN)
- Plan and implement a Web Application Firewall (WAF)
- Recommend when to use Azure DDoS Protection Standard

#### 3. Secure Compute, Storage, and Databases (20–25%)

##### 3.1 Plan and implement advanced security for compute
- Plan and implement remote access to virtual machines, including Azure Bastion and just-in-time (JIT)
- Configure network isolation for Azure Kubernetes Service (AKS)
- Secure and monitor AKS
- Configure authentication for AKS
- Configure security monitoring for Azure Container Instances (ACIs)
- Configure security monitoring for Azure Container Apps (ACAs)
- Manage access to Azure Container Registry (ACR)
- Configure disk encryption, including Azure Disk Encryption (ADE), encryption at host, and confidential disk encryption
- Recommend security configurations for Azure API Management

##### 3.2 Plan and implement security for storage
- Configure access control for storage accounts
- Manage storage account access keys
- Select and configure an appropriate method for access to Azure Files
- Select and configure an appropriate method for access to Azure Blob Storage
- Select and configure appropriate methods for protecting against data security threats, including soft delete, backups, versioning, and immutable storage
- Configure Bring your own key (BYOK)
- Enable double encryption at the Azure Storage infrastructure level

##### 3.3 Plan and implement security for Azure SQL Database and Azure SQL Managed Instance
- Enable Microsoft Entra database authentication
- Enable database auditing
- Plan and implement dynamic masking
- Implement Transparent Data Encryption (TDE)
- Recommend when to use Azure SQL Database Always Encrypted

#### 4. Secure Azure using Microsoft Defender for Cloud and Microsoft Sentinel (30–35%)

##### 4.1 Implement and manage enforcement of cloud governance policies
- Create, assign, and interpret policies and initiatives in Azure Policy
- Configure Azure Key Vault network settings
- Configure access to Key Vault, including vault access policies and Azure Role Based Access Control
- Manage certificates, secrets, and keys
- Configure key rotation
- Perform backup and recovery of certificates, secrets, and keys
- Implement security controls to protect backups
- Implement security controls for asset management

##### 4.2 Manage security posture by using Microsoft Defender for Cloud
- Identify and remediate security risks by using the Microsoft Defender for Cloud Secure Score and Inventory
- Assess compliance against security frameworks by using Microsoft Defender for Cloud
- Manage compliance standards in Microsoft Defender for Cloud
- Add custom standards to Microsoft Defender for Cloud
- Connect hybrid cloud and multi-cloud environments to Microsoft Defender for Cloud, including Amazon Web Services (AWS) and Google Cloud Platform (GCP)
- Implement and use Microsoft Defender External Attack Surface Management (EASM)

##### 4.3 Configure and manage threat protection by using Microsoft Defender for Cloud
- Enable workload protection services in Microsoft Defender for Cloud
- Configure Microsoft Defender for Servers, Microsoft Defender for Databases, and Microsoft Defender for Storage
- Implement and manage agentless scanning for virtual machines in Microsoft Defender for Servers
- Implement and manage Microsoft Defender Vulnerability Management for Azure virtual machines
- Connect to and configure settings in Microsoft Defender for Cloud DevOps Security, including GitHub, Azure DevOps, and GitLab

##### 4.4 Configure and manage security monitoring and automation solutions
- Manage and respond to security alerts in Microsoft Defender for Cloud
- Configure workflow automation by using Microsoft Defender for Cloud
- Monitor network security events and performance data by configuring data collection rules (DCRs) in Azure Monitor
- Configure data connectors in Microsoft Sentinel
- Enable analytics rules in Microsoft Sentinel
- Configure automation in Microsoft Sentinel

---

## 🚀 **The Good Stuff: Must-Have AZ-500 Resources**
- [AZ-500 Exam Page](https://learn.microsoft.com/en-us/certifications/exams/az-500)
- [AZ-500 Study Guide (2025)](https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-500)
- [Exam Registration (Microsoft/Pearson VUE)](https://learn.microsoft.com/en-us/credentials/certifications/schedule-through-pearson-vue?examUid=exam.AZ-500)
- [AZ-500 Free Practice Assessment](https://learn.microsoft.com/en-us/credentials/certifications/azure-security-engineer/practice/assessment?assessment-type=practice)
- [Microsoft Learning AZ-500 Labs](https://microsoftlearning.github.io/AZ500-AzureSecurityTechnologies/)
- [Official Microsoft Learning Path](https://learn.microsoft.com/en-us/training/courses/az-500t00)
- [MeasureUp AZ-500 Practice Exams](https://www.measureup.com/az-500-microsoft-azure-security-technologies.html)

---

## 📚 **Microsoft Learn Paths**
Structured learning paths to master all exam skills:
- [Manage identity and access](https://learn.microsoft.com/en-us/training/paths/manage-identity-access/)
- [Implement platform protection](https://learn.microsoft.com/en-us/training/paths/implement-platform-protection/)
- [Manage security operations](https://learn.microsoft.com/en-us/training/paths/manage-security-operations/)
- [Secure Azure services and workloads](https://learn.microsoft.com/en-us/training/paths/secure-azure-services-workloads/)
- [Configure security for hybrid environments](https://learn.microsoft.com/en-us/training/paths/configure-security-for-hybrid-environments/)
- [Microsoft Defender for Cloud Implementation](https://learn.microsoft.com/en-us/training/paths/implement-microsoft-defender-for-cloud/)

---

## 🛡️ **Security Best Practices**
Expert guidance for implementing robust Azure security:

### Identity & Access Management
- [Microsoft Entra ID documentation](https://learn.microsoft.com/en-us/entra/identity/)
- [Azure RBAC documentation](https://learn.microsoft.com/en-us/azure/role-based-access-control/)
- [Privileged Identity Management](https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/)

### Data Protection
- [Microsoft Purview documentation](https://learn.microsoft.com/en-us/purview/)
- [Azure Key Vault documentation](https://learn.microsoft.com/en-us/azure/key-vault/)
- [Azure Storage Security](https://learn.microsoft.com/en-us/azure/storage/common/storage-security-guide)

### Network Security
- [Azure DDoS Protection](https://learn.microsoft.com/en-us/azure/ddos-protection/)
- [Azure Network Security](https://learn.microsoft.com/en-us/azure/security/fundamentals/network-overview)
- [Azure Firewall documentation](https://learn.microsoft.com/en-us/azure/firewall/)

---

## 🔧 **Your Toolkit**
Essential tools to follow along and practice efficiently:

### VS Code Extensions
- [Security IntelliSense](https://marketplace.visualstudio.com/items?itemName=azsdktm.SecurityIntelliSense)
- [Snyk Security](https://marketplace.visualstudio.com/items?itemName=snyk-security.snyk-vulnerability-scanner)
- [Azure Account](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)

### PowerShell Modules
- [Az.Security](https://www.powershellgallery.com/packages/Az.Security)
- [Az.SecurityInsights](https://www.powershellgallery.com/packages/Az.SecurityInsights)
- [Az.KeyVault](https://www.powershellgallery.com/packages/Az.KeyVault)
- [Microsoft.PowerShell.SecretManagement](https://www.powershellgallery.com/packages/Microsoft.PowerShell.SecretManagement)

### Dev Tools
- [PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
- [GitHub CLI](https://cli.github.com/)
- [Azure PowerShell Module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps)

---

## 💻 **Hands-on Labs & Practice**
Learn through hands-on experience:
- **[Lab Environment Setup Guide](labs/LAB-SETUP.md)** - Start here to prepare for labs!
- [Microsoft Security Assessment](https://www.microsoft.com/en-us/security/business/security-assessment)
- [Microsoft Defender for Cloud Workflow Automation](https://learn.microsoft.com/en-us/azure/defender-for-cloud/workflow-automation)
- [Microsoft Secure Score](https://security.microsoft.com/securescore)
- [Attack Surface Reduction Rules](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/attack-surface-reduction)
- [Azure Free Account](https://azure.microsoft.com/en-us/free/)
- [Microsoft Learn Sandbox Environments](https://learn.microsoft.com/en-us/training/modules/describe-azure-compute-networking-services/4-exercise-configure-network-access)

---

## ✍️ **Practice Tests & Exam Prep**
Validate your knowledge before the real exam:
- [Microsoft Free Practice Assessment](https://learn.microsoft.com/en-us/credentials/certifications/azure-security-engineer/practice/assessment?assessment-type=practice)
- [MeasureUp AZ-500](https://www.measureup.com/az-500-microsoft-azure-security-technologies.html)
- [Udemy Practice Tests](https://www.udemy.com/topic/microsoft-az-500/)

---

## 🎓 **Related Certifications**
Expand your Microsoft security credentials:

### Microsoft Security Certifications
- [SC-100: Microsoft Cybersecurity Architect](https://learn.microsoft.com/en-us/credentials/certifications/cybersecurity-architect-expert/)
- [SC-200: Microsoft Security Operations Analyst](https://learn.microsoft.com/en-us/credentials/certifications/security-operations-analyst/)
- [SC-300: Microsoft Identity and Access Administrator](https://learn.microsoft.com/en-us/credentials/certifications/identity-and-access-administrator/)
- [SC-400: Microsoft Information Protection Administrator](https://learn.microsoft.com/en-us/credentials/certifications/information-protection-administrator/)

### Industry Certifications
- CompTIA Security+
- CISSP (Certified Information Systems Security Professional)
- CCSP (Certified Cloud Security Professional)
- CISM (Certified Information Security Manager)

---

## 💸 **Exam Discounts and Registration Info**
- [Microsoft Certification Special Offers](https://learn.microsoft.com/en-us/certifications/deals)
- [About Online Exams](https://learn.microsoft.com/en-us/credentials/certifications/online-exams)
- [Certification Policies and FAQs](https://learn.microsoft.com/en-us/credentials/certifications/certification-exam-policies)

---

## 🎥 **Tim's Helper Videos**
- [Exam Registration Walkthrough](https://www.youtube.com/watch?v=FOFWbSYbbVI)
- [Online Testing Tips](https://www.youtube.com/watch?v=myf6r5nulj0)

---

## 🛡️ **2025 Security Focus Areas**

### Zero Trust Security
- [Microsoft Zero Trust Implementation Guide](https://learn.microsoft.com/en-us/security/zero-trust/)
- [Azure Zero Trust Network Architecture](https://learn.microsoft.com/en-us/security/zero-trust/azure-infrastructure)
- [Zero Trust Deployment Center](https://learn.microsoft.com/en-us/security/zero-trust/deploy/)

### Cloud-Native Security
- [Microsoft Entra Workload ID](https://learn.microsoft.com/en-us/entra/workload-id/)
- [Azure Container Apps Security](https://learn.microsoft.com/en-us/azure/container-apps/security-concept)
- [Azure Kubernetes Service (AKS) Security](https://learn.microsoft.com/en-us/azure/aks/concepts-security)

### AI Security & Governance
- [Azure OpenAI Service Security](https://learn.microsoft.com/en-us/azure/ai-services/openai/security)
- [Responsible AI Guidelines](https://learn.microsoft.com/en-us/azure/ai-services/responsible-ai-standards)
- [AI Security Best Practices](https://learn.microsoft.com/en-us/security/ai-security/)

---

## 📱 **Community & Support**
Connect with security professionals:
- [Microsoft Security Community](https://techcommunity.microsoft.com/t5/security-compliance-and-identity/ct-p/SecurityComplianceandIdentity)
- [Azure Security Podcast](https://azsecuritypodcast.net/)
- [Microsoft Security Blog](https://www.microsoft.com/security/blog/)
- [Microsoft Defender for Cloud GitHub Repository](https://github.com/Azure/Microsoft-Defender-for-Cloud)
- [Microsoft Security YouTube Channel](https://www.youtube.com/@MSFTSecurity)

---

This README is designed for maximum utility and easy navigation. If you have suggestions or corrections, feel free to reach out via the contact information above. Best of luck on your AZ-500 journey!


================================================
FILE: az104-README.md
================================================
# Tim Warner's AZ-104 Study Resources

<img src="az104-cover-slide.png" alt="AZ-104 Course Cover" width="800"/>

Welcome to the ultimate resource hub for preparing for the **AZ-104 Microsoft Azure Administrator Exam**. Whether you're aiming for certification or deepening your Azure knowledge, this guide is packed with the best tools, links, and tips to set you up for success.

---

## 📬 **Contact Information**
- **[Email](mailto:timothywarner316@gmail.com)**
- **[LinkedIn](https://www.linkedin.com/in/timothywarner/)**
- **[YouTube Channel](https://www.youtube.com/channel/UCim7PFtynyPuzMHtbNyYOXA)**
- **[Website](https://techtrainertim.com)**
- **[Bluesky](https://bsky.app/profile/techtrainertim.bsky.social)**
- **[Mastodon](https://mastodon.social/@techtrainertim)**

---

## 🚀 **The Good Stuff: Must-Have AZ-104 Resources**
- [AZ-104 Exam Page](https://learn.microsoft.com/en-us/certifications/exams/az-104)
- [AZ-104 Skills Measured](https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-104)
- [Exam Registration (Microsoft/Pearson VUE)](https://learn.microsoft.com/en-us/credentials/certifications/schedule-through-pearson-vue?examUid=exam.AZ-104&examUrl=https%3A%2F%2Flearn.microsoft.com%2Fcredentials%2Fcertifications)
- [MeasureUp AZ-104 Practice Exams](https://www.measureup.com/microsoft-practice-test-az-104-microsoft-azure-administrator.html)
- [Microsoft Learn AZ-104 Learning Path](https://learn.microsoft.com/en-us/training/courses/az-104t00/)
- [Azure Free Account Signup](https://azure.microsoft.com/en-us/pricing/purchase-options/azure-account)
- [Pearson CertPREP AZ-104 Training Labs](https://govstore.pearsonvue.com/certprep-microsoft-exam-az-104/p/CLC-AZ104-PVUE)

---

## 📘 **Conceptual Knowledge**
These resources build your understanding of Azure fundamentals and exam concepts:
- [Azure Documentation](https://docs.microsoft.com/en-us/azure/)
- [Azure Architecture Center](https://docs.microsoft.com/en-us/azure/architecture/)
- [Azure Quickstart Templates](https://azure.microsoft.com/en-us/resources/templates/)
- [Azure SDKs and Tools](https://azure.microsoft.com/en-us/downloads/)
- [Sam Cogan ARM Tutorial](https://www.youtube.com/watch?v=9EpBiud48Ao&t=1s)
- [Adam Marczak ARM Tutorials](https://www.youtube.com/watch?v=Ge_Sp-1lWZ4&t=916s)
- [Azure Bicep Overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview)
- [AZ-104 Class Topology](https://lucid.app/lucidchart/5b4214cf-b00b-400d-80ff-c15572f57904/view?page=0_0#)

---

## 🛠 **Your Toolkit**
Essential tools to follow along and practice efficiently:
- **[Visual Studio Code](https://code.visualstudio.com/)**  
  Recommended extensions:
  - [PowerShell](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
  - [Azure Account](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
  - [ARM Tools](https://marketplace.visualstudio.com/items?itemName=msazurermtools.azurerm-vscode-tools)
  - [Azure CLI Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azurecli)
  - [Bicep](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep)
- [PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
- [Azure PowerShell Module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps)
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
- [Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/)
- [AzCopy](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10)

---

## 🛡 **Practical Application**
Learn through hands-on labs and live environments:
- [Azure Free Account](https://azure.microsoft.com/en-us/free/)
- [Microsoft Learn: Azure Administrator Path](https://docs.microsoft.com/en-us/learn/browse/?roles=administrator)
- [Azure Citadel](https://azurecitadel.com/)
- [AZ-104 Microsoft Official Curriculum Labs](https://github.com/MicrosoftLearning/AZ-104-MicrosoftAzureAdministrator)
- [Azure Bicep Playground](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/playground)
- [Azure Log Analytics Demo Environment](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/log-analytics-demo-environment)

---

## 📑 **Practice Exams**
- [Microsoft Free Practice Assessments](https://learn.microsoft.com/en-us/certifications/practice-assessments-for-microsoft-certifications)
- [MeasureUp Practice Exams](https://www.measureup.com/az-104-microsoft-azure-administrator.html)

---

## 💸 **Exam Discounts and Registration Info**
- [Microsoft Certification Special Offers](https://learn.microsoft.com/en-us/certifications/deals)
- [AZ-104 Exam Registration](https://learn.microsoft.com/en-us/credentials/certifications/exams/az-104)
- [About Online Exams](https://learn.microsoft.com/en-us/credentials/certifications/online-exams)
- [Certification Policies and FAQs](https://learn.microsoft.com/en-us/credentials/certifications/certification-exam-policies)
- [Microsoft Certification Exam Policies](https://learn.microsoft.com/en-us/certifications/certification-exam-policies)

---

## 🎥 **Tim's Helper Videos**
- [Exam Registration Walkthrough](https://www.youtube.com/watch?v=FOFWbSYbbVI)
- [Online Testing Tips](https://www.youtube.com/watch?v=myf6r5nulj0&feature=youtu.be)

---

This README is designed for maximum utility and easy navigation. If you have suggestions or corrections, feel free to reach out via the contact information above. Best of luck on your AZ-104 journey!


================================================
FILE: az500-objective-domain.md
================================================
# Exam AZ-500: Microsoft Azure Security Technologies

![Microsoft Azure Security](images/az500-cover-slide-final.png)

## Exam Information
**Skills measured as of January 31, 2025**

---

## 🎯 Audience Profile

As the Azure security engineer, you implement, manage, and monitor security for resources in Azure, multi-cloud, and hybrid environments as part of an end-to-end infrastructure. You implement and manage security components and configurations by using Microsoft Defender for Cloud and other tools. You ensure that the infrastructure aligns with standards and best practices such as the Microsoft Cloud Security Benchmark (MCSB).

### Your responsibilities include:

- ✅ Managing the security posture
- ✅ Implementing threat protection
- ✅ Identifying and remediating vulnerabilities
- ✅ Implementing regulatory compliance controls for Azure infrastructure including identity and access, network, compute, storage, data, applications, asset management, backup and recovery, and DevOps security

As an Azure security engineer, you work with architects, administrators, and developers to plan and implement solutions that meet security and compliance requirements. You may also collaborate with security operations in responding to security incidents in Azure.

### Required Experience

- Practical experience in administration of Microsoft Azure and hybrid environments
- Strong familiarity with Microsoft Entra ID, as well as compute, network, and storage in Azure

---

## 📊 Skills at a Glance

| Skill Area | Weight |
|------------|--------|
| Secure identity and access | 15–20% |
| Secure networking | 20–25% |
| Secure compute, storage, and databases | 20–25% |
| Secure Azure using Microsoft Defender for Cloud and Microsoft Sentinel | 30–35% |

---

## 🔐 Detailed Skills Outline

### 1. Secure Identity and Access (15–20%)

#### 1.1 Manage Security Controls for Identity and Access

- Manage Azure built-in role assignments
- Manage custom roles, including Azure roles and Microsoft Entra roles
- Implement and manage Microsoft Entra Permissions Management
- Plan and manage Azure resources in Microsoft Entra Privileged Identity Management, including settings and assignments
- Implement multi-factor authentication (MFA) for access to Azure resources
- Implement Conditional Access policies for cloud resources in Azure

#### 1.2 Manage Microsoft Entra Application Access

- Manage access to enterprise applications in Microsoft Entra ID, including OAuth permission grants
- Manage Microsoft Entra app registrations
- Configure app registration permission scopes
- Manage app registration permission consent
- Manage and use service principals
- Manage managed identities

---

### 2. Secure Networking (20–25%)

#### 2.1 Plan and Implement Security for Virtual Networks

- Plan and implement Network Security Groups (NSGs) and Application Security Groups (ASGs)
- Manage virtual networks by using Azure Virtual Network Manager
- Plan and implement user-defined routes (UDRs)
- Plan and implement Virtual Network peering or VPN gateway
- Plan and implement Virtual WAN, including secured virtual hub
- Secure VPN connectivity, including point-to-site and site-to-site
- Implement encryption over ExpressRoute
- Configure firewall settings on Azure resources
- Monitor network security by using Network Watcher

#### 2.2 Plan and Implement Security for Private Access to Azure Resources

- Plan and implement virtual network Service Endpoints
- Plan and implement Private Endpoints
- Plan and implement Private Link services
- Plan and implement network integration for Azure App Service and Azure Functions
- Plan and implement network security configurations for an App Service Environment (ASE)
- Plan and implement network security configurations for an Azure SQL Managed Instance

#### 2.3 Plan and Implement Security for Public Access to Azure Resources

- Plan and implement Transport Layer Security (TLS) to applications, including Azure App Service and API Management
- Plan, implement, and manage an Azure Firewall, including Azure Firewall Manager and firewall policies
- Plan and implement an Azure Application Gateway
- Plan and implement an Azure Front Door, including Content Delivery Network (CDN)
- Plan and implement a Web Application Firewall (WAF)
- Recommend when to use Azure DDoS Protection Standard

---

### 3. Secure Compute, Storage, and Databases (20–25%)

#### 3.1 Plan and Implement Advanced Security for Compute

- Plan and implement remote access to virtual machines, including Azure Bastion and just-in-time (JIT)
- Configure network isolation for Azure Kubernetes Service (AKS)
- Secure and monitor AKS
- Configure authentication for AKS
- Configure security monitoring for Azure Container Instances (ACIs)
- Configure security monitoring for Azure Container Apps (ACAs)
- Manage access to Azure Container Registry (ACR)
- Configure disk encryption, including Azure Disk Encryption (ADE), encryption at host, and confidential disk encryption
- Recommend security configurations for Azure API Management

#### 3.2 Plan and Implement Security for Storage

- Configure access control for storage accounts
- Manage storage account access keys
- Select and configure an appropriate method for access to Azure Files
- Select and configure an appropriate method for access to Azure Blob Storage
- Select and configure appropriate methods for protecting against data security threats, including:
  - Soft delete
  - Backups
  - Versioning
  - Immutable storage
- Configure Bring your own key (BYOK)
- Enable double encryption at the Azure Storage infrastructure level

#### 3.3 Plan and Implement Security for Azure SQL Database and Azure SQL Managed Instance

- Enable Microsoft Entra database authentication
- Enable database auditing
- Plan and implement dynamic masking
- Implement Transparent Data Encryption (TDE)
- Recommend when to use Azure SQL Database Always Encrypted

---

### 4. Secure Azure using Microsoft Defender for Cloud and Microsoft Sentinel (30–35%)

#### 4.1 Implement and Manage Enforcement of Cloud Governance Policies

- Create, assign, and interpret policies and initiatives in Azure Policy
- Configure Azure Key Vault network settings
- Configure access to Key Vault, including vault access policies and Azure Role Based Access Control
- Manage certificates, secrets, and keys
- Configure key rotation
- Perform backup and recovery of certificates, secrets, and keys
- Implement security controls to protect backups
- Implement security controls for asset management

#### 4.2 Manage Security Posture by Using Microsoft Defender for Cloud

- Identify and remediate security risks by using the Microsoft Defender for Cloud Secure Score and Inventory
- Assess compliance against security frameworks by using Microsoft Defender for Cloud
- Manage compliance standards in Microsoft Defender for Cloud
- Add custom standards to Microsoft Defender for Cloud
- Connect hybrid cloud and multi-cloud environments to Microsoft Defender for Cloud, including:
  - Amazon Web Services (AWS)
  - Google Cloud Platform (GCP)
- Implement and use Microsoft Defender External Attack Surface Management (EASM)

#### 4.3 Configure and Manage Threat Protection by Using Microsoft Defender for Cloud

- Enable workload protection services in Microsoft Defender for Cloud
- Configure Microsoft Defender for:
  - Servers
  - Databases
  - Storage
- Implement and manage agentless scanning for virtual machines in Microsoft Defender for Servers
- Implement and manage Microsoft Defender Vulnerability Management for Azure virtual machines
- Connect to and configure settings in Microsoft Defender for Cloud Devops Security, including:
  - GitHub
  - Azure DevOps
  - GitLab

#### 4.4 Configure and Manage Security Monitoring and Automation Solutions

- Manage and respond to security alerts in Microsoft Defender for Cloud
- Configure workflow automation by using Microsoft Defender for Cloud
- Monitor network security events and performance data by configuring data collection rules (DCRs) in Azure Monitor
- Configure data connectors in Microsoft Sentinel
- Enable analytics rules in Microsoft Sentinel
- Configure automation in Microsoft Sentinel

================================================
FILE: azure-cli.azcli
================================================
#!/bin/bash
# AZ-500 Security Implementation Example
# Purpose: Demonstrates security hardening and auditing across multiple Azure services

# Set variables
RG_NAME="SecurityAuditRG"
LOCATION="eastus"
STORAGE_ACCOUNT="securityauditsa$RANDOM"
KEYVAULT_NAME="security-kv-$RANDOM"
NSG_NAME="security-nsg"
VNET_NAME="security-vnet"
LOG_ANALYTICS_WORKSPACE="security-law"

# Create Resource Group with tags for compliance
az group create \
    --name $RG_NAME \
    --location $LOCATION \
    --tags "Environment=Production" "DataClassification=Confidential" "ComplianceRequired=HIPAA"

# Create VNet with custom subnet configuration
az network vnet create \
    --resource-group $RG_NAME \
    --name $VNET_NAME \
    --address-prefix 10.0.0.0/16 \
    --subnet-name ApplicationSubnet \
    --subnet-prefix 10.0.1.0/24

# Create NSG with security rules
az network nsg create \
    --resource-group $RG_NAME \
    --name $NSG_NAME

# Add security rules to NSG
az network nsg rule create \
    --resource-group $RG_NAME \
    --nsg-name $NSG_NAME \
    --name "DenyAllInbound" \
    --priority 4096 \
    --direction Inbound \
    --access Deny \
    --protocol "*" \
    --source-address-prefixes "*" \
    --source-port-ranges "*" \
    --destination-address-prefixes "*" \
    --destination-port-ranges "*"

# Create Storage Account with security features
az storage account create \
    --name $STORAGE_ACCOUNT \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --sku Standard_GRS \
    --kind StorageV2 \
    --https-only true \
    --min-tls-version TLS1_2 \
    --allow-blob-public-access false \
    --enable-hierarchical-namespace true

# Enable Azure Defender for Storage
az security pricing create \
    --name "StorageAccounts" \
    --tier "Standard"

# Create Key Vault with advanced security features
az keyvault create \
    --name $KEYVAULT_NAME \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --sku Premium \
    --enable-rbac-authorization true \
    --enable-purge-protection true \
    --retention-days 90

# Enable Key Vault logging
az monitor diagnostic-settings create \
    --name "KeyVaultAudit" \
    --resource $KEYVAULT_NAME \
    --resource-group $RG_NAME \
    --resource-type "Microsoft.KeyVault/vaults" \
    --logs '[{"category": "AuditEvent","enabled": true}]' \
    --metrics '[{"category": "AllMetrics","enabled": true}]'

# Create Log Analytics Workspace for security monitoring
az monitor log-analytics workspace create \
    --resource-group $RG_NAME \
    --workspace-name $LOG_ANALYTICS_WORKSPACE \
    --location $LOCATION \
    --sku PerGB2018

# Enable Microsoft Defender for Cloud
az security pricing create \
    --name "VirtualMachines" \
    --tier "Standard"

# Configure security policies
az security policy assignment create \
    --name "SecurityBaselinePolicy" \
    --display-name "Security Baseline" \
    --policy-definition-id "/providers/Microsoft.Authorization/policyDefinitions/1f3afdf9-d0c9-4c3d-847f-89da613e70a8"

# Enable JIT VM Access
az vm jit-policy create \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --vm-name "sample-vm" \
    --jit-policy "{'jitNetworkAccessPolicy':{'virtualMachines':[{'id':'/subscriptions/{subscription-id}/resourceGroups/$RG_NAME/providers/Microsoft.Compute/virtualMachines/sample-vm','ports':[{'number':22,'protocol':'*','allowedSourceAddressPrefix':'*','maxRequestAccessDuration':'PT3H'}]}]}}"

# Enable diagnostic settings for Activity Log
az monitor diagnostic-settings create \
    --name "SecurityAudit" \
    --resource-group $RG_NAME \
    --logs '[{"category": "Administrative","enabled": true},{"category": "Security","enabled": true}]' \
    --workspace $LOG_ANALYTICS_WORKSPACE

# Export security recommendations
az security assessment list \
    --resource-group $RG_NAME \
    --query "[].{Name:name, Status:status.code, Description:metadata.description}" \
    --output table

# Configure custom security alerts
az monitor activity-log alert create \
    --name "SecurityAlert" \
    --resource-group $RG_NAME \
    --condition category="Security" \
    --action-group "/subscriptions/{subscription-id}/resourceGroups/$RG_NAME/providers/microsoft.insights/actionGroups/SecurityTeam"

echo "Security configuration completed. Review the Microsoft Defender for Cloud dashboard for security recommendations."


================================================
FILE: azure-policy.json
================================================
{
    "mode": "Indexed",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Web/sites"
                }
            ]
        },
        "then": {
            "effect": "deployIfNotExists",
            "details": {
                "type": "Microsoft.Web/sites",
                "name": "[field('name')]",
                "roleDefinitionIds": [
                    "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" // Contributor role
                ],
                "existenceCondition": {
                    "allOf": [
                        {
                            "field": "identity.type",
                            "contains": "UserAssigned"
                        },
                        {
                            "field": "identity.userAssignedIdentities",
                            "exists": "true"
                        }
                    ]
                },
                "deployment": {
                    "properties": {
                        "mode": "Incremental",
                        "template": {
                            "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                            "contentVersion": "1.0.0.0",
                            "parameters": {
                                "webAppName": {
                                    "type": "string"
                                },
                                "location": {
                                    "type": "string"
                                },
                                "userAssignedIdentityName": {
                                    "type": "string",
                                    "defaultValue": "[concat(parameters('webAppName'), '-identity')]"
                                }
                            },
                            "resources": [
                                {
                                    "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
                                    "apiVersion": "2018-11-30",
                                    "name": "[parameters('userAssignedIdentityName')]",
                                    "location": "[parameters('location')]"
                                },
                                {
                                    "type": "Microsoft.Web/sites",
                                    "apiVersion": "2022-03-01",
                                    "name": "[parameters('webAppName')]",
                                    "location": "[parameters('location')]",
                                    "identity": {
                                        "type": "UserAssigned",
                                        "userAssignedIdentities": {
                                            "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]": {}
                                        }
                                    },
                                    "dependsOn": [
                                        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]"
                                    ]
                                }
                            ]
                        },
                        "parameters": {
                            "webAppName": {
                                "value": "[field('name')]"
                            },
                            "location": {
                                "value": "[field('location')]"
                            }
                        }
                    }
                }
            }
        }
    },
    "parameters": {}
}


================================================
FILE: azure-powershell.ps1
================================================


================================================
FILE: code-samples/README.md
================================================
# AZ-500 Code Samples

This directory contains code samples, templates, and scripts that demonstrate Azure security concepts relevant to the AZ-500 exam.

## Directory Structure

- **bicep/** - Azure Bicep templates for infrastructure-as-code deployments
- **json/** - Azure Resource Manager (ARM) templates and JSON configuration files
- **powershell/** - PowerShell scripts for Azure security automation
- **cli/** - Azure CLI scripts for security configurations
- **kusto/** - Kusto Query Language (KQL) samples for Azure Monitor and Sentinel

## How to Use These Samples

These code samples are designed to help you understand and practice implementing Azure security concepts. Follow these steps:

1. **Review the code** to understand the security configurations
2. **Test in a sandbox environment** before applying to production
3. **Modify parameters** to match your specific requirements
4. **Reference the [Azure documentation](https://learn.microsoft.com/en-us/azure)** for detailed explanations

## Security Best Practices

When using these code samples, remember to follow security best practices:

- Use managed identities where possible
- Apply the principle of least privilege for access control
- Encrypt sensitive data at rest and in transit
- Implement defense in depth with multiple security layers
- Enable logging and monitoring for security-relevant events

## Contributing

If you have improvements or additional samples, please follow the contribution guidelines in the main repository. 

================================================
FILE: code-samples/bicep/deployment.bicep
================================================
// AZ-500 Security Implementation Example
// Purpose: Demonstrates secure infrastructure deployment with multiple security controls

// Parameters
@description('Primary location for all resources')
param location string = resourceGroup().location

@description('Environment name')
@allowed([
  'Production'
  'Development'
  'Test'
])
param environmentName string

@description('IP addresses or ranges that should be allowed through the firewall')
param allowedIPRanges array

@description('Key Vault SKU')
@allowed([
  'standard'
  'premium'
])
param keyVaultSku string = 'premium'

@minLength(3)
@maxLength(24)
@description('Storage Account name')
param storageAccountName string

@secure()
@description('SQL Server administrator password')
param sqlServerAdminPassword string

// Variables
var networkSecurityGroupName = 'security-nsg'
var virtualNetworkName = 'security-vnet'
var keyVaultName = 'kv-${uniqueString(resourceGroup().id)}'
var logAnalyticsWorkspaceName = 'law-${uniqueString(resourceGroup().id)}'
var applicationInsightsName = 'ai-${uniqueString(resourceGroup().id)}'

// Tags
var commonTags = {
  Environment: environmentName
  SecurityContact: 'security@contoso.com'
  DataClassification: 'Confidential'
  ComplianceRequired: 'HIPAA'
}

// Network Security Group
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
  name: networkSecurityGroupName
  location: location
  tags: commonTags
  properties: {
    securityRules: [
      {
        name: 'DenyAllInbound'
        properties: {
          priority: 4096
          direction: 'Inbound'
          access: 'Deny'
          protocol: '*'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
          destinationPortRange: '*'
        }
      }
    ]
  }
}

// Virtual Network with Subnets
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
  name: virtualNetworkName
  location: location
  tags: commonTags
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/16'
      ]
    }
    subnets: [
      {
        name: 'ApplicationSubnet'
        properties: {
          addressPrefix: '10.0.1.0/24'
          networkSecurityGroup: {
            id: nsg.id
          }
          serviceEndpoints: [
            {
              service: 'Microsoft.KeyVault'
            }
            {
              service: 'Microsoft.Storage'
            }
            {
              service: 'Microsoft.Sql'
            }
          ]
        }
      }
      {
        name: 'DatabaseSubnet'
        properties: {
          addressPrefix: '10.0.2.0/24'
          delegations: [
            {
              name: 'sqlDelegation'
              properties: {
                serviceName: 'Microsoft.Sql/managedInstances'
              }
            }
          ]
        }
      }
    ]
  }
}

// Key Vault with RBAC and Advanced Security
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: keyVaultName
  location: location
  tags: commonTags
  properties: {
    tenantId: subscription().tenantId
    sku: {
      family: 'A'
      name: keyVaultSku
    }
    enableRbacAuthorization: true
    enablePurgeProtection: true
    enabledForTemplateDeployment: true
    enabledForDiskEncryption: true
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      ipRules: [for ip in allowedIPRanges: {
        value: ip
      }]
      virtualNetworkRules: [
        {
          id: '${vnet.id}/subnets/ApplicationSubnet'
        }
      ]
    }
  }
}

// Storage Account with Security Features
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  tags: commonTags
  sku: {
    name: 'Standard_GRS'
  }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
    encryption: {
      services: {
        blob: {
          enabled: true
        }
        file: {
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      virtualNetworkRules: [
        {
          id: '${vnet.id}/subnets/ApplicationSubnet'
          action: 'Allow'
        }
      ]
      ipRules: [for ip in allowedIPRanges: {
        value: ip
        action: 'Allow'
      }]
    }
  }
}

// Log Analytics Workspace
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
  name: logAnalyticsWorkspaceName
  location: location
  tags: commonTags
  properties: {
    sku: {
      name: 'PerGB2018'
    }
    retentionInDays: 90
    features: {
      enableLogAccessUsingOnlyResourcePermissions: true
    }
  }
}

// Application Insights for Security Monitoring
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: applicationInsightsName
  location: location
  tags: commonTags
  kind: 'web'
  properties: {
    Application_Type: 'web'
    WorkspaceResourceId: logAnalytics.id
    DisableIpMasking: false
    DisableLocalAuth: true
  }
}

// Diagnostic Settings for Key Vault
resource keyVaultDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  scope: keyVault
  name: 'KeyVaultAudit'
  properties: {
    workspaceId: logAnalytics.id
    logs: [
      {
        category: 'AuditEvent'
        enabled: true
        retentionPolicy: {
          enabled: true
          days: 90
        }
      }
    ]
    metrics: [
      {
        category: 'AllMetrics'
        enabled: true
        retentionPolicy: {
          enabled: true
          days: 90
        }
      }
    ]
  }
}

// Role Assignments
resource keyVaultAdminRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(keyVault.id, 'Key Vault Administrator')
  scope: keyVault
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')
    principalType: 'ServicePrincipal'
    principalId: 'YOUR-MANAGED-IDENTITY-ID'
  }
}

// Outputs
output keyVaultName string = keyVault.name
output storageAccountName string = storageAccount.name
output vnetName string = vnet.name
output logAnalyticsWorkspaceId string = logAnalytics.id


================================================
FILE: code-samples/cli/azure-cli.azcli
================================================
#!/bin/bash
# AZ-500 Security Implementation Example
# Purpose: Demonstrates security hardening and auditing across multiple Azure services

# Set variables
RG_NAME="SecurityAuditRG"
LOCATION="eastus"
STORAGE_ACCOUNT="securityauditsa$RANDOM"
KEYVAULT_NAME="security-kv-$RANDOM"
NSG_NAME="security-nsg"
VNET_NAME="security-vnet"
LOG_ANALYTICS_WORKSPACE="security-law"

# Create Resource Group with tags for compliance
az group create \
    --name $RG_NAME \
    --location $LOCATION \
    --tags "Environment=Production" "DataClassification=Confidential" "ComplianceRequired=HIPAA"

# Create VNet with custom subnet configuration
az network vnet create \
    --resource-group $RG_NAME \
    --name $VNET_NAME \
    --address-prefix 10.0.0.0/16 \
    --subnet-name ApplicationSubnet \
    --subnet-prefix 10.0.1.0/24

# Create NSG with security rules
az network nsg create \
    --resource-group $RG_NAME \
    --name $NSG_NAME

# Add security rules to NSG
az network nsg rule create \
    --resource-group $RG_NAME \
    --nsg-name $NSG_NAME \
    --name "DenyAllInbound" \
    --priority 4096 \
    --direction Inbound \
    --access Deny \
    --protocol "*" \
    --source-address-prefixes "*" \
    --source-port-ranges "*" \
    --destination-address-prefixes "*" \
    --destination-port-ranges "*"

# Create Storage Account with security features
az storage account create \
    --name $STORAGE_ACCOUNT \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --sku Standard_GRS \
    --kind StorageV2 \
    --https-only true \
    --min-tls-version TLS1_2 \
    --allow-blob-public-access false \
    --enable-hierarchical-namespace true

# Enable Azure Defender for Storage
az security pricing create \
    --name "StorageAccounts" \
    --tier "Standard"

# Create Key Vault with advanced security features
az keyvault create \
    --name $KEYVAULT_NAME \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --sku Premium \
    --enable-rbac-authorization true \
    --enable-purge-protection true \
    --retention-days 90

# Enable Key Vault logging
az monitor diagnostic-settings create \
    --name "KeyVaultAudit" \
    --resource $KEYVAULT_NAME \
    --resource-group $RG_NAME \
    --resource-type "Microsoft.KeyVault/vaults" \
    --logs '[{"category": "AuditEvent","enabled": true}]' \
    --metrics '[{"category": "AllMetrics","enabled": true}]'

# Create Log Analytics Workspace for security monitoring
az monitor log-analytics workspace create \
    --resource-group $RG_NAME \
    --workspace-name $LOG_ANALYTICS_WORKSPACE \
    --location $LOCATION \
    --sku PerGB2018

# Enable Microsoft Defender for Cloud
az security pricing create \
    --name "VirtualMachines" \
    --tier "Standard"

# Configure security policies
az security policy assignment create \
    --name "SecurityBaselinePolicy" \
    --display-name "Security Baseline" \
    --policy-definition-id "/providers/Microsoft.Authorization/policyDefinitions/1f3afdf9-d0c9-4c3d-847f-89da613e70a8"

# Enable JIT VM Access
az vm jit-policy create \
    --resource-group $RG_NAME \
    --location $LOCATION \
    --vm-name "sample-vm" \
    --jit-policy "{'jitNetworkAccessPolicy':{'virtualMachines':[{'id':'/subscriptions/{subscription-id}/resourceGroups/$RG_NAME/providers/Microsoft.Compute/virtualMachines/sample-vm','ports':[{'number':22,'protocol':'*','allowedSourceAddressPrefix':'*','maxRequestAccessDuration':'PT3H'}]}]}}"

# Enable diagnostic settings for Activity Log
az monitor diagnostic-settings create \
    --name "SecurityAudit" \
    --resource-group $RG_NAME \
    --logs '[{"category": "Administrative","enabled": true},{"category": "Security","enabled": true}]' \
    --workspace $LOG_ANALYTICS_WORKSPACE

# Export security recommendations
az security assessment list \
    --resource-group $RG_NAME \
    --query "[].{Name:name, Status:status.code, Description:metadata.description}" \
    --output table

# Configure custom security alerts
az monitor activity-log alert create \
    --name "SecurityAlert" \
    --resource-group $RG_NAME \
    --condition category="Security" \
    --action-group "/subscriptions/{subscription-id}/resourceGroups/$RG_NAME/providers/microsoft.insights/actionGroups/SecurityTeam"

echo "Security configuration completed. Review the Microsoft Defender for Cloud dashboard for security recommendations."


================================================
FILE: code-samples/json/azure-policy.json
================================================
{
    "mode": "Indexed",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Web/sites"
                }
            ]
        },
        "then": {
            "effect": "deployIfNotExists",
            "details": {
                "type": "Microsoft.Web/sites",
                "name": "[field('name')]",
                "roleDefinitionIds": [
                    "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" // Contributor role
                ],
                "existenceCondition": {
                    "allOf": [
                        {
                            "field": "identity.type",
                            "contains": "UserAssigned"
                        },
                        {
                            "field": "identity.userAssignedIdentities",
                            "exists": "true"
                        }
                    ]
                },
                "deployment": {
                    "properties": {
                        "mode": "Incremental",
                        "template": {
                            "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                            "contentVersion": "1.0.0.0",
                            "parameters": {
                                "webAppName": {
                                    "type": "string"
                                },
                                "location": {
                                    "type": "string"
                                },
                                "userAssignedIdentityName": {
                                    "type": "string",
                                    "defaultValue": "[concat(parameters('webAppName'), '-identity')]"
                                }
                            },
                            "resources": [
                                {
                                    "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
                                    "apiVersion": "2018-11-30",
                                    "name": "[parameters('userAssignedIdentityName')]",
                                    "location": "[parameters('location')]"
                                },
                                {
                                    "type": "Microsoft.Web/sites",
                                    "apiVersion": "2022-03-01",
                                    "name": "[parameters('webAppName')]",
                                    "location": "[parameters('location')]",
                                    "identity": {
                                        "type": "UserAssigned",
                                        "userAssignedIdentities": {
                                            "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]": {}
                                        }
                                    },
                                    "dependsOn": [
                                        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]"
                                    ]
                                }
                            ]
                        },
                        "parameters": {
                            "webAppName": {
                                "value": "[field('name')]"
                            },
                            "location": {
                                "value": "[field('location')]"
                            }
                        }
                    }
                }
            }
        }
    },
    "parameters": {}
}


================================================
FILE: code-samples/json/custom-rbac-role.json
================================================
{
    "Name": "Security Operations Analyst Custom Role",
    "IsCustom": true,
    "Description": "Allows security operations team to monitor security-related resources, manage security alerts, and perform specific remediation actions while maintaining separation of duties.",
    "Actions": [
        "Microsoft.Security/alerts/read",
        "Microsoft.Security/securitySolutions/read",
        "Microsoft.Security/policies/read",
        "Microsoft.Security/pricings/read",
        "Microsoft.Security/settings/read",
        "Microsoft.Security/assessments/read",
        "Microsoft.Network/networkWatchers/read",
        "Microsoft.Network/networkSecurityGroups/read",
        "Microsoft.KeyVault/vaults/read",
        "Microsoft.Insights/alertRules/*",
        "Microsoft.Resources/subscriptions/resourceGroups/read"
    ],
    "NotActions": [
        "Microsoft.KeyVault/vaults/delete",
        "Microsoft.KeyVault/vaults/write",
        "Microsoft.Network/networkSecurityGroups/write",
        "Microsoft.Network/networkSecurityGroups/delete"
    ],
    "DataActions": [
        "Microsoft.KeyVault/vaults/secrets/read",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
        "Microsoft.Insights/Logs/Read"
    ],
    "NotDataActions": [
        "Microsoft.KeyVault/vaults/secrets/write",
        "Microsoft.KeyVault/vaults/secrets/delete",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete"
    ],
    "AssignableScopes": [
        "/subscriptions/00000000-0000-0000-0000-000000000000",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SecurityOperations",
        "/providers/Microsoft.Management/managementGroups/SecurityTeam"
    ]
}


================================================
FILE: code-samples/json/deployment.json
================================================


================================================
FILE: code-samples/kusto/kusto.kql
================================================
// Security Investigation Query - Correlated Security Events Analysis
// Purpose: Detect potential lateral movement attempts by correlating failed login attempts
// with subsequent successful logins and suspicious process executions

// First, let's get failed login attempts
let FailedLogins = 
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4625  // Failed login attempt
    | where AccountType == "User"
    | project 
        TimeGenerated,
        SourceComputer = Computer,
        TargetAccount = tolower(TargetUserName),
        SourceIP = IpAddress,
        FailureReason = Status;

// Get successful logins that happened after failed attempts
let SuccessfulLogins =
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4624  // Successful login
    | where LogonType in (3, 10)  // Network and RemoteInteractive logons
    | project
        LoginTime = TimeGenerated,
        DestinationHost = Computer,
        TargetAccount = tolower(TargetUserName),
        LogonType,
        SourceIP = IpAddress;

// Get suspicious process executions
let SuspiciousProcesses =
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4688  // Process creation
    | where CommandLine has_any("mimikatz", "psexec", "wmic", "powershell -enc")
    | project
        ProcessTime = TimeGenerated,
        Host = Computer,
        Account = tolower(SubjectUserName),
        ProcessName = Process,
        CommandLine;

// Correlate all events
FailedLogins
| join kind=inner (
    SuccessfulLogins
    | where LoginTime > TimeGenerated  // Only get logins that happened after failed attempts
) on TargetAccount
| where LoginTime - TimeGenerated < timespan(1h)  // Within 1 hour
| join kind=leftouter (
    SuspiciousProcesses
    | where ProcessTime > TimeGenerated  // Only get processes that ran after failed attempts
) on $left.TargetAccount == $right.Account
| where ProcessTime - LoginTime < timespan(2h) or isnull(ProcessTime)  // Within 2 hours of successful login
| project
    InitialFailureTime = TimeGenerated,
    SuccessfulLoginTime = LoginTime,
    SuspiciousProcessTime = ProcessTime,
    TargetAccount,
    SourceIP,
    DestinationHost,
    FailureReason,
    LogonType,
    SuspiciousProcess = ProcessName,
    SuspiciousCommandLine = CommandLine
| sort by InitialFailureTime asc
| extend TimeBetweenFailureAndSuccess = datetime_diff('minute', SuccessfulLoginTime, InitialFailureTime)
| extend AlertSeverity = case(
    isnotnull(SuspiciousProcess), "High",
    TimeBetweenFailureAndSuccess < 10, "Medium",
    "Low"
)
| summarize
    FailedLoginCount = count(),
    UniqueSourceIPs = dcount(SourceIP),
    AffectedHosts = make_set(DestinationHost),
    SuspiciousProcesses = make_set(SuspiciousProcess)
    by TargetAccount, AlertSeverity
| extend RecommendedAction = case(
    AlertSeverity == "High", "Immediate investigation required. Consider account suspension.",
    AlertSeverity == "Medium", "Review login patterns and validate with user.",
    "Monitor for additional suspicious activity."
)


================================================
FILE: code-samples/powershell/azure-powershell.ps1
================================================


================================================
FILE: custom-rbac-role.json
================================================
{
    "Name": "Security Operations Analyst Custom Role",
    "IsCustom": true,
    "Description": "Allows security operations team to monitor security-related resources, manage security alerts, and perform specific remediation actions while maintaining separation of duties.",
    "Actions": [
        "Microsoft.Security/alerts/read",
        "Microsoft.Security/securitySolutions/read",
        "Microsoft.Security/policies/read",
        "Microsoft.Security/pricings/read",
        "Microsoft.Security/settings/read",
        "Microsoft.Security/assessments/read",
        "Microsoft.Network/networkWatchers/read",
        "Microsoft.Network/networkSecurityGroups/read",
        "Microsoft.KeyVault/vaults/read",
        "Microsoft.Insights/alertRules/*",
        "Microsoft.Resources/subscriptions/resourceGroups/read"
    ],
    "NotActions": [
        "Microsoft.KeyVault/vaults/delete",
        "Microsoft.KeyVault/vaults/write",
        "Microsoft.Network/networkSecurityGroups/write",
        "Microsoft.Network/networkSecurityGroups/delete"
    ],
    "DataActions": [
        "Microsoft.KeyVault/vaults/secrets/read",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
        "Microsoft.Insights/Logs/Read"
    ],
    "NotDataActions": [
        "Microsoft.KeyVault/vaults/secrets/write",
        "Microsoft.KeyVault/vaults/secrets/delete",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete"
    ],
    "AssignableScopes": [
        "/subscriptions/00000000-0000-0000-0000-000000000000",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SecurityOperations",
        "/providers/Microsoft.Management/managementGroups/SecurityTeam"
    ]
}


================================================
FILE: deployment.bicep
================================================
// AZ-500 Security Implementation Example
// Purpose: Demonstrates secure infrastructure deployment with multiple security controls

// Parameters
@description('Primary location for all resources')
param location string = resourceGroup().location

@description('Environment name')
@allowed([
  'Production'
  'Development'
  'Test'
])
param environmentName string

@description('IP addresses or ranges that should be allowed through the firewall')
param allowedIPRanges array

@description('Key Vault SKU')
@allowed([
  'standard'
  'premium'
])
param keyVaultSku string = 'premium'

@minLength(3)
@maxLength(24)
@description('Storage Account name')
param storageAccountName string

@secure()
@description('SQL Server administrator password')
param sqlServerAdminPassword string

// Variables
var networkSecurityGroupName = 'security-nsg'
var virtualNetworkName = 'security-vnet'
var keyVaultName = 'kv-${uniqueString(resourceGroup().id)}'
var logAnalyticsWorkspaceName = 'law-${uniqueString(resourceGroup().id)}'
var applicationInsightsName = 'ai-${uniqueString(resourceGroup().id)}'

// Tags
var commonTags = {
  Environment: environmentName
  SecurityContact: 'security@contoso.com'
  DataClassification: 'Confidential'
  ComplianceRequired: 'HIPAA'
}

// Network Security Group
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
  name: networkSecurityGroupName
  location: location
  tags: commonTags
  properties: {
    securityRules: [
      {
        name: 'DenyAllInbound'
        properties: {
          priority: 4096
          direction: 'Inbound'
          access: 'Deny'
          protocol: '*'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
          destinationPortRange: '*'
        }
      }
    ]
  }
}

// Virtual Network with Subnets
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
  name: virtualNetworkName
  location: location
  tags: commonTags
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/16'
      ]
    }
    subnets: [
      {
        name: 'ApplicationSubnet'
        properties: {
          addressPrefix: '10.0.1.0/24'
          networkSecurityGroup: {
            id: nsg.id
          }
          serviceEndpoints: [
            {
              service: 'Microsoft.KeyVault'
            }
            {
              service: 'Microsoft.Storage'
            }
            {
              service: 'Microsoft.Sql'
            }
          ]
        }
      }
      {
        name: 'DatabaseSubnet'
        properties: {
          addressPrefix: '10.0.2.0/24'
          delegations: [
            {
              name: 'sqlDelegation'
              properties: {
                serviceName: 'Microsoft.Sql/managedInstances'
              }
            }
          ]
        }
      }
    ]
  }
}

// Key Vault with RBAC and Advanced Security
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: keyVaultName
  location: location
  tags: commonTags
  properties: {
    tenantId: subscription().tenantId
    sku: {
      family: 'A'
      name: keyVaultSku
    }
    enableRbacAuthorization: true
    enablePurgeProtection: true
    enabledForTemplateDeployment: true
    enabledForDiskEncryption: true
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      ipRules: [for ip in allowedIPRanges: {
        value: ip
      }]
      virtualNetworkRules: [
        {
          id: '${vnet.id}/subnets/ApplicationSubnet'
        }
      ]
    }
  }
}

// Storage Account with Security Features
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  tags: commonTags
  sku: {
    name: 'Standard_GRS'
  }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
    encryption: {
      services: {
        blob: {
          enabled: true
        }
        file: {
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      virtualNetworkRules: [
        {
          id: '${vnet.id}/subnets/ApplicationSubnet'
          action: 'Allow'
        }
      ]
      ipRules: [for ip in allowedIPRanges: {
        value: ip
        action: 'Allow'
      }]
    }
  }
}

// Log Analytics Workspace
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
  name: logAnalyticsWorkspaceName
  location: location
  tags: commonTags
  properties: {
    sku: {
      name: 'PerGB2018'
    }
    retentionInDays: 90
    features: {
      enableLogAccessUsingOnlyResourcePermissions: true
    }
  }
}

// Application Insights for Security Monitoring
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: applicationInsightsName
  location: location
  tags: commonTags
  kind: 'web'
  properties: {
    Application_Type: 'web'
    WorkspaceResourceId: logAnalytics.id
    DisableIpMasking: false
    DisableLocalAuth: true
  }
}

// Diagnostic Settings for Key Vault
resource keyVaultDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  scope: keyVault
  name: 'KeyVaultAudit'
  properties: {
    workspaceId: logAnalytics.id
    logs: [
      {
        category: 'AuditEvent'
        enabled: true
        retentionPolicy: {
          enabled: true
          days: 90
        }
      }
    ]
    metrics: [
      {
        category: 'AllMetrics'
        enabled: true
        retentionPolicy: {
          enabled: true
          days: 90
        }
      }
    ]
  }
}

// Role Assignments
resource keyVaultAdminRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(keyVault.id, 'Key Vault Administrator')
  scope: keyVault
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')
    principalType: 'ServicePrincipal'
    principalId: 'YOUR-MANAGED-IDENTITY-ID'
  }
}

// Outputs
output keyVaultName string = keyVault.name
output storageAccountName string = storageAccount.name
output vnetName string = vnet.name
output logAnalyticsWorkspaceId string = logAnalytics.id


================================================
FILE: deployment.json
================================================


================================================
FILE: docs/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer using any of the [private contact addresses](https://github.com/timothywarner/az500#support). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>

For answers to common questions about this code of conduct, see <https://www.contributor-covenant.org/faq>


================================================
FILE: docs/CONTRIBUTING.md
================================================
# Contributing

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.

## Development environment setup

> **[?]**
> Proceed to describe how to setup local development environment.
> e.g:

To set up a development environment, please follow these steps:

1. Clone the repo

   ```sh
   git clone https://github.com/timothywarner/az500
   ```

2. TODO

## Issues and feature requests

You've found a bug in the source code, a mistake in the documentation or maybe you'd like a new feature? You can help us by submitting an issue to our [GitHub Repository](https://github.com/timothywarner/az500/issues). Before you create an issue, make sure you search the archive, maybe your question was already answered.

Please try to create bug reports that are:

- _Reproducible._ Include steps to reproduce the problem.
- _Specific._ Include as much detail as possible: which version, what environment, etc.
- _Unique._ Do not duplicate existing opened issues.
- _Scoped to a Single Bug._ One bug per report.

Even better: You could submit a pull request with a fix or new feature!

## Pull request process

1. Search our repository for open or closed
[pull requests](https://github.com/timothywarner/az500/pulls)
that relates to your submission. You don't want to duplicate effort.
2. Fork the project
3. Create your feature branch (`git checkout -b feat/amazing_feature`)
4. Commit your changes (`git commit -m 'feat: add amazing_feature'`)
5. Push to the branch (`git push origin feat/amazing_feature`)
6. Open a pull request

Exam AZ-500: Microsoft Azure Security Technologies Crash Course uses [conventional commits](https://www.conventionalcommits.org), so please follow the specification.


================================================
FILE: docs/SECURITY.md
================================================
# Security Policy

## Reporting a Vulnerability

If there are any vulnerability in **Exam AZ-500: Microsoft Azure Security Technologies Crash Course** project, don't hesitate to _report them_.

1. Use any of the [private contact addresses](https://github.com/timothywarner/az500#support).
2. Describe the vulnerability.

- If you have a fix, explain or attach it.
- In the near time, expect a reply with the required steps. Also, there may be a demand for a pull request which include the fixes.

> You should not disclose the vulnerability publicly if you haven't received an answer in some weeks.
> If the vulnerability is rejected, you may post it publicly within some hour of rejection, unless the rejection is withdrawn within that time period.
> After the vulnerability has been fixed, you may disclose the vulnerability details publicly over some days.


================================================
FILE: kusto.kql
================================================
// Security Investigation Query - Correlated Security Events Analysis
// Purpose: Detect potential lateral movement attempts by correlating failed login attempts
// with subsequent successful logins and suspicious process executions

// First, let's get failed login attempts
let FailedLogins = 
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4625  // Failed login attempt
    | where AccountType == "User"
    | project 
        TimeGenerated,
        SourceComputer = Computer,
        TargetAccount = tolower(TargetUserName),
        SourceIP = IpAddress,
        FailureReason = Status;

// Get successful logins that happened after failed attempts
let SuccessfulLogins =
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4624  // Successful login
    | where LogonType in (3, 10)  // Network and RemoteInteractive logons
    | project
        LoginTime = TimeGenerated,
        DestinationHost = Computer,
        TargetAccount = tolower(TargetUserName),
        LogonType,
        SourceIP = IpAddress;

// Get suspicious process executions
let SuspiciousProcesses =
    SecurityEvent
    | where TimeGenerated > ago(24h)
    | where EventID == 4688  // Process creation
    | where CommandLine has_any("mimikatz", "psexec", "wmic", "powershell -enc")
    | project
        ProcessTime = TimeGenerated,
        Host = Computer,
        Account = tolower(SubjectUserName),
        ProcessName = Process,
        CommandLine;

// Correlate all events
FailedLogins
| join kind=inner (
    SuccessfulLogins
    | where LoginTime > TimeGenerated  // Only get logins that happened after failed attempts
) on TargetAccount
| where LoginTime - TimeGenerated < timespan(1h)  // Within 1 hour
| join kind=leftouter (
    SuspiciousProcesses
    | where ProcessTime > TimeGenerated  // Only get processes that ran after failed attempts
) on $left.TargetAccount == $right.Account
| where ProcessTime - LoginTime < timespan(2h) or isnull(ProcessTime)  // Within 2 hours of successful login
| project
    InitialFailureTime = TimeGenerated,
    SuccessfulLoginTime = LoginTime,
    SuspiciousProcessTime = ProcessTime,
    TargetAccount,
    SourceIP,
    DestinationHost,
    FailureReason,
    LogonType,
    SuspiciousProcess = ProcessName,
    SuspiciousCommandLine = CommandLine
| sort by InitialFailureTime asc
| extend TimeBetweenFailureAndSuccess = datetime_diff('minute', SuccessfulLoginTime, InitialFailureTime)
| extend AlertSeverity = case(
    isnotnull(SuspiciousProcess), "High",
    TimeBetweenFailureAndSuccess < 10, "Medium",
    "Low"
)
| summarize
    FailedLoginCount = count(),
    UniqueSourceIPs = dcount(SourceIP),
    AffectedHosts = make_set(DestinationHost),
    SuspiciousProcesses = make_set(SuspiciousProcess)
    by TargetAccount, AlertSeverity
| extend RecommendedAction = case(
    AlertSeverity == "High", "Immediate investigation required. Consider account suspension.",
    AlertSeverity == "Medium", "Review login patterns and validate with user.",
    "Monitor for additional suspicious activity."
)


================================================
FILE: labs/LAB-SETUP.md
================================================
# AZ-500 Lab Environment Setup Guide

This guide will help you prepare your environment for the hands-on labs in this AZ-500 crash course.

## Prerequisites

### Azure Subscription

You'll need an Azure subscription with:
- Owner or Contributor rights
- Sufficient quota for creating the following resources:
  - Virtual Networks
  - Virtual Machines (2-3 B-series VMs)
  - Storage Accounts
  - Key Vault
  - Microsoft Defender for Cloud (Standard tier features)

### Recommended Options:
1. **Azure Pass** (if provided by instructor)
2. **Free Azure Account** ([Create here](https://azure.microsoft.com/en-us/free/))
3. **Visual Studio Subscription** (formerly MSDN)
4. **Company subscription** (if allowed for training)

### Local Environment Setup

1. **Required Software:**
   - [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) (latest version)
   - [PowerShell 7+](https://github.com/PowerShell/PowerShell#get-powershell)
   - [Az PowerShell module](https://docs.microsoft.com/en-us/powershell/azure/install-az-ps)
   - [Visual Studio Code](https://code.visualstudio.com/download)
   
2. **VS Code Extensions:**
   - [Azure Account](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
   - [Azure CLI Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-cli)
   - [PowerShell](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
   - [Azure Resource Manager Tools](https://marketplace.visualstudio.com/items?itemName=msazurermtools.azurerm-vscode-tools)

## Quick Setup Steps

### 1. Verify Azure CLI Installation

```bash
# Check version
az --version

# Login to Azure
az login

# List subscriptions
az account list --output table

# Set your subscription (if you have multiple)
az account set --subscription "Your-Subscription-Name-or-ID"
```

### 2. Verify PowerShell Setup

```powershell
# Check PowerShell version
$PSVersionTable.PSVersion

# Install/update Az module if needed
Install-Module -Name Az -Force -AllowClobber -Scope CurrentUser

# Login to Azure
Connect-AzAccount

# List subscriptions
Get-AzSubscription

# Set your subscription (if you have multiple)
Set-AzContext -Subscription "Your-Subscription-Name-or-ID"
```

### 3. Create Resource Group for Labs

```bash
# Azure CLI
az group create --name AZ500-Labs --location eastus2

# PowerShell
New-AzResourceGroup -Name AZ500-Labs -Location eastus2
```

### 4. Enable Microsoft Defender for Cloud

For some labs, we'll use Microsoft Defender for Cloud. Enable it in advance:

1. Navigate to **Microsoft Defender for Cloud** in the Azure Portal
2. Go to **Environment Settings**
3. Select your subscription
4. Enable the **Servers** and **Databases** plans (you can disable after the course)
5. Set **Continuous export** to **On**

### 5. Download Lab Files

Clone this repository to have local access to all lab files:

```bash
git clone https://github.com/timothywarner/az500
cd az500
```

## Troubleshooting Tips

### Cannot Create Resources / Permission Issues
- Verify you have Owner or Contributor role on your subscription
- Check if you have any Resource Policy restrictions
- Ensure you're working in the correct subscription

### Azure CLI or PowerShell Connection Issues
- Re-authenticate with `az login` or `Connect-AzAccount`
- Check your internet connection
- Verify any proxy or firewall settings

### Resource Creation Fails
- Check your subscription quota limits
- Try a different region if you're hitting regional limits
- Ensure you've accepted any required marketplace terms

## Getting Help During Labs

If you encounter issues during the labs:
1. Check the lab instructions carefully for any hints
2. Ask the instructor during the session
3. Search the [Microsoft Q&A for Azure](https://docs.microsoft.com/en-us/answers/products/azure?product=all)

Good luck with your labs! 

================================================
FILE: labs/README.md
================================================
# AZ-500 Hands-on Labs

This directory contains hands-on labs and exercises to help you practice Azure security concepts relevant to the AZ-500 exam.

## Lab Environment Setup

Before beginning the labs, ensure you have:

1. An **Azure subscription** with sufficient permissions
2. **Visual Studio Code** with Azure extensions installed
3. **Azure CLI** and **PowerShell** with Az modules
4. **Git** for downloading lab materials

## Lab Modules

The labs are organized to align with the main exam skill areas:

### Module 1: Identity and Access Management
- Configuring Microsoft Entra ID for workloads
- Implementing Privileged Identity Management
- Implementing RBAC and custom roles

### Module 2: Platform Protection
- Implementing network security
- Configuring advanced security for compute
- Implementing container security

### Module 3: Security Operations
- Configuring security policies
- Working with Microsoft Defender for Cloud
- Security monitoring with Azure Sentinel

### Module 4: Data and Application Security
- Configuring security for storage
- Configuring security for databases
- Implementing Azure Key Vault

## Using the Official Microsoft Labs

Microsoft provides an excellent set of official AZ-500 labs:

1. Visit the [Microsoft Learning AZ-500 GitHub Repository](https://microsoftlearning.github.io/AZ500-AzureSecurityTechnologies/)
2. Choose a lab module that matches your study area
3. Follow the step-by-step instructions
4. Review the concepts after completing each lab

## Lab Best Practices

- **Clean up resources** after completing labs to avoid unnecessary charges
- **Take notes** during labs to document key concepts and commands
- **Experiment beyond** the instructions to deepen your understanding
- **Create Azure free account** if you don't have a subscription

Remember that hands-on experience is crucial for mastering the skills needed for the AZ-500 exam. Try to complete all labs to ensure comprehensive preparation. 

================================================
FILE: scripts/blueprints/basic-networking-blueprint/Artifacts/7ddd6a5f-4815-4526-aa69-40bbffd263d3.json
================================================
{
  "kind": "roleAssignment",
  "properties": {
    "displayName": "Melissa Gaughan (melissa@timw.info) : Contributor",
    "dependsOn": [],
    "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
    "principalIds": [
      "f798da5e-6a8b-4150-949f-c393dc8314bb"
    ],
    "resourceGroup": "SingleRG"
  }
}

================================================
FILE: scripts/blueprints/basic-networking-blueprint/Artifacts/7ddd6a5f-4815-4526-aa69-40bbffd26cc7.json
================================================
{
  "kind": "policyAssignment",
  "properties": {
    "displayName": "Inherit a tag from the resource group if missing",
    "dependsOn": [],
    "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/ea3f2387-9b95-492a-a190-fcdc54f7b070",
    "parameters": {
      "tagName": {
        "value": "class"
      }
    },
    "resourceGroup": "SingleRG"
  }
}

================================================
FILE: scripts/blueprints/basic-networking-blueprint/Artifacts/nsg-template.json
================================================
{
  "kind": "template",
  "properties": {
    "displayName": "NSG for new VNET",
    "description": "",
    "dependsOn": [
      "vnet-and-subnet-template"
    ],
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "localPrefix": {
          "type": "string",
          "metadata": {
            "displayName": "Prefix for the resource names deployed in this template"
          }
        }
      },
      "variables": {
        "subnetId": "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', concat(parameters('localPrefix'),'vnet-blueprint'), concat(parameters('localPrefix'),'subnet-blueprint'))]",
        "location": "[resourceGroup().location]",
        "existingVirtualNetworkResourceGroupName": "[resourceGroup().name]",
        "existingVirtualNetworkName": "[concat(parameters('localPrefix'), 'vnet-blueprint')]",
        "existingSubnetName": "[concat(parameters('localPrefix'), 'subnet-blueprint')]",
        "newNsgName": "[concat(parameters('localPrefix'), 'nsg-blueprint')]"
      },
      "resources": [
        {
          "type": "Microsoft.Network/networkSecurityGroups",
          "apiVersion": "2018-04-01",
          "name": "[variables('newNsgName')]",
          "location": "[variables('location')]",
          "properties": {
            "securityRules": []
          }
        },
        {
          "apiVersion": "2018-02-01",
          "type": "Microsoft.Resources/deployments",
          "name": "associateNsg",
          "resourceGroup": "[resourceGroup().name]",
          "dependsOn": [
            "[variables('newNsgName')]"
          ],
          "properties": {
            "mode": "Incremental",
            "template": {
              "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
              "contentVersion": "1.0.0.0",
              "resources": [
                {
                  "apiVersion": "2018-04-01",
                  "type": "Microsoft.Network/virtualNetworks/subnets",
                  "name": "[concat(variables('existingVirtualNetworkName'), '/', variables('existingSubnetName'))]",
                  "location": "[variables('location')]",
                  "properties": {
                    "addressPrefix": "[reference(variables('subnetId'), '2018-04-01').addressPrefix]",
                    "networkSecurityGroup": {
                      "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('newNsgName'))]"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    },
    "resourceGroup": "SingleRG",
    "parameters": {
      "localPrefix": {
        "value": "[parameters('resourceNamePrefix')]"
      }
    }
  }
}

================================================
FILE: scripts/blueprints/basic-networking-blueprint/Artifacts/vnet-and-subnet-template.json
================================================
{
  "kind": "template",
  "properties": {
    "displayName": "VNET and one subnet",
    "dependsOn": [],
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "localPrefix": {
          "type": "string",
          "metadata": {
            "displayName": "Prefix for the resource names deployed in this template"
          }
        },
        "addressSpaceVnet": {
          "type": "string",
          "defaultValue": "10.0.0.0/16"
        },
        "addressSpaceSubnet": {
          "type": "string",
          "defaultValue": "10.0.0.0/24"
        }
      },
      "resources": [
        {
          "apiVersion": "2015-06-15",
          "type": "Microsoft.Network/virtualNetworks",
          "name": "[concat(parameters('localPrefix'), 'vnet-blueprint')]",
          "location": "[resourceGroup().location]",
          "properties": {
            "addressSpace": {
              "addressPrefixes": [
                "[parameters('addressSpaceVnet')]"
              ]
            },
            "subnets": [
              {
                "name": "[concat(parameters('localPrefix'), 'subnet-blueprint')]",
                "properties": {
                  "addressPrefix": "[parameters('addressSpaceSubnet')]"
                }
              }
            ]
          }
        }
      ]
    },
    "resourceGroup": "SingleRG",
    "parameters": {
      "localPrefix": {
        "value": "[parameters('resourceNamePrefix')]"
      },
      "addressSpaceVnet": {
        "value": "[parameters('addressSpaceForVnet')]"
      },
      "addressSpaceSubnet": {
        "value": "[parameters('addressSpaceForSubnet')]"
      }
    }
  }
}

================================================
FILE: scripts/blueprints/basic-networking-blueprint/Blueprint.json
================================================
{
  "properties": {
    "displayName": "Basic Networking (VNET)",
    "description": "Configures a virtual network with a subnet and an NSG.",
    "targetScope": "subscription",
    "parameters": {
      "resourceNamePrefix": {
        "type": "string",
        "metadata": {
          "displayName": "Resource name prefix",
          "description": "Resource group and resource name prefix"
        }
      },
      "addressSpaceForVnet": {
        "type": "string",
        "metadata": {
          "displayName": "Addess space for vnet"
        },
        "defaultValue": "10.0.0.0/16"
      },
      "addressSpaceForSubnet": {
        "type": "string",
        "metadata": {
          "displayName": "Addess space for subnet"
        },
        "defaultValue": "10.0.0.0/24"
      }
    },
    "resourceGroups": {
      "SingleRG": {
        "location": "eastus",
        "metadata": {
          "displayName": "VNET Resource Group"
        },
        "dependsOn": [],
        "tags": {
          "class": "user-group"
        }
      }
    },
    "blueprintName": "basic-networking-blueprint"
  }
}

================================================
FILE: scripts/blueprints/blueprints-references.txt
================================================
##### Azure Blueprints Learning Resources #####

Azure Blueprints documentation
https://docs.microsoft.com/en-us/azure/governance/blueprints/

Understand the lifecycle of a blueprint - Azure Blueprints | Microsoft Docs
https://docs.microsoft.com/en-us/azure/governance/blueprints/concepts/lifecycle

An overview of Azure Blueprints | Azure Friday - YouTube
https://www.youtube.com/watch?v=cQ9D-d6KkMY

Azure Governance - #3 - Policy & Blueprints - YouTube
https://www.youtube.com/watch?v=EwO25vecGUo

Sample Blueprint Definitions
https://github.com/azure/azure-blueprints

Azure Blueprint Tutorial
https://agazoth.github.io/blogpost/2018/11/11/Azure-Blueprint.html

Import/Export Azure Blueprints using Manage-AzureRMBlueprint PowerShell Script
https://www.youtube.com/watch?v=SMORUIPhKd8&feature=youtu.be

Azure Blueprints PowerShell
https://github.com/JimGBritt/AzureBlueprint/

Azure Blueprint PowerShell, Part 2
https://github.com/Agazoth/AzureBlueprint

Azure Blueprints via Azure DevOps Pipeline​
https://www.linkedin.com/pulse/azure-blueprints-via-devops-pipeline-paul-towler/

Azure Blueprints pipeline scripts
https://github.com/Azure/azure-blueprints/tree/master/pipelines-scripts

Azure Blueprints - Visual Studio Extension
https://marketplace.visualstudio.com/items?itemName=nepeters.azure-blueprints


================================================
FILE: scripts/blueprints/blueprints.ps1
================================================
<# Manage Azure Blueprints as code
   Tim Warner (techtrainertim.com)
   01-September-2020
#>

# Authenticate
Connect-AzAccount
Set-AzContext -SubscriptionName 'Microsoft Azure Sponsorship'

# Install the Blueprints module
Install-Module -Name Az.Blueprint -Verbose

# Export an existing Azure blueprint to the local system
$bp = Get-AzBlueprint -Name 'basic-networking-blueprint'

Export-AzBlueprintWithArtifact -Blueprint $bp -OutputPath '.' -Version '1.0'


# Push sample blueprint to Azure as a draft
Import-AzBlueprintWithArtifact -Name Boilerplate -ManagementGroupId "DevMG" -InputPath  ".\samples\101-boilerplate"

# Publish a new version so it can be assigned:
# Get the blueprint we just created
$bp = Get-AzBlueprint -Name Boilerplate -ManagementGroupId "DevMG"
# Publish version 1.0
Publish-AzBlueprint -Bluerpint $bp -Version 1.0

# Assign blueprint to a subscription
# Get the version of the blueprint you want to assign, which we will pas to New-AzBlueprintAssignment
$publishedBp = Get-AzBlueprint -ManagementGroupId "DevMG" -Name "Boilerplate" -LatestPublished

# Each resource group artifact in the blueprint will need a hashtable for the actual RG name and location
$rgHash = @{ name = "MyBoilerplateRG"; location = "eastus" }

# all other (non-rg) parameters are listed in a single hashtable, with a key/value pair for each parameter
$parameters = @{ principalIds = "caeebed6-cfa8-45ff-9d8a-03dba4ef9a7d" }

# All of the resource group artifact hashtables are themselves grouped into a parent hashtable
# the 'key' for each item in the table should match the RG placeholder name in the blueprint
$rgArray = @{ SingleRG = $rgHash }

# Assign the new blueprint to the specified subscription (Assignment updates should use Set-AzBlueprintAssignment
New-AzBlueprintAssignment -Blueprint $publishedBp -Location eastus -SubscriptionId "00000000-1111-0000-1111-000000000000" -ResourceGroupParameter $rgArray -Parameter $parameters

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/policyStorageTags.json
================================================
{
    "kind": "policyAssignment",
    "properties": {
        "displayName": "Apply storage tag to resource group",
        "description": "Apply storage tag and the parameter also used by the template to resource groups",
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/49c88fc8-6fd1-46fd-a676-f12d1d3a4c71",
        "parameters": {
            "tagName": {
                "value": "StorageType"
            },
            "tagValue": {
                "value": "[parameters('storageAccountType')]"
            }
        }
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/policyTags.json
================================================
{
    "kind": "policyAssignment",
    "properties": {
        "displayName": "Apply tag and its default value to resource groups",
        "description": "Apply tag and its default value to resource groups",
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/49c88fc8-6fd1-46fd-a676-f12d1d3a4c71",
        "parameters": {
            "tagName": {
                "value": "[parameters('tagName')]"
            },
            "tagValue": {
                "value": "[parameters('tagValue')]"
            }
        }
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/roleContributor.json
================================================
{
    "kind": "roleAssignment",
    "properties": {
        "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
        "principalIds": "[parameters('contributors')]"
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/roleOwner.json
================================================
{
    "kind": "roleAssignment",
    "properties": {
        "resourceGroup": "storageRG",
        "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
        "principalIds": "[parameters('owners')]"
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/templateStorage.json
================================================
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountTypeFromBP": {
            "type": "string",
            "metadata": {
                "description": "Storage Account type"
            }
        },
        "tagNameFromBP": {
            "type": "string",
            "defaultValue": "NotSet",
            "metadata": {
                "description": "Tag name from blueprint"
            }
        },
        "tagValueFromBP": {
            "type": "string",
            "defaultValue": "NotSet",
            "metadata": {
                "description": "Tag value from blueprint"
            }
        }
    },
    "variables": {
        "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'standardsa')]"
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            "apiVersion": "2016-01-01",
            "tags": {
                "[parameters('tagNameFromBP')]": "[parameters('tagValueFromBP')]"
            },
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "[parameters('storageAccountTypeFromBP')]"
            },
            "kind": "Storage",
            "properties": {}
        }
    ],
    "outputs": {
        "storageAccountSku": {
            "type": "string",
            "value": "[variables('storageAccountName')]"
        }
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/artifacts/templateStorageParams.json
================================================
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountTypeFromBP": {
            "value": "[parameters('storageAccountType')]"
        },
        "tagNameFromBP": {
            "value": "[parameters('tagName')]"
        },
        "tagValueFromBP": {
            "value": "[parameters('tagValue')]"
        }
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/blueprint.json
================================================
{
    "properties": {
        "description": "This blueprint sets tag policy and role assignment on the subscription, creates a ResourceGroup, and deploys a resource template and role assignment to that ResourceGroup.",
        "targetScope": "subscription",
        "parameters": {
            "storageAccountType": {
                "type": "string",
                "defaultValue": "Standard_LRS",
                "allowedValues": [
                    "Standard_LRS",
                    "Standard_GRS",
                    "Standard_ZRS",
                    "Premium_LRS"
                ],
                "metadata": {
                    "displayName": "storage account type.",
                    "description": null
                }
            },
            "tagName": {
                "type": "string",
                "metadata": {
                    "displayName": "The name of the tag to provide the policy assignment.",
                    "description": null
                }
            },
            "tagValue": {
                "type": "string",
                "metadata": {
                    "displayName": "The value of the tag to provide the policy assignment.",
                    "description": null
                }
            },
            "contributors": {
                "type": "array",
                "metadata": {
                    "description": "List of AAD object IDs that is assigned Contributor role at the subscription",
                    "strongType": "PrincipalId"
                }
            },
            "owners": {
                "type": "array",
                "metadata": {
                    "description": "List of AAD object IDs that is assigned Owner role at the resource group",
                    "strongType": "PrincipalId"
                }
            }
        },
        "resourceGroups": {
            "storageRG": {
                "description": "Contains the resource template deployment and a role assignment."
            }
        }
    }
}

================================================
FILE: scripts/blueprints/sample-blueprint/blueprintAssignment.json
================================================
{
    "properties": {
        "blueprintId": "/providers/Microsoft.Management/managementGroups/{YourMG}/providers/Microsoft.Blueprint/blueprints/MyBlueprint",
        "resourceGroups": {
            "storageRG": {
                "name": "StorageAccount",
                "location": "eastus2"
            }
        },
        "parameters": {
            "storageAccountType": {
                "value": "Standard_GRS"
            },
            "tagName": {
                "value": "CostCenter"
            },
            "tagValue": {
                "value": "ContosoIT"
            },
            "contributors": {
                "value": [
                    "7be2f100-3af5-4c15-bcb7-27ee43784a1f",
                    "38833b56-194d-420b-90ce-cff578296714"
                ]
            },
            "owners": {
                "value": [
                    "44254d2b-a0c7-405f-959c-f829ee31c2e7",
                    "316deb5f-7187-4512-9dd4-21e7798b0ef9"
                ]
            }
        }
    },
    "identity": {
        "type": "systemAssigned"
    },
    "location": "westus"
}

================================================
FILE: scripts/blueprints/warner-azure-blueprints.ps1
================================================
# Getting Started with Azure Blueprints
# Tim Warner (techtrainertim.com)

# Ref: https://timw.info/f88be

# Authenticate to Azure
Connect-AzAccount
Set-AzContext -SubscriptionName 'Microsoft Azure Sponsorship'

# Get Azure Blueprints module
Install-Module -Name Az.Blueprint -Force ; Update-Help -ErrorAction SilentlyContinue

# Get a reference to the sample blueprint object
$blueprint = New-AzBlueprint -Name 'MyBlueprint' -BlueprintFile .\blueprint.json

# Add artifacts
New-AzBlueprintArtifact -Blueprint $blueprint -Name 'roleContributor' -ArtifactFile .\artifacts\roleContributor.json

New-AzBlueprintArtifact -Blueprint $blueprint -Name 'policyTags' -ArtifactFile .\artifacts\policyTags.json

New-AzBlueprintArtifact -Blueprint $blueprint -Name 'policyStorageTags' -ArtifactFile .\artifacts\policyStorageTags.json

New-AzBlueprintArtifact -Blueprint $blueprint -Type TemplateArtifact -Name 'templateStorage' -TemplateFile .\artifacts\templateStorage.json -TemplateParameterFile .\artifacts\templateStorageParams.json -ResourceGroupName storageRG

New-AzBlueprintArtifact -Blueprint $blueprint -Name 'roleOwner' -ArtifactFile .\artifacts\roleOwner.json

# Publish the blueprint
Publish-AzBlueprint -Blueprint $blueprint -Version '1.0.0.0'

# Assign the blueprint
New-AzBlueprintAssignment -Blueprint $blueprint -Name 'assignMyBlueprint' -AssignmentFile .\blueprintAssignment.json

# Unassign the blueprint
Remove-AzBlueprintAssignment -Name 'assignMyBlueprint'


================================================
FILE: scripts/key-vault.azcli
================================================
# Manage Key Vault with CLI

# Ref: timw.info/1fg

# Preliminary info
az login

az configure

az account set --name "Microsoft Azure Sponsorship"

az account list -o table

# Add a secret
az keyvault secret set --vault-name "twaz500vault1" --name "VMPassword" --value "hVFkk965BuUv "

# View secrets
az keyvault secret list --vault-name "twaz500vault1"

# Retrieve a secret
az keyvault secret show --name "VMPassword" --vault-name "<your-unique-keyvault-name>" --query "value"

# Register service principal
az ad sp create-for-rbac -n "KeyVaultSP" --password "hVFkk965BuUv" --role Contributor
# If you don't specify a password, one will be created for you

# Allow SP to read secrets
az keyvault set-policy --name "twaz500vault1" --spn 8f8c4bbd-485b-45fd-98f7-ec6300b7b4ed --secret-permissions get





================================================
FILE: scripts/powershell/Dockerfile.txt
================================================
# Dockerfile needs that name with no extension in root of build folder.

# Sample Dockerfile

# Indicates that the windowsservercore image will be used as the base image.
FROM mcr.microsoft.com/windows/servercore:ltsc2019

# Metadata indicating an image maintainer.
LABEL maintainer="jshelton@contoso.com"

# Uses dism.exe to install the IIS role.
RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart

# Creates an HTML file and adds content to this file.
RUN echo "Hello World - Dockerfile" > c:\inetpub\wwwroot\index.html

# Sets a command or process that will run each time a container is run from the new image.
CMD [ "cmd" ]

# Build process
docker build -t iis-image-name .

# Run process

# Another Dockerfile

#Step 1: Start from base image mcr.microsoft.com/windows/servercore
FROM mcr.microsoft.com/windows/servercore

#Step 2: Create temporary directory to hold SQL Server 2016 installation files
RUN powershell -Command (mkdir C:\SQL2016Dev_SP2)

#Step 3: Copy SQL Server 2016 installation files from the host to the container image
COPY \SQL2016Dev_SP2 C:/SQL2016Dev_SP2

#Step 4: Install SQL Server 2016 via command line
RUN C:/SQL2016Dev_SP2/SETUP.exe /Q /ACTION=INSTALL /FEATURES=SQLENGINE /INSTANCENAME=MSSQLSERVER 
/SECURITYMODE=SQL /SAPWD="y0urSecUr3PAssw0rd" /SQLSVCACCOUNT="NT AUTHORITY\System" 
/AGTSVCACCOUNT="NT AUTHORITY\System" /SQLSYSADMINACCOUNTS="BUILTIN\Administrators" 
/IACCEPTSQLSERVERLICENSETERMS=1 /TCPENABLED=1 /UPDATEENABLED=False

#Step 5: Set SQL Server service to automatic
RUN powershell -Command (Set-Service MSSQLSERVER -StartupType Automatic)

#Step 6: Remove SQL Server installation media folder
RUN powershell -Command (Remove-Item -Path C:/SQL2016Dev_SP2 -Recurse -Force) 

#Step 7: Switch shell to PowerShell in preparation for running script Start.ps1
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

#Step 8: Copy Start.ps1 to image on root directory
COPY \start.ps1 /

#Step 9: Set current working directory for script execution
WORKDIR /

#Step 10: Run PowerShell script Start.ps1, passing the -ACCEPT_EULA parameter with a value of Y
CMD .\start.ps1 -ACCEPT_EULA "Y" -Verbose












================================================
FILE: scripts/powershell/Update-AutomationAzureModulesForAccount.ps1
================================================
<#
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
#>

<#
.SYNOPSIS
Update Azure PowerShell modules in an Azure Automation account.

.DESCRIPTION
This Azure Automation runbook updates Azure PowerShell modules imported into an
Azure Automation account with the module versions published to the PowerShell Gallery.

Prerequisite: an Azure Automation account with an Azure Run As account credential.

.PARAMETER ResourceGroupName
The Azure resource group name.

.PARAMETER AutomationAccountName
The Azure Automation account name.

.PARAMETER SimultaneousModuleImportJobCount
(Optional) The maximum number of module import jobs allowed to run concurrently.

.PARAMETER AzureModuleClass
(Optional) The class of module that will be updated (AzureRM or Az)
If set to Az, this script will rely on only Az modules to update other modules.
Set this to Az if your runbooks use only Az modules to avoid conflicts.

.PARAMETER AzureEnvironment
(Optional) Azure environment name.

.PARAMETER Login
(Optional) If $false, do not login to Azure.

.PARAMETER ModuleVersionOverrides
(Optional) Module versions to use instead of the latest on the PowerShell Gallery.
If $null, the currently published latest versions will be used.
If not $null, must contain a JSON-serialized dictionary, for example:
    '{ "AzureRM.Compute": "5.8.0", "AzureRM.Network": "6.10.0" }'
or
    @{ 'AzureRM.Compute'='5.8.0'; 'AzureRM.Network'='6.10.0' } | ConvertTo-Json

.PARAMETER PsGalleryApiUrl
(Optional) PowerShell Gallery API URL.

.LINK
https://docs.microsoft.com/en-us/azure/automation/automation-update-azure-modules
#>

[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
param(
    [Parameter(Mandatory = $true)]
    [string] $ResourceGroupName,

    [Parameter(Mandatory = $true)]
    [string] $AutomationAccountName,

    [int] $SimultaneousModuleImportJobCount = 10,

    [string] $AzureModuleClass = 'AzureRM',

    [string] $AzureEnvironment = 'AzureCloud',

    [bool] $Login = $true,

    [string] $ModuleVersionOverrides = $null,

    [string] $PsGalleryApiUrl = 'https://www.powershellgallery.com/api/v2'
)

$ErrorActionPreference = "Continue"

#region Constants

$script:AzureRMProfileModuleName = "AzureRM.Profile"
$script:AzureRMAutomationModuleName = "AzureRM.Automation"
$script:GetAzureRmAutomationModule = "Get-AzureRmAutomationModule"
$script:NewAzureRmAutomationModule = "New-AzureRmAutomationModule"

$script:AzAccountsModuleName = "Az.Accounts"
$script:AzAutomationModuleName = "Az.Automation"
$script:GetAzAutomationModule = "Get-AzAutomationModule"
$script:NewAzAutomationModule = "New-AzAutomationModule"

$script:AzureSdkOwnerName = "azure-sdk"

#endregion

#region Functions

function ConvertJsonDictTo-HashTable($JsonString) {
    try{
        $JsonObj = ConvertFrom-Json $JsonString -ErrorAction Stop
    } catch [System.ArgumentException] {
        throw "Unable to deserialize the JSON string for parameter ModuleVersionOverrides: ", $_
    }

    $Result = @{}
    foreach ($Property in $JsonObj.PSObject.Properties) {
        $Result[$Property.Name] = $Property.Value
    }

    $Result
}

# Use the Run As connection to login to Azure
function Login-AzureAutomation([bool] $AzModuleOnly) {
    try {
        $RunAsConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
        Write-Output "Logging in to Azure ($AzureEnvironment)..."

        if (!$RunAsConnection.ApplicationId) {
            $ErrorMessage = "Connection 'AzureRunAsConnection' is incompatible type."
            throw $ErrorMessage
        }

        if ($AzModuleOnly) {
            Connect-AzAccount `
                -ServicePrincipal `
                -TenantId $RunAsConnection.TenantId `
                -ApplicationId $RunAsConnection.ApplicationId `
                -CertificateThumbprint $RunAsConnection.CertificateThumbprint `
                -Environment $AzureEnvironment

            Select-AzSubscription -SubscriptionId $RunAsConnection.SubscriptionID  | Write-Verbose
        } else {
            Add-AzureRmAccount `
                -ServicePrincipal `
                -TenantId $RunAsConnection.TenantId `
                -ApplicationId $RunAsConnection.ApplicationId `
                -CertificateThumbprint $RunAsConnection.CertificateThumbprint `
                -Environment $AzureEnvironment

            Select-AzureRmSubscription -SubscriptionId $RunAsConnection.SubscriptionID  | Write-Verbose
        }
    } catch {
        if (!$RunAsConnection) {
            $RunAsConnection | fl | Write-Output
            Write-Output $_.Exception
            $ErrorMessage = "Connection 'AzureRunAsConnection' not found."
            throw $ErrorMessage
        }

        throw $_.Exception
    }
}

# Checks the PowerShell Gallery for the latest available version for the module
function Get-ModuleDependencyAndLatestVersion([string] $ModuleName) {

    $ModuleUrlFormat = "$PsGalleryApiUrl/Search()?`$filter={1}&searchTerm=%27{0}%27&targetFramework=%27%27&includePrerelease=false&`$skip=0&`$top=40"

    $ForcedModuleVersion = $ModuleVersionOverridesHashTable[$ModuleName]

    $CurrentModuleUrl =
        if ($ForcedModuleVersion) {
            $ModuleUrlFormat -f $ModuleName, "Version%20eq%20'$ForcedModuleVersion'"
        } else {
            $ModuleUrlFormat -f $ModuleName, 'IsLatestVersion'
        }

    $SearchResult = Invoke-RestMethod -Method Get -Uri $CurrentModuleUrl -UseBasicParsing

    if (!$SearchResult) {
        Write-Verbose "Could not find module $ModuleName on PowerShell Gallery. This may be a module you imported from a different location. Ignoring this module"
    } else {
        if ($SearchResult.Length -and $SearchResult.Length -gt 1) {
            $SearchResult = $SearchResult | Where-Object { $_.title.InnerText -eq $ModuleName }
        }

        if (!$SearchResult) {
            Write-Verbose "Could not find module $ModuleName on PowerShell Gallery. This may be a module you imported from a different location. Ignoring this module"
        } else {
            $PackageDetails = Invoke-RestMethod -Method Get -UseBasicParsing -Uri $SearchResult.id

            # Ignore the modules that are not published as part of the Azure SDK
            if ($PackageDetails.entry.properties.Owners -ne $script:AzureSdkOwnerName) {
                Write-Warning "Module : $ModuleName is not part of azure sdk. Ignoring this."
            } else {
                $ModuleVersion = $PackageDetails.entry.properties.version
                $Dependencies = $PackageDetails.entry.properties.dependencies

                @($ModuleVersion, $Dependencies)
            }
        }
    }
}

function Get-ModuleContentUrl($ModuleName) {
    $ModuleContentUrlFormat = "$PsGalleryApiUrl/package/{0}"
    $VersionedModuleContentUrlFormat = "$ModuleContentUrlFormat/{1}"

    $ForcedModuleVersion = $ModuleVersionOverridesHashTable[$ModuleName]
    if ($ForcedModuleVersion) {
        $VersionedModuleContentUrlFormat -f $ModuleName, $ForcedModuleVersion
    } else {
        $ModuleContentUrlFormat -f $ModuleName
    }
}

# Imports the module with given version into Azure Automation
function Import-AutomationModule([string] $ModuleName, [bool] $UseAzModule = $false) {

    $NewAutomationModule = $null
    $GetAutomationModule = $null
    if ($UseAzModule) {
        $GetAutomationModule = $script:GetAzAutomationModule
        $NewAutomationModule = $script:NewAzAutomationModule
    } else {
        $GetAutomationModule = $script:GetAzureRmAutomationModule
        $NewAutomationModule = $script:NewAzureRmAutomationModule
    }


    $LatestModuleVersionOnGallery = (Get-ModuleDependencyAndLatestVersion $ModuleName)[0]

    $ModuleContentUrl = Get-ModuleContentUrl $ModuleName
    # Find the actual blob storage location of the module
    do {
        $ModuleContentUrl = (Invoke-WebRequest -Uri $ModuleContentUrl -MaximumRedirection 0 -UseBasicParsing -ErrorAction Ignore).Headers.Location
    } while (!$ModuleContentUrl.Contains(".nupkg"))

    $CurrentModule = & $GetAutomationModule `
                        -Name $ModuleName `
                        -ResourceGroupName $ResourceGroupName `
                        -AutomationAccountName $AutomationAccountName

    if ($CurrentModule.Version -eq $LatestModuleVersionOnGallery) {
        Write-Output "Module : $ModuleName is already present with version $LatestModuleVersionOnGallery. Skipping Import"
    } else {
        Write-Output "Importing $ModuleName module of version $LatestModuleVersionOnGallery to Automation"

        & $NewAutomationModule `
            -ResourceGroupName $ResourceGroupName `
            -AutomationAccountName $AutomationAccountName `
            -Name $ModuleName `
            -ContentLink $ModuleContentUrl > $null
    }
}

# Parses the dependency got from PowerShell Gallery and returns name and version
function GetModuleNameAndVersionFromPowershellGalleryDependencyFormat([string] $Dependency) {
    if ($null -eq $Dependency) {
        throw "Improper dependency format"
    }

    $Tokens = $Dependency -split":"
    if ($Tokens.Count -ne 3) {
        throw "Improper dependency format"
    }

    $ModuleName = $Tokens[0]
    $ModuleVersion = $Tokens[1].Trim("[","]")

    @($ModuleName, $ModuleVersion)
}

# Validates if the given list of modules has already been added to the module import map
function AreAllModulesAdded([string[]] $ModuleListToAdd) {
    $Result = $true

    foreach ($ModuleToAdd in $ModuleListToAdd) {
        $ModuleAccounted = $false

        # $ModuleToAdd is specified in the following format:
        #       ModuleName:ModuleVersionSpecification:
        # where ModuleVersionSpecification follows the specifiation
        # at https://docs.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards
        # For example:
        #       AzureRm.profile:[4.0.0]:
        # or
        #       AzureRm.profile:3.0.0:
        # In any case, the dependency version specification is always separated from the module name with
        # the ':' character. The explicit intent of this runbook is to always install the latest module versions,
        # so we want to completely ignore version specifications here.
        $ModuleNameToAdd = $ModuleToAdd -replace '\:.*', ''

        foreach($AlreadyIncludedModules in $ModuleImportMapOrder) {
            if ($AlreadyIncludedModules -contains $ModuleNameToAdd) {
                $ModuleAccounted = $true
                break
            }
        }

        if (!$ModuleAccounted) {
            $Result = $false
            break
        }
    }

    $Result
}

# Creates a module import map. This is a 2D array of strings so that the first
# element in the array consist of modules with no dependencies.
# The second element only depends on the modules in the first element, the
# third element only dependes on modules in the first and second and so on.
function Create-ModuleImportMapOrder([bool] $AzModuleOnly) {
    $ModuleImportMapOrder = $null
    $ProfileOrAccountsModuleName = $null
    $GetAutomationModule = $null

    # Use the relevant module class to avoid conflicts
    if ($AzModuleOnly) {
        $ProfileOrAccountsModuleName = $script:AzAccountsModuleName
        $GetAutomationModule = $script:GetAzAutomationModule
    } else {
        $ProfileOrAccountsModuleName = $script:AzureRmProfileModuleName
        $GetAutomationModule = $script:GetAzureRmAutomationModule
    }

    # Get all the non-conflicting modules in the current automation account
    $CurrentAutomationModuleList = & $GetAutomationModule `
                                        -ResourceGroupName $ResourceGroupName `
                                        -AutomationAccountName $AutomationAccountName |
        ?{
            ($AzModuleOnly -and ($_.Name -eq 'Az' -or $_.Name -like 'Az.*')) -or
            (!$AzModuleOnly -and ($_.Name -eq 'AzureRM' -or $_.Name -like 'AzureRM.*' -or
            $_.Name -eq 'Azure' -or $_.Name -like 'Azure.*'))
        }

    # Get the latest version of the AzureRM.Profile OR Az.Accounts module
    $VersionAndDependencies = Get-ModuleDependencyAndLatestVersion $ProfileOrAccountsModuleName

    $ModuleEntry = $ProfileOrAccountsModuleName
    $ModuleEntryArray = ,$ModuleEntry
    $ModuleImportMapOrder += ,$ModuleEntryArray

    do {
        $NextAutomationModuleList = $null
        $CurrentChainVersion = $null
        # Add it to the list if the modules are not available in the same list
        foreach ($Module in $CurrentAutomationModuleList) {
            $Name = $Module.Name

            Write-Verbose "Checking dependencies for $Name"
            $VersionAndDependencies = Get-ModuleDependencyAndLatestVersion $Module.Name
            if ($null -eq $VersionAndDependencies) {
                continue
            }

            $Dependencies = $VersionAndDependencies[1].Split("|")

            $AzureModuleEntry = $Module.Name

            # If the previous list contains all the dependencies then add it to current list
            if ((-not $Dependencies) -or (AreAllModulesAdded $Dependencies)) {
                Write-Verbose "Adding module $Name to dependency chain"
                $CurrentChainVersion += ,$AzureModuleEntry
            } else {
                # else add it back to the main loop variable list if not already added
                if (!(AreAllModulesAdded $AzureModuleEntry)) {
                    Write-Verbose "Module $Name does not have all dependencies added as yet. Moving module for later import"
                    $NextAutomationModuleList += ,$Module
                }
            }
        }

        $ModuleImportMapOrder += ,$CurrentChainVersion
        $CurrentAutomationModuleList = $NextAutomationModuleList

    } while ($null -ne $CurrentAutomationModuleList)

    $ModuleImportMapOrder
}

# Wait and confirm that all the modules in the list have been imported successfully in Azure Automation
function Wait-AllModulesImported(
            [Collections.Generic.List[string]] $ModuleList,
            [int] $Count,
            [bool] $UseAzModule = $false) {

    $GetAutomationModule = if ($UseAzModule) {
        $script:GetAzAutomationModule
    } else {
        $script:GetAzureRmAutomationModule
    }

    $i = $Count - $SimultaneousModuleImportJobCount
    if ($i -lt 0) { $i = 0 }

    for ( ; $i -lt $Count; $i++) {
        $Module = $ModuleList[$i]

        Write-Output ("Checking import Status for module : {0}" -f $Module)
        while ($true) {
            $AutomationModule = & $GetAutomationModule `
                                    -Name $Module `
                                    -ResourceGroupName $ResourceGroupName `
                                    -AutomationAccountName $AutomationAccountName

            $IsTerminalProvisioningState = ($AutomationModule.ProvisioningState -eq "Succeeded") -or
                                           ($AutomationModule.ProvisioningState -eq "Failed")

            if ($IsTerminalProvisioningState) {
                break
            }

            Write-Verbose ("Module {0} is getting imported" -f $Module)
            Start-Sleep -Seconds 30
        }

        if ($AutomationModule.ProvisioningState -ne "Succeeded") {
            Write-Error ("Failed to import module : {0}. Status : {1}" -f $Module, $AutomationModule.ProvisioningState)
        } else {
            Write-Output ("Successfully imported module : {0}" -f $Module)
        }
    }
}

# Uses the module import map created to import modules.
# It will only import modules from an element in the array if all the modules
# from the previous element have been added.
function Import-ModulesInAutomationAccordingToDependency([string[][]] $ModuleImportMapOrder, [bool] $UseAzModule) {

    foreach($ModuleList in $ModuleImportMapOrder) {
        $i = 0
        Write-Output "Importing Array of modules : $ModuleList"
        foreach ($Module in $ModuleList) {
            Write-Verbose ("Importing module : {0}" -f $Module)
            Import-AutomationModule -ModuleName $Module -UseAzModule $UseAzModule
            $i++
            if ($i % $SimultaneousModuleImportJobCount -eq 0) {
                # It takes some time for the modules to start getting imported.
                # Sleep for sometime before making a query to see the status
                Start-Sleep -Seconds 20
                Wait-AllModulesImported -ModuleList $ModuleList -Count $i -UseAzModule $UseAzModule
            }
        }

        if ($i -lt $SimultaneousModuleImportJobCount) {
            Start-Sleep -Seconds 20
            Wait-AllModulesImported -ModuleList $ModuleList -Count $i -UseAzModule $UseAzModule
        }
    }
}

function Update-ProfileAndAutomationVersionToLatest([string] $AutomationModuleName) {
    # Get the latest azure automation module version
    $VersionAndDependencies = Get-ModuleDependencyAndLatestVersion $AutomationModuleName

    # Automation only has dependency on profile
    $ModuleDependencies = GetModuleNameAndVersionFromPowershellGalleryDependencyFormat $VersionAndDependencies[1]
    $ProfileModuleName = $ModuleDependencies[0]

    # Create web client object for downloading data
    $WebClient = New-Object System.Net.WebClient

    # Download AzureRM.Profile to temp location
    $ModuleContentUrl = Get-ModuleContentUrl $ProfileModuleName
    $ProfileURL = (Invoke-WebRequest -Uri $ModuleContentUrl -MaximumRedirection 0 -UseBasicParsing -ErrorAction Ignore).Headers.Location
    $ProfilePath = Join-Path $env:TEMP ($ProfileModuleName + ".zip")
    $WebClient.DownloadFile($ProfileURL, $ProfilePath)

    # Download AzureRM.Automation to temp location
    $ModuleContentUrl = Get-ModuleContentUrl $AutomationModuleName
    $AutomationURL = (Invoke-WebRequest -Uri $ModuleContentUrl -MaximumRedirection 0 -UseBasicParsing -ErrorAction Ignore).Headers.Location
    $AutomationPath = Join-Path $env:TEMP ($AutomationModuleName + ".zip")
    $WebClient.DownloadFile($AutomationURL, $AutomationPath)

    # Create folder for unzipping the Module files
    $PathFolderName = New-Guid
    $PathFolder = Join-Path $env:TEMP $PathFolderName

    # Unzip files
    $ProfileUnzipPath = Join-Path $PathFolder $ProfileModuleName
    Expand-Archive -Path $ProfilePath -DestinationPath $ProfileUnzipPath -Force
    $AutomationUnzipPath = Join-Path $PathFolder $AutomationModuleName
    Expand-Archive -Path $AutomationPath -DestinationPath $AutomationUnzipPath -Force

    # Import modules
    Import-Module (Join-Path $ProfileUnzipPath ($ProfileModuleName + ".psd1")) -Force -Verbose
    Import-Module (Join-Path $AutomationUnzipPath ($AutomationModuleName + ".psd1")) -Force -Verbose
}

#endregion

#region Main body

if ($ModuleVersionOverrides) {
    $ModuleVersionOverridesHashTable = ConvertJsonDictTo-HashTable $ModuleVersionOverrides
} else {
    $ModuleVersionOverridesHashTable = @{}
}


$UseAzModule = $null
$AutomationModuleName = $null

# We want to support updating Az modules. This means this runbook should support upgrading using only Az modules
if ($AzureModuleClass -eq "Az") {
    $UseAzModule = $true
    $AutomationModuleName = $script:AzAutomationModuleName
} elseif ( $AzureModuleClass -eq "AzureRM") {
    $UseAzModule = $false
    $AutomationModuleName = $script:AzureRMAutomationModuleName
} else {
     Write-Error "Invalid AzureModuleClass: '$AzureModuleClass'. Must be either Az or AzureRM" -ErrorAction Stop
}

# Import the latest version of the Az automation and accounts version to the local sandbox
Update-ProfileAndAutomationVersionToLatest $AutomationModuleName

if ($Login) {
    Login-AzureAutomation $UseAzModule
}

$ModuleImportMapOrder = Create-ModuleImportMapOrder $UseAzModule
Import-ModulesInAutomationAccordingToDependency $ModuleImportMapOrder $UseAzModule


#endregion

================================================
FILE: scripts/powershell/aad-pim-powershell.ps1
================================================
# install Azure PowerShell
Install-Module -Name Az -Verbose

# install Azure AD module
Install-Module -Name AzureADPreview -Verbose
Import-Module -Name AzureADPreview

# connect to Azure and AAD
Connect-AzAccount
Connect-AzureAD

# get AAD PIM commands

Get-Command -Noun AzureADMSPriv*

Get-AzureADMSPrivilegedRoleDefinition -ProviderId aadRoles -ResourceId 926d99e7-117c-4a6a-8031-0cc481e9da26

# MS PIM module https://timw.info/5ut

# install the module
Install-Module -Name Microsoft.Azure.ActiveDirectory.PIM.PSModule -force -allowclobber

# import and view commands & help
Import-Module -Name Microsoft.Azure.ActiveDirectory.PIM.PSModule

Get-Command -Module Microsoft.Azure.ActiveDirectory.PIM.PSModule

Tutorial: https://timw.info/14r

================================================
FILE: scripts/powershell/app-gateway-e2e-tls.ps1
================================================
<# End-to-End TLS for Application Gateway

Ref: timw.info/ys2

Note: This is only a partial procedure

#>

# Configure the certificate for the application gateway. This certificate is used to decrypt and reencrypt the traffic on the application gateway.
$passwd = ConvertTo-SecureString  <certificate file password> -AsPlainText -Force
$cert = New-AzApplicationGatewaySSLCertificate -Name cert01 -CertificateFile <full path to .pfx file> -Password $passwd

# Create the HTTP listener for the application gateway. Assign the front-end IP configuration, port, and TLS/SSL certificate to use.
$listener = New-AzApplicationGatewayHttpListener -Name listener01 -Protocol Https -FrontendIPConfiguration $fipconfig -FrontendPort $fp -SSLCertificate $cert

# V1: Upload the certificate to be used on the TLS-enabled back-end pool resources. The certificate provided in the previous step should be the public key of the .pfx certificate present on the back end.
$authcert = New-AzApplicationGatewayAuthenticationCertificate -Name 'allowlistcert1' -CertificateFile C:\cert.cer

# V2: create a trusted root certificate instead of an authentication certificate
$trustedRootCert01 = New-AzApplicationGatewayTrustedRootCertificate -Name "test1" -CertificateFile  <path to root cert file>

# Configure the HTTP settings for the application gateway back end. Assign the certificate uploaded in the preceding step to the HTTP settings.
$poolSetting01 = New-AzApplicationGatewayBackendHttpSettings -Name “setting01” -Port 443 -Protocol Https -CookieBasedAffinity Disabled -TrustedRootCertificate $trustedRootCert01 -HostName "test1"

================================================
FILE: scripts/powershell/application-security-groups.ps1
================================================
# create the ASGs
$webAsg = New-AzApplicationSecurityGroup -ResourceGroupName 'Load-Balancer' -Name webASG -Location 'eastus2'

# Assign vNICs to ASG
$webNic = Get-AzNetworkInterface -Name 'myNIC0' -ResourceGroupName 'Load-Balancer'
$webNic.IpConfigurations[0].ApplicationSecurityGroups = $webAsg
Set-AzNetworkInterface -NetworkInterface $webNic

$webNic = Get-AzNetworkInterface -Name 'myNIC1' -ResourceGroupName 'Load-Balancer'
$webNic.IpConfigurations[0].ApplicationSecurityGroups = $webAsg
Set-AzNetworkInterface -NetworkInterface $webNic

================================================
FILE: scripts/powershell/azcopy.txt
================================================
# Use AzCopy

# Ref: https://timw.info/d0a73

# Sign in (you can also use SAS tokens and managed identities)
azcopy login --tenant-id=<tenant-id>

# Create a container
azcopy make 'https://mystorageaccount.blob.core.windows.net/mycontainer'

# Upload a file
azcopy copy 'C:\myDirectory\myTextFile.txt' 'https://mystorageaccount.blob.core.windows.net/mycontainer/myTextFile.txt'

# Upload files
azcopy copy 'C:\myDirectory' 'https://mystorageaccount.blob.core.windows.net/mycontainer' --include-path 'photos;documents\myFile.txt' --recursive

# Copy a blob to another storage account
azcopy copy 'https://mysourceaccount.blob.core.windows.net/mycontainer/myTextFile.txt?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-07-04T05:30:08Z&st=2019-07-03T21:30:08Z&spr=https&sig=CAfhgnc9gdGktvB=ska7bAiqIddM845yiyFwdMH481QA8%3D' 'https://mydestinationaccount.blob.core.windows.net/mycontainer/myTextFile.txt'

# Copy all containers and blobs to another storage account	azcopy copy 'https://mysourceaccount.blob.core.windows.net/?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-07-04T05:30:08Z&st=2019-07-03T21:30:08Z&spr=https&sig=CAfhgnc9gdGktvB=ska7bAiqIddM845yiyFwdMH481QA8%3D' 'https://mydestinationaccount.blob.core.windows.net' --recursive


================================================
FILE: scripts/powershell/azure-key-vault-powershell.ps1
================================================
<# Work with Azure Key Vault and PowerShell

   Ref: https://docs.microsoft.com/en-us/azure/key-vault/quick-create-powershell
#>

# Set up environment
Login-AzAccount

New-AzResourceGroup -Name ContosoResourceGroup -Location EastUS

New-AzKeyVault -Name 'Contoso-Vault2' -ResourceGroupName 'ContosoResourceGroup' -Location 'East US'

# Convert a plaintext secret to a secure string
$secretvalue = ConvertTo-SecureString 'hVFkk965BuUv' -AsPlainText -Force

# Store the secret in key vault
$secret = Set-AzKeyVaultSecret -VaultName 'ContosoKeyVault' -Name 'ExamplePassword' -SecretValue $secretvalue

# Retrieve the key value
(Get-AzKeyVaultSecret -vaultName "Contosokeyvault" -name "ExamplePassword").SecretValueText

# Clean up the environment
Remove-AzResourceGroup -Name ContosoResourceGroup

================================================
FILE: scripts/powershell/azuresql-database-tde.ps1
================================================
# Set variables
$resourceGroup = ''
$dbServerName = ''
$dbName = ''
$keyVaultName = ''
$keyVaultKeyId = (Get-AzureKeyVaultKey -VaultName '' -Name '').Id

# Add a service principal for SQL server
$server = Set-AzSqlServer -ResourceGroupName $resourceGroup -ServerName $dbServerName -AssignIdentity

# Grand key vault permissions to server
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName `
    -ObjectId $server.Identity.PrincipalId -PermissionsToKeys get, wrapKey, unwrapKey

# add the key from Key Vault to the server
Add-AzSqlServerKeyVaultKey -ResourceGroupName $resourceGroup -ServerName $dbServerName -KeyId $keyVaultKeyId

# set the key as the TDE protector for all resources under the server
Set-AzSqlServerTransparentDataEncryptionProtector -ResourceGroupName $resourceGroup -ServerName $dbServerName `
    -Type AzureKeyVault -KeyId $keyVaultKeyId

# confirm the TDE protector was configured as intended
Get-AzSqlServerTransparentDataEncryptionProtector -ResourceGroupName $resourceGroup -ServerName $dbServerName

# Enable TDE
Set-AzSqlDatabaseTransparentDataEncryption -ResourceGroupName $resourceGroup `
    -ServerName $dbServerName -DatabaseName $dbName -State "Enabled"

# Check encryption state
# get the encryption state
Get-AzSqlDatabaseTransparentDataEncryption -ResourceGroupName $resourceGroup `
    -ServerName $dbServerName -DatabaseName $dbName `

# check the encryption progress for a database or data warehouse
Get-AzSqlDatabaseTransparentDataEncryptionActivity -ResourceGroupName $resourceGroup `
    -ServerName $dbServerName -DatabaseName $dbName

# Turn off TDE
Set-AzSqlDatabaseTransparentDataEncryption -ServerName $dbServerName -ResourceGroupName $resourceGroup `
    -DatabaseName $dbName -State "Disabled"






================================================
FILE: scripts/powershell/backup-key-vault.ps1
================================================
Get-Command -Module Az.KeyVault

Backup-AzKeyVaultSecret -VaultName 'MyKeyVault' -Name 'MySecret' -OutputFile 'C:\Backup.blob' -Force

================================================
FILE: scripts/powershell/convert-vhd.ps1
================================================
# Convert VHDX to VHD 
Convert-VHD -Path 'C:\users\public\Documents\Hyper-V\Virtual hard disks\win16template.vhdx' -DestinationPath 'c:\VHD\win16template.vhd' -Verbose

# Launch Sysprep
Start-Process -FilePath 'C:\Windows\System32\Sysprep\sysprep.exe'

# Upload to Azure blob storage



================================================
FILE: scripts/powershell/cosmos-container-rbac.ps1
================================================
# Ref: https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac

# Install PowerShell Core
Install-Module -Name PSReleaseTools
Get-PSCore

# Install Azure PowerShell
Install-Module -Name Az -Verbose
Update-Help

# Get Cosmos DB preview module
Find-Module -Name Az.CosmosDB -AllowPrerelease
Install-Module -Name Az.CosmosDB -Verbose -Force

# Sign into Azure
Connect-AzAccount
Set-AzContext -SubscriptionName ''

# RO
$resourceGroupName = "dp201"
$accountName = "twdp201cosmos"
New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -Type CustomRole -RoleName MyReadOnlyRole `
    -DataAction @( `
        'Microsoft.DocumentDB/databaseAccounts/readMetadata',
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed') `
    -AssignableScope "/"

# RW
New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -Type CustomRole -RoleName MyReadWriteRole `
    -DataAction @( `
        'Microsoft.DocumentDB/databaseAccounts/readMetadata',
    'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*') `
    -AssignableScope "/" #acct or /dbs/db/colls/container

# Fetch role IDs
Get-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName

# Assign a role
$readOnlyRoleDefinitionId = "<roleDefinitionId>" # as fetched above
$principalId = "<aadPrincipalId>" #object ID
New-AzCosmosDBSqlRoleAssignment -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -RoleDefinitionId $readOnlyRoleDefinitionId `
    -Scope $accountName `
    -PrincipalId $principalId


================================================
FILE: scripts/powershell/create-aks-cluster.ps1
================================================
Ref 1: https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough

# Create resource group
az group create --name aks --location eastus

# Create cluster
az aks create --resource-group aks --name oreillyAKS --node-count 1 --enable-addons monitoring --generate-ssh-keys

<#
SSH key files '/home/tim/.ssh/id_rsa' and '/home/tim/.ssh/id_rsa.pub' have been generated under ~/.ssh to allow SSH access to the VM. If using machines without permanent storage like Azure Cloud Shell without an attached file share, back up your keys to a safe location
#>
# Connect to the cluster
az aks install-cli

az aks get-credentials --resource-group aks --name oreillyAKS

kubectl get nodes

# Deploy the application (YAML is in cloud drive)
kubectl apply -f azure-vote.yaml

# Test the application (CTRL+C to stop)
kubectl get service azure-vote-front --watch

# Browse to load balancer external IP

# Start the Kubernetes dashboard
az aks browse --resource-group aks --name oreillyAKS

# Sign into the dashboard (K8S 1.16+)
kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard

## Update <RESOURCE_GROUP and <AKS_NAME> with your input.

kubectl config view -o jsonpath='{.users[?(@.name == "clusterUser_aks_oreillyAKS")].user.auth-provider.config.access-token}'



================================================
FILE: scripts/powershell/create-azure-bastion.ps1
================================================
# ref: https://timw.info/5ei
# ref2: https://timw.info/p1c

# Create delegated subnet
$subnetName = "AzureBastionSubnet"
$subnet = New-AzVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix 10.0.0.0/24
$vnet = New-AzVirtualNetwork -Name "myVnet" -ResourceGroupName "myBastionRG" -Location "westeurope" -AddressPrefix 10.0.0.0/16 -Subnet $subnet

# Create public IP
$publicip = New-AzPublicIpAddress -ResourceGroupName "myBastionRG" -name "myPublicIP" -location "westeurope" -AllocationMethod Static -Sku Standard

# Create Bastion
$bastion = New-AzBastion -ResourceGroupName "myBastionRG" -Name "myBastion" -PublicIpAddress $publicip -VirtualNetwork $vnet

================================================
FILE: scripts/powershell/create-key-vault.ps1
================================================
Get-AzContext | Format-List

New-AzResourceGroup -Name 'cs' -Location EastUS

New-AzKeyVault -Name 'cs-vault' -ResourceGroupName 'cs' -Location 'East US'

Set-AzKeyVaultAccessPolicy -VaultName 'cs-vault' `
    -UserPrincipalName 'tim@timw.info' `
    -PermissionsToSecrets get, set, delete

$secretvalue = ConvertTo-SecureString '?!hVFkk965BuUv!?' -AsPlainText -Force

$secretset = Set-AzKeyVaultSecret -VaultName 'cs-vault' `
    -Name 'cs-password' -SecretValue $secretvalue

$secretget = Get-AzKeyVaultSecret -VaultName 'cs-vault' -Name 'ExamplePassword'

$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)

try {
    $secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
}
finally {
    [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
}
Write-Output $secretValueText

================================================
FILE: scripts/powershell/custom-azure-rbac-role.ps1
================================================
# Ref: https://docs.microsoft.com/en-us/azure/role-based-access-control/tutorial-custom-role-powershell

Get-AzProviderOperation 'Microsoft.Storage/*' | Format-Table -Property Operation, Description -AutoSize

Get-AzRoleDefinition -Name 'Virtual Machine Contributor' | ConvertTo-Json | Out-File 'D:\vmcontrib.json'

code D:\vmcontrib.json

Get-AzSubscription | Select-Object -Property id

New-AzRoleDefinition -InputFile 'D:\vmcontrib.json'

Get-AzRoleDefinition | Where-Object -FilterScript { $_.IsCustom -eq $true } | Format-Table -Property Name, IsCustom

Get-AzRoleDefinition 'Help Desk Support' | Remove-AzRoleDefinition -Force

Get-AzRoleDefinition | Where-Object { $_.IsCustom -eq $true } | Remove-AzRoleDefinition -Force

Remove-AzRoleDefinition -Id '22222222-2222-2222-2222-222222222222'

================================================
FILE: scripts/powershell/custom-rbac-role.ps1
================================================
# Ref: https://docs.microsoft.com/en-us/azure/role-based-access-control/tutorial-custom-role-powershell

# ARM REST API Ref: https://docs.microsoft.com/en-us/rest/api/azure/

Get-AzProviderOperation 'Microsoft.Network/*' | Format-Table -Property Operation, Description -AutoSize

Get-AzRoleDefinition -Name 'Virtual Machine Contributor' | ConvertTo-Json | Out-File 'D:\vmc2022.json'

Get-AzSubscription -SubscriptionName 'Microsoft Azure Sponsorship' | Select-Object -Property id
# 2fbf906e-1101-4bc0-b64f-adc44e462fff

New-AzRoleDefinition -InputFile 'D:\vmc2022.json'

Get-AzRoleDefinition | Where-Object -FilterScript { $_.IsCustom -eq $true } | Format-Table -Property Name, IsCustom

Get-AzRoleDefinition 'VM Admnistrator' | Remove-AzRoleDefinition -Force

Get-AzRoleDefinition | ? { $_.IsCustom -eq $true } | Remove-AzRoleDefinition -Force

Remove-AzRoleDefinition -Id 'fb31d481-00fd-4214-8f47-c030bcc59099'

================================================
FILE: scripts/powershell/customscriptextension.ps1
================================================
$fileUri = @("https://xxxxxxx.blob.core.windows.net/buildServer1/1_Add_Tools.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/2_Add_Features.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/3_CompleteInstall.ps1")

$settings = @{"fileUris" = $fileUri};

$storageAcctName = "xxxxxxx"
$storageKey = "1234ABCD"
$protectedSettings = @{"storageAccountName" = $storageAcctName; "storageAccountKey" = $storageKey; "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File 1_Add_Tools.ps1"};

#run command
Set-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -Location <locationName> `
    -VMName <vmName> `
    -Name "buildserver1" `
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion "1.10" `
    -Settings $settings    `
    -ProtectedSettings $protectedSettings `

================================================
FILE: scripts/powershell/enable-azuresql-database-tde.ps1
================================================
EXECUTE sp_set_database_firewall_rule N'my_db_rule';
,'168.0.0.0'
,'168.0.0.0'

-- Enable Azure connections.
EXECUTE sp_set_database_firewall_rule N'Allow Azure', '0.0.0.0', '0.0.0.0';

-- Create database-level firewall setting for only IP 0.0.0.4
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.4';

-- Update database-level firewall setting to create a range of allowed IP addresses
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.6';

================================================
FILE: scripts/powershell/enforce-tag-value-rg.json
================================================
{
    "properties": {
        "displayName": "Enforce tag and its value on resource groups",
        "description": "Enforces a required tag and its value on resource groups.",
        "mode": "All",
        "parameters": {
            "tagName": {
                "type": "String",
                "metadata": {
                    "description": "Name of the tag, such as costCenter"
                }
            },
            "tagValue": {
                "type": "String",
                "metadata": {
                    "description": "Value of the tag, such as headquarters"
                }
            }
        },
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "field": "type",
                        "equals": "Microsoft.Resources/subscriptions/resourceGroups"
                    },
                    {
                        "not": {
                            "field": "[concat('tags[',parameters('tagName'), ']')]",
                            "equals": "[parameters('tagValue')]"
                        }
                    }
                ]
            },
            "then": {
                "effect": "deny"
            }
        }
    }
}

================================================
FILE: scripts/powershell/installWebServer.ps1
================================================
Install-WindowsFeature -name Web-Server -IncludeManagementTools

================================================
FILE: scripts/powershell/linux-vm-ssh-keys.ps1
================================================
# Linux VM / SSH Keys

# Generate SSH key pair
ssh-keygen -t rsa -b 2048

# Display your public key
cat ~/.ssh/id_rsa.pub

# SSH into your VM
ssh user@vmaddress

# Quick create VM
# Create a subnet configuration
$subnetConfig = New-AzVirtualNetworkSubnetConfig `
    -Name "mySubnet" `
    -AddressPrefix 192.168.1.0/24

# Create a virtual network
$vnet = New-AzVirtualNetwork `
    -ResourceGroupName "myResourceGroup" `
    -Location "EastUS" `
    -Name "myVNET" `
    -AddressPrefix 192.168.0.0/16 `
    -Subnet $subnetConfig

# Create a public IP address and specify a DNS name
$pip = New-AzPublicIpAddress `
    -ResourceGroupName "myResourceGroup" `
    -Location "EastUS" `
    -AllocationMethod Static `
    -IdleTimeoutInMinutes 4 `
    -Name "mypublicdns$(Get-Random)"

# Create an inbound network security group rule for port 22
$nsgRuleSSH = New-AzNetworkSecurityRuleConfig `
    -Name "myNetworkSecurityGroupRuleSSH"  `
    -Protocol "Tcp" `
    -Direction "Inbound" `
    -Priority 1000 `
    -SourceAddressPrefix * `
    -SourcePortRange * `
    -DestinationAddressPrefix * `
    -DestinationPortRange 22 `
    -Access "Allow"

# Create an inbound network security group rule for port 80
$nsgRuleWeb = New-AzNetworkSecurityRuleConfig `
    -Name "myNetworkSecurityGroupRuleWWW"  `
    -Protocol "Tcp" `
    -Direction "Inbound" `
    -Priority 1001 `
    -SourceAddressPrefix * `
    -SourcePortRange * `
    -DestinationAddressPrefix * `
    -DestinationPortRange 80 `
    -Access "Allow"

# Create a network security group
$nsg = New-AzNetworkSecurityGroup `
    -ResourceGroupName "myResourceGroup" `
    -Location "EastUS" `
    -Name "myNetworkSecurityGroup" `
    -SecurityRules $nsgRuleSSH, $nsgRuleWeb

# Create a virtual network card and associate with public IP address and NSG
$nic = New-AzNetworkInterface `
    -Name "myNic" `
    -ResourceGroupName "myResourceGroup" `
    -Location "EastUS" `
    -SubnetId $vnet.Subnets[0].Id `
    -PublicIpAddressId $pip.Id `
    -NetworkSecurityGroupId $nsg.Id

# Define a credential object
$securePassword = ConvertTo-SecureString ' ' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("azureuser", $securePassword)

# Create a virtual machine configuration
$vmConfig = New-AzVMConfig `
    -VMName "myVM" `
    -VMSize "Standard_D1" | `
    Set-AzVMOperatingSystem `
    -Linux `
    -ComputerName "myVM" `
    -Credential $cred `
    -DisablePasswordAuthentication | `
    Set-AzVMSourceImage `
    -PublisherName "Canonical" `
    -Offer "UbuntuServer" `
    -Skus "16.04-LTS" `
    -Version "latest" | `
    Add-AzVMNetworkInterface `
    -Id $nic.Id

# Configure the SSH key
$sshPublicKey = cat ~/.ssh/id_rsa.pub
Add-AzVMSshPublicKey `
    -VM $vmconfig `
    -KeyData $sshPublicKey `
    -Path "/home/azureuser/.ssh/authorized_keys"

New-AzVM `
    -ResourceGroupName "myResourceGroup" `
    -Location eastus -VM $vmConfig

# Connect to the VM
Get-AzPublicIpAddress -ResourceGroupName "myResourceGroup" | Select "IpAddress"

ssh azureuser@10.111.12.123

# Install a web server
sudo apt-get -y update
sudo apt-get -y install nginx

# Browser to http://pubip


================================================
FILE: scripts/powershell/managed-storage-account.ps1
================================================
#Prefix for resources
$prefix = "tlw704"

#Basic variables
$location = "eastus"
$id = Get-Random -Minimum 1000 -Maximum 9999

#Create a resource group for Key Vault
$keyVaultGroup = New-AzResourceGroup -Name "$prefix-key-vault-$id" -Location $location

#Create a new Key Vault
$keyVaultParameters = @{
    Name = "$prefix-key-vault-$id"
    ResourceGroupName = $keyVaultGroup.ResourceGroupName
    Location = $location
    Sku = "Standard"
}

$keyVault = New-AzKeyVault @keyVaultParameters

#Grant yourself access to the Key Vault
# Give your user principal access to all storage account permissions, on your Key Vault instance
$accessPolicy = @{
    VaultName = $keyVault.Name
    UserPrincipalName = "tim@timw.info"
    PermissionsToStorage = ("get","list","listsas","delete","set","update","regeneratekey","recover","backup","restore","purge")
}

Set-AzKeyVaultAccessPolicy @accessPolicy

$keyVault | Format-List

#Create a new storage account
$saAccountParameters = @{
    Name = "$($prefix)sa$id"
    ResourceGroupName = $keyVaultGroup.ResourceGroupName
    Location = $location
    SkuName = "Standard_LRS"
}

$storageAccount = New-AzStorageAccount @saAccountParameters

Get-AzStorageAccountKey -ResourceGroupName $storageAccount.ResourceGroupName -Name $storageAccount.StorageAccountName

$keyVaultSpAppId = "cfa8b339-82a2-471a-a3c9-0fc0be7a4093"

New-AzRoleAssignment -ApplicationId $keyVaultSpAppId -RoleDefinitionName 'Storage Account Key Operator Service Role' -Scope $storageAccount.Id

# Add your storage account to your Key Vault's managed storage accounts list
$managedStorageAccount = @{
    VaultName = $keyVault.VaultName
    AccountName = $storageAccount.StorageAccountName
    AccountResourceId = $storageAccount.Id
    ActiveKeyName = "key1"
    RegenerationPeriod = [System.Timespan]::FromDays(90)
}

Add-AzKeyVaultManagedStorageAccount @managedStorageAccount

Get-AzKeyVaultManagedStorageAccount -VaultName $keyVault.VaultName

# Regenerate keys and set key1 as active key
Update-AzKeyVaultManagedStorageAccountKey -VaultName $keyVault.VaultName -AccountName $storageAccount.StorageAccountName -KeyName "key1"

================================================
FILE: scripts/powershell/networking.ps1
================================================
# Azure Networking

###### CREATE NEW MULTI-TIER VNET ######
# Variables for common values
$rgName='MyResourceGroup'
$location='eastus'

# Create user object
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."

# Create a resource group.
New-AzResourceGroup -Name $rgName -Location $location

# Create a virtual network with a front-end subnet and back-end subnet.
$fesubnet = New-AzVirtualNetworkSubnetConfig -Name 'MySubnet-FrontEnd' -AddressPrefix '10.0.1.0/24'
$besubnet = New-AzVirtualNetworkSubnetConfig -Name 'MySubnet-BackEnd' -AddressPrefix '10.0.2.0/24'
$vnet = New-AzVirtualNetwork -ResourceGroupName $rgName -Name 'MyVnet' -AddressPrefix '10.0.0.0/16' `
  -Location $location -Subnet $fesubnet, $besubnet

# Create an NSG rule to allow HTTP traffic in from the Internet to the front-end subnet.
$rule1 = New-AzNetworkSecurityRuleConfig -Name 'Allow-HTTP-All' -Description 'Allow HTTP' `
  -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 `
  -SourceAddressPrefix Internet -SourcePortRange * `
  -DestinationAddressPrefix * -DestinationPortRange 80

# Create an NSG rule to allow RDP traffic from the Internet to the front-end subnet.
$rule2 = New-AzNetworkSecurityRuleConfig -Name 'Allow-RDP-All' -Description "Allow RDP" `
  -Access Allow -Protocol Tcp -Direction Inbound -Priority 200 `
  -SourceAddressPrefix Internet -SourcePortRange * `
  -DestinationAddressPrefix * -DestinationPortRange 3389


# Create a network security group for the front-end subnet.
$nsgfe = New-AzNetworkSecurityGroup -ResourceGroupName $RgName -Location $location `
  -Name 'MyNsg-FrontEnd' -SecurityRules $rule1,$rule2

# Associate the front-end NSG to the front-end subnet.
Set-AzVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name 'MySubnet-FrontEnd' `
  -AddressPrefix '10.0.1.0/24' -NetworkSecurityGroup $nsgfe

# Create an NSG rule to allow SQL traffic from the front-end subnet to the back-end subnet.
$rule1 = New-AzNetworkSecurityRuleConfig -Name 'Allow-SQL-FrontEnd' -Description "Allow SQL" `
  -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 `
  -SourceAddressPrefix '10.0.1.0/24' -SourcePortRange * `
  -DestinationAddressPrefix * -DestinationPortRange 1433

# Create an NSG rule to allow RDP traffic from the Internet to the back-end subnet.
$rule2 = New-AzNetworkSecurityRuleConfig -Name 'Allow-RDP-All' -Description "Allow RDP" `
  -Access Allow -Protocol Tcp -Direction Inbound -Priority 200 `
  -SourceAddressPrefix Internet -SourcePortRange * `
  -DestinationAddressPrefix * -DestinationPortRange 3389

# Create a network security group for back-end subnet.
$nsgbe = New-AzNetworkSecurityGroup -ResourceGroupName $RgName -Location $location `
  -Name "MyNsg-BackEnd" -SecurityRules $rule1,$rule2

# Associate the back-end NSG to the back-end subnet
Set-AzVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name 'MySubnet-BackEnd' `
  -AddressPrefix '10.0.2.0/24' -NetworkSecurityGroup $nsgbe

# Create a public IP address for the web server VM.
$publicipvm1 = New-AzPublicIpAddress -ResourceGroupName $rgName -Name 'MyPublicIp-Web' `
  -location $location -AllocationMethod Dynamic

# Create a NIC for the web server VM.
$nicVMweb = New-AzNetworkInterface -ResourceGroupName $rgName -Location $location `
  -Name 'MyNic-Web' -PublicIpAddress $publicipvm1 -NetworkSecurityGroup $nsgfe -Subnet $vnet.Subnets[0]

# Create a Web Server VM in the front-end subnet
$vmConfig = New-AzVMConfig -VMName 'MyVm-Web' -VMSize 'Standard_DS2' | `
  Set-AzVMOperatingSystem -Windows -ComputerName 'MyVm-Web' -Credential $cred | `
  Set-AzVMSourceImage -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' `
  -Skus '2016-Datacenter' -Version latest | Add-AzVMNetworkInterface -Id $nicVMweb.Id

$vmweb = New-AzVM -ResourceGroupName $rgName -Location $location -VM $vmConfig

# Create a public IP address for the SQL VM.
$publicipvm2 = New-AzPublicIpAddress -ResourceGroupName $rgName -Name MyPublicIP-Sql `
  -location $location -AllocationMethod Dynamic

# Create a NIC for the SQL VM.
$nicVMsql = New-AzNetworkInterface -ResourceGroupName $rgName -Location $location `
  -Name MyNic-Sql -PublicIpAddress $publicipvm2 -NetworkSecurityGroup $nsgbe -Subnet $vnet.Subnets[1]

# Create a SQL VM in the back-end subnet.
$vmConfig = New-AzVMConfig -VMName 'MyVm-Sql' -VMSize 'Standard_DS2' | `
  Set-AzVMOperatingSystem -Windows -ComputerName 'MyVm-Sql' -Credential $cred | `
  Set-AzVMSourceImage -PublisherName 'MicrosoftSQLServer' -Offer 'SQL2016-WS2016' `
  -Skus 'Web' -Version latest | Add-AzVMNetworkInterface -Id $nicVMsql.Id

$vmsql = New-AzVM -ResourceGroupName $rgName -Location $location -VM $vmConfig

# Create an NSG rule to block all outbound traffic from the back-end subnet to the Internet (must be done after VM creation)
$rule3 = New-AzNetworkSecurityRuleConfig -Name 'Deny-Internet-All' -Description "Deny Internet All" `
  -Access Deny -Protocol Tcp -Direction Outbound -Priority 300 `
  -SourceAddressPrefix * -SourcePortRange * `
  -DestinationAddressPrefix Internet -DestinationPortRange *

# Add NSG rule to Back-end NSG
$nsgbe.SecurityRules.add($rule3)

Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsgb###### CREATE NEW


###### PIER TWO VNETS ######
# Variables for common values
$rgName = 'MyResourceGroup'
$location = 'eastus'

# Create a resource group.
New-AzResourceGroup -Name $rgName -Location $location

# Create virtual network 1.
$vnet1 = New-AzVirtualNetwork -ResourceGroupName $rgName -Name 'Vnet1' -AddressPrefix '10.0.0.0/16' -Location $location

# Create virtual network 2.
$vnet2 = New-AzVirtualNetwork -ResourceGroupName $rgName -Name 'Vnet2' -AddressPrefix '10.1.0.0/16' -Location $location

# Peer VNet1 to VNet2.
Add-AzVirtualNetworkPeering -Name 'LinkVnet1ToVnet2' -VirtualNetwork $vnet1 -RemoteVirtualNetworkId $vnet2.Id

# Peer VNet2 to VNet1.
Add-AzVirtualNetworkPeering -Name 'LinkVnet2ToVnet1' -VirtualNetwork $vnet2 -RemoteVirtualNetworkId $vnet1.Id

























================================================
FILE: scripts/powershell/password-reset.ps1
================================================
net user tim P@$$w0rd123!

New-Item -Name 'extension.txt' -Path 'C:\' -ItemType File -Value 'It works.' -Force

================================================
FILE: scripts/powershell/policy-enforce-tag-value-rg.json
================================================
{
    "properties": {
        "displayName": "Enforce tag and its value on resource groups",
        "description": "Enforces a required tag and its value on resource groups.",
        "mode": "All",
        "parameters": {
            "tagName": {
                "type": "String",
                "metadata": {
                    "description": "Name of the tag, such as costCenter"
                }
            },
            "tagValue": {
                "type": "String",
                "metadata": {
                    "description": "Value of the tag, such as headquarters"
                }
            }
        },
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "field": "type",
                        "equals": "Microsoft.Resources/subscriptions/resourceGroups"
                    },
                    {
                        "not": {
                            "field": "[concat('tags[',parameters('tagName'), ']')]",
                            "equals": "[parameters('tagValue')]"
                        }
                    }
                ]
            },
            "then": {
                "effect": "deny"
            }
        }
    }
}

================================================
FILE: scripts/powershell/powershell-key-vault.ps1
================================================
# PowerShell Key Vault (Ref: https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-powershell)

# Convert a secret to a secure string
$secretvalue = ConvertTo-SecureString 'hVFkk965BuUv' -AsPlainText -Force

# Create a secret
$secret = Set-AzKeyVaultSecret -VaultName 'oreilly-vault-001' `
  -Name 'ExamplePassword' -SecretValue $secretvalue

# View the secret in plain text
(Get-AzKeyVaultSecret -vaultName "oreilly-vault-001" -name "ExamplePassword").SecretValueText


================================================
FILE: scripts/powershell/storage-account.ps1
================================================
# Azure Storage Accounts

# List storage accounts
Get-AzStorageAccount | Select StorageAccountName, Location

# Retrieve an existing storage account
$resourceGroup = "myexistingresourcegroup"
$storageAccountName = "myexistingstorageaccount"

$storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroup `
    -Name $storageAccountName

# Create a storage account
# Get list of locations and select one.
Get-AzLocation | select Location
$location = "eastus"

# Create a new resource group.
$resourceGroup = "teststoragerg"
New-AzResourceGroup -Name $resourceGroup -Location $location

# Set the name of the storage account and the SKU name.
$storageAccountName = "testpshstorage"
$skuName = "Standard_LRS"

# Create the storage account.
$storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroup `
    -Name $storageAccountName `
    -Location $location `
    -SkuName $skuName

# Retrieve the context.
$ctx = $storageAccount.Context

# Manage access keys
$storageAccountKey = `
(Get-AzStorageAccountKey `
        -ResourceGroupName $resourceGroup `
        -Name $storageAccountName).Value[0]


# Regenerate the key
New-AzStorageAccountKey -ResourceGroupName $resourceGroup `
    -Name $storageAccountName `
    -KeyName key1

# Delete the storage account
Remove-AzStorageAccount -ResourceGroup $resourceGroup -AccountName $storageAccountName













================================================
FILE: scripts/powershell/taxonomic-tags.ps1
================================================
# Resource Groups and Taxonomic Tags

# See existing tags on a resource group
(Get-AzResourceGroup -Name 'oreilly').Tags

# See existing tags for a particular resource
(Get-AzResource -ResourceId /subscriptions/<subscription-id>/resourceGroups/oreilly/providers/Microsoft.Storage/storageAccounts/<storage-name>).Tags

# See existing tags for a named resource
(Get-AzResource -ResourceName 'oreilly-keyvault1' -ResourceGroupName 'oreilly').Tags

# Get resource groups that have a specific tag
(Get-AzResourceGroup -Tag @{ Dept = "Finance" }).ResourceGroupName

# Get resources that have a specific tag
(Get-AzResource -Tag @{ Dept = "Finance" }).Name

# Get resources that have a specific tag name
(Get-AzResource -TagName Dept).Name

# Add tags to RG without existing tags
Set-AzResourceGroup -Name oreilly -Tag @{ Dept = "IT"; Environment = "Test" }

# Add tags to RG that has existing tags
$tags = (Get-AzResourceGroup -Name oreilly).Tags
$tags.Add("Status", "Approved")
Set-AzResourceGroup -Tag $tags -Name oreilly

# Apply tags from an RG to its resources, preserving existing tags
$group = Get-AzResourceGroup "oreilly"
if ($null -ne $group.Tags) {
    $resources = Get-AzResource -ResourceGroupName $group.ResourceGroupName
    foreach ($r in $resources) {
        $resourcetags = (Get-AzResource -ResourceId $r.ResourceId).Tags
        if ($resourcetags) {
            foreach ($key in $group.Tags.Keys) {
                if (-not($resourcetags.ContainsKey($key))) {
                    $resourcetags.Add($key, $group.Tags[$key])
                }
            }
            Set-AzResource -Tag $resourcetags -ResourceId $r.ResourceId -Force
        }
        else {
            Set-AzResource -Tag $group.Tags -ResourceId $r.ResourceId -Force
        }
    }
}

# Remove all tags
Set-AzResourceGroup -Tag @{ } -Name oreilly

================================================
FILE: scripts/powershell/validate-deploy-arm-template.ps1
================================================
Set-Location -Path '~\azure-admin-crash-course\101-storage-account-create'

code .\azuredeploy.json
code .\azuredeploy.parameters.json

Test-AzResourceGroupDeployment -ResourceGroupName oreilly -Mode Incremental -TemplateFile .\azuredeploy.json -TemplateParameterFile

New-AzResourceGroupDeployment -Name 'deploy-storage-account' `
    -ResourceGroupName oreilly `
    -Mode Incremental `
    -TemplateParameterFile '.\azuredeploy.json' `
    -Verbose

================================================
FILE: scripts/powershell/vm-key-vault.parameters.json
================================================
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "value": "tim"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/2fbf906e-1101-4bc0-b64f-adc44e462fff/resourceGroups/INSTRUCTOR/providers/Microsoft.KeyVault/vaults/TimKV"
        },
        "secretName": "vm-password"
      }
    },

    "dnsLabelPrefix": {
      "value": "newvm79347a"
    }
  }
}

================================================
FILE: scripts/powershell/vm-key-vault.template.json
================================================
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "type": "string",
      "defaultValue":  "tim",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the Virtual Machine."
      }
    },
    "dnsLabelPrefix": {
      "type": "string",
      "metadata": {
        "description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
      }
    },
    "windowsOSVersion": {
      "type": "string",
      "defaultValue": "2019-Datacenter",
      "allowedValues": [
        "2008-R2-SP1",
        "2012-Datacenter",
        "2012-R2-Datacenter",
        "2016-Nano-Server",
        "2016-Datacenter-with-Containers",
        "2016-Datacenter",
        "2019-Datacenter"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_A2_v2",
      "metadata": {
        "description": "Size of the virtual machine."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    }
  },
  "variables": {
    "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'sawinvm')]",
    "nicName": "myVMNic",
    "addressPrefix": "10.0.0.0/16",
    "subnetName": "Subnet",
    "subnetPrefix": "10.0.0.0/24",
    "publicIPAddressName": "myPublicIP",
    "vmName": "SimpleWinVM",
    "virtualNetworkName": "MyVNET",
    "subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]",
    "networkSecurityGroupName": "default-NSG"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2018-11-01",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2018-11-01",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAllocationMethod": "Dynamic",
        "dnsSettings": {
          "domainNameLabel": "[parameters('dnsLabelPrefix')]"
        }
      }
    },
    {
      "comments":  "Default Network Security Group for template",
      "type":  "Microsoft.Network/networkSecurityGroups",
      "apiVersion":  "2019-08-01",
      "name":  "[variables('networkSecurityGroupName')]",
      "location":  "[parameters('location')]",
      "properties": {
        "securityRules": [
          {
            "name":  "default-allow-3389",
            "properties": {
              "priority":  1000,
              "access":  "Allow",
              "direction":  "Inbound",
              "destinationPortRange":  "3389",
              "protocol":  "Tcp",
              "sourcePortRange":  "*",
              "sourceAddressPrefix":  "*",
              "destinationAddressPrefix":  "*"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2018-11-01",
      "name": "[variables('virtualNetworkName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
      ],
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetPrefix')]",
              "networkSecurityGroup": {
                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2018-11-01",
      "name": "[variables('nicName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2018-10-01",
      "name": "[variables('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
        "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "[parameters('windowsOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage"
          },
          "dataDisks": [
            {
              "diskSizeGB": 1023,
              "lun": 0,
              "createOption": "Empty"
            }
          ]
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
            "enabled": true,
            "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob]"
          }
        }
      }
    }
  ],
  "outputs": {
    "hostname": {
      "type": "string",
      "value": "[reference(variables('publicIPAddressName')).dnsSettings.fqdn]"
    }
  }
}


================================================
FILE: scripts/powershell/vnet-peering.ps1
================================================
<# VNet Peering with Azure PowerShell
Ref: http://rb.gy/b2fonv
#>

# create a resource group
New-AzResourceGroup -ResourceGroupName myResourceGroup -Location EastUS

# create a virtual network

$virtualNetwork1 = New-AzVirtualNetwork `
  -ResourceGroupName myResourceGroup `
  -Location EastUS `
  -Name myVirtualNetwork1 `
  -AddressPrefix 10.0.0.0/16

# Add VNet config
$subnetConfig = Add-AzVirtualNetworkSubnetConfig `
  -Name Subnet1 `
  -AddressPrefix 10.0.0.0/24 `
  -VirtualNetwork $virtualNetwork1

# Commit the config to the VNet
$virtualNetwork1 | Set-AzVirtualNetwork

# Create a second VNet
$virtualNetwork2 = New-AzVirtualNetwork `
  -ResourceGroupName myResourceGroup `
  -Location EastUS `
  -Name myVirtualNetwork2 `
  -AddressPrefix 10.1.0.0/16

# Create the subnet configuration.
$subnetConfig = Add-AzVirtualNetworkSubnetConfig `
  -Name Subnet1 `
  -AddressPrefix 10.1.0.0/24 `
  -VirtualNetwork $virtualNetwork2

# Write the subnet configuration to the virtual network.
$virtualNetwork2 | Set-AzVirtualNetwork

# Create a peering
Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork1-myVirtualNetwork2 `
  -VirtualNetwork $virtualNetwork1 `
  -RemoteVirtualNetworkId $virtualNetwork2.Id

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork2-myVirtualNetwork1 `
  -VirtualNetwork $virtualNetwork2 `
  -RemoteVirtualNetworkId $virtualNetwork1.Id

# Get the peering status
Get-AzVirtualNetworkPeering `
  -ResourceGroupName myResourceGroup `
  -VirtualNetworkName myVirtualNetwork1 `
  | Select-Object PeeringState


================================================
FILE: scripts/powershell/webjob.ps1
================================================
New-Item -Path D:\ -Name webjob.txt -Value "Hi there"

================================================
FILE: scripts/sql/azure-sql-database-firewall-rules.sql
================================================
EXECUTE sp_set_database_firewall_rule N'my_db_rule';
,'168.0.0.0'
,'168.0.0.0'

-- Enable Azure connections.
EXECUTE sp_set_database_firewall_rule N'Allow Azure', '0.0.0.0', '0.0.0.0';

-- Create database-level firewall setting for only IP 0.0.0.4
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.4';

-- Update database-level firewall setting to create a range of allowed IP addresses
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.6';

================================================
FILE: scripts/sql/azure-sql-row-level-security.sql
================================================
-- Row-level security
-- Ref: https://timw.info/zwx



================================================
FILE: scripts/sql/azuresql-database-firewall.sql
================================================
EXECUTE sp_set_database_firewall_rule N'my_db_rule';
,'168.0.0.0'
,'168.0.0.0'

-- Enable Azure connections.
EXECUTE sp_set_database_firewall_rule N'Allow Azure', '0.0.0.0', '0.0.0.0';

-- Create database-level firewall setting for only IP 0.0.0.4
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.4';

-- Update database-level firewall setting to create a range of allowed IP addresses
EXECUTE sp_set_database_firewall_rule N'Example DB Setting 1', '0.0.0.4', '0.0.0.6';

================================================
FILE: study-resources/AZ-500-Teaching-Punchlist.md
================================================
# AZ-500 Teaching Punchlist

## Segment 1: Identity and Access (10 AM - 11 AM)
- **Manage Entra Identities**
  - Users, groups, external identities
  - Entra ID Protection: MFA, passwordless, Conditional Access
  - Single sign-on (SSO), OAuth, and app registrations
  - Privileged Identity Management (PIM), custom roles, and permissions

## Segment 2: Secure Storage (11 AM - 12 PM)
- **Plan and Implement Storage Security**
  - Access control: Azure Blob, File, Table, Queue
  - Protect data: soft delete, versioning, immutable storage
  - Encryption: BYOK, double encryption, TDE (databases)
  - Auditing and compliance: Purview and dynamic masking

## Segment 3: Secure Compute (12 PM - 1 PM)
- **Plan and Implement Compute Security**
  - Azure Bastion, Just-in-Time (JIT) VM access
  - AKS security: network isolation, monitoring, and authentication
  - Disk encryption: ADE, encryption at host, confidential disk encryption

## Segment 4: Monitoring and Security Operations (1 PM - 2 PM)
- **Monitor and Secure Operations**
  - Microsoft Defender: Secure Score, compliance, and threat protection
  - Azure Key Vault: manage secrets, certificates, and keys
  - Azure Monitor: configure and evaluate alerts
  - Microsoft Sentinel: analytics, incidents, and automation

## Segment 5: Wrap-up and Q&A (2 PM - 3 PM)
- **Q&A and Additional Topics**
  - Recap of key topics: identity, storage, compute, and monitoring
  - Answer audience questions
  - Explore real-world use cases and advanced scenarios


================================================
FILE: study-resources/AZ-500-cert-study-resources.md
================================================
# Exam AZ-500 Certification Study Resources

Last updated: March 2024

## Official Microsoft Learning Resources

* [AZ-500 Exam Page]
Download .txt
gitextract_20_50j8_/

├── .github/
│   └── workflows/
│       └── check-readme-links.yml
├── .gitignore
├── AZ-500-Teaching-Punchlist.md
├── AZ-500-cert-study-resources.md
├── AZ-500-course-plan.md
├── GETTING-STARTED.md
├── LICENSE
├── README.md
├── az104-README.md
├── az500-objective-domain.md
├── azure-cli.azcli
├── azure-policy.json
├── azure-powershell.ps1
├── code-samples/
│   ├── README.md
│   ├── bicep/
│   │   └── deployment.bicep
│   ├── cli/
│   │   └── azure-cli.azcli
│   ├── json/
│   │   ├── azure-policy.json
│   │   ├── custom-rbac-role.json
│   │   └── deployment.json
│   ├── kusto/
│   │   └── kusto.kql
│   └── powershell/
│       └── azure-powershell.ps1
├── custom-rbac-role.json
├── deployment.bicep
├── deployment.json
├── docs/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   └── SECURITY.md
├── images/
│   └── visio/
│       ├── AZ-500.vsdx
│       ├── az300-topology.vsdx
│       ├── azure-classroom-reference-diagram.vsdx
│       └── drawings.vsdx
├── kusto.kql
├── labs/
│   ├── LAB-SETUP.md
│   └── README.md
├── scripts/
│   ├── blueprints/
│   │   ├── basic-networking-blueprint/
│   │   │   ├── Artifacts/
│   │   │   │   ├── 7ddd6a5f-4815-4526-aa69-40bbffd263d3.json
│   │   │   │   ├── 7ddd6a5f-4815-4526-aa69-40bbffd26cc7.json
│   │   │   │   ├── nsg-template.json
│   │   │   │   └── vnet-and-subnet-template.json
│   │   │   └── Blueprint.json
│   │   ├── blueprints-references.txt
│   │   ├── blueprints.ps1
│   │   ├── sample-blueprint/
│   │   │   ├── artifacts/
│   │   │   │   ├── policyStorageTags.json
│   │   │   │   ├── policyTags.json
│   │   │   │   ├── roleContributor.json
│   │   │   │   ├── roleOwner.json
│   │   │   │   ├── templateStorage.json
│   │   │   │   └── templateStorageParams.json
│   │   │   ├── blueprint.json
│   │   │   └── blueprintAssignment.json
│   │   ├── warner-azure-blueprints.pptx
│   │   └── warner-azure-blueprints.ps1
│   ├── key-vault.azcli
│   ├── powershell/
│   │   ├── Dockerfile.txt
│   │   ├── Update-AutomationAzureModulesForAccount.ps1
│   │   ├── aad-pim-powershell.ps1
│   │   ├── app-gateway-e2e-tls.ps1
│   │   ├── application-security-groups.ps1
│   │   ├── azcopy.txt
│   │   ├── azure-key-vault-powershell.ps1
│   │   ├── azuresql-database-tde.ps1
│   │   ├── backup-key-vault.ps1
│   │   ├── convert-vhd.ps1
│   │   ├── cosmos-container-rbac.ps1
│   │   ├── create-aks-cluster.ps1
│   │   ├── create-azure-bastion.ps1
│   │   ├── create-key-vault.ps1
│   │   ├── custom-azure-rbac-role.ps1
│   │   ├── custom-rbac-role.ps1
│   │   ├── customscriptextension.ps1
│   │   ├── enable-azuresql-database-tde.ps1
│   │   ├── enforce-tag-value-rg.json
│   │   ├── installWebServer.ps1
│   │   ├── linux-vm-ssh-keys.ps1
│   │   ├── managed-storage-account.ps1
│   │   ├── networking.ps1
│   │   ├── password-reset.ps1
│   │   ├── policy-enforce-tag-value-rg.json
│   │   ├── powershell-key-vault.ps1
│   │   ├── storage-account.ps1
│   │   ├── taxonomic-tags.ps1
│   │   ├── validate-deploy-arm-template.ps1
│   │   ├── vm-key-vault.parameters.json
│   │   ├── vm-key-vault.template.json
│   │   ├── vnet-peering.ps1
│   │   └── webjob.ps1
│   └── sql/
│       ├── azure-sql-database-firewall-rules.sql
│       ├── azure-sql-row-level-security.sql
│       └── azuresql-database-firewall.sql
├── study-resources/
│   ├── AZ-500-Teaching-Punchlist.md
│   ├── AZ-500-cert-study-resources.md
│   ├── AZ-500-course-plan.md
│   └── README.md
├── templates/
│   ├── 101-aci-vnet/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-aks/
│   │   ├── .ci_skip
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-application-gateway-v2-autoscale-create/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-functions-managed-identity/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-storage-account-create/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-vm-simple-windows/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 101-webapp-basic-windows/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 201-2-vms-loadbalancer-lbrules/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── 201-sql-auditing-server-policy-to-blob-storage/
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   └── metadata.json
│   ├── AZ-300/
│   │   ├── AKS/
│   │   │   ├── AKS.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── AZ-300.sln
│   │   ├── App-Gateway/
│   │   │   ├── App-Gateway.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── AppService+Container/
│   │   │   ├── AppService+Container.deployproj
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── Deploy-AzureResourceGroup.ps1
│   │   ├── Deployment.targets
│   │   ├── KeyVault/
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── KeyVault.deployproj
│   │   │   ├── README.md
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── README.md
│   │   ├── VM Copy Loops.deployproj
│   │   ├── WebApp+SQL/
│   │   │   ├── Deploy-AzureResourceGroup.ps1
│   │   │   ├── Deployment.targets
│   │   │   ├── README.md
│   │   │   ├── WebApp+SQL.deployproj
│   │   │   ├── azuredeploy.json
│   │   │   └── azuredeploy.parameters.json
│   │   ├── azuredeploy.json
│   │   └── azuredeploy.parameters.json
│   ├── Basic-ACR-AKS-Blueprint/
│   │   ├── Artifacts/
│   │   │   ├── 16985fcd-e84e-4310-8306-45c89bccc429.json
│   │   │   ├── 31e3b372-1efb-42e8-ac45-d938d00212d6.json
│   │   │   ├── 397ca67f-80f5-4da5-9484-f71ce2f58030.json
│   │   │   ├── a369d0c9-ab75-42b2-8677-2adb34f2757c.json
│   │   │   ├── d8a78686-485d-4956-96a6-64f305a7f822.json
│   │   │   ├── d8c28060-2804-4421-bed1-f61a5f456183.json
│   │   │   └── f465a2a1-0e85-439b-a9ac-3dcf94e066cf.json
│   │   └── Blueprint.json
│   ├── active-directory-new-domain-ha-2-dc/
│   │   ├── .gitignore
│   │   ├── DSC/
│   │   │   ├── ConfigureADBDC.ps1
│   │   │   ├── CreateADPDC.ps1
│   │   │   └── PrepareADBDC.ps1
│   │   ├── README.md
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   ├── metadata.json
│   │   └── nestedtemplates/
│   │       ├── configureADBDC.json
│   │       ├── nic.json
│   │       ├── vnet-with-dns-server.json
│   │       └── vnet.json
│   ├── customscriptext.json
│   ├── customscriptext.param.json
│   ├── docker-containers.azcli
│   ├── generative-ai/
│   │   ├── azurecli.azcli
│   │   ├── azuredeploy.json
│   │   ├── kusto.kql
│   │   ├── main.bicep
│   │   └── powershell.ps1
│   ├── virtual-network/
│   │   ├── azuredeploy.json
│   │   ├── azuredeploy.parameters.json
│   │   ├── hub-vnet.bicep
│   │   └── vnets-deploy.bicep
│   └── ~arm-templates/
│       ├── S2S-VPN/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── app service-cosmos/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── application-gateway/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── azure-sql-aworks/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── bastion/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── container-registry/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── event-hub/
│       │   ├── eventhub.json
│       │   └── eventhub.parameters.json
│       ├── firewall/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── iot-hub/
│       │   ├── iothub.json
│       │   └── iothub.parameters.json
│       ├── linux-vm-password/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── linux-vm-ssh/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── load-balancer/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── multiple-vms/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── new-AD-forest/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── private-dns-zone/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       ├── traffic-manager/
│       │   ├── trafficmanager.json
│       │   └── trafficmanager.parameters.json
│       ├── virtual-network/
│       │   ├── azuredeploy.json
│       │   └── azuredeploy.parameters.json
│       └── windows-vm-cse/
│           ├── azuredeploy.json
│           └── azuredeploy.parameters.json
└── warner-AZ500.pptx
Condensed preview — 235 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (658K chars).
[
  {
    "path": ".github/workflows/check-readme-links.yml",
    "chars": 1077,
    "preview": "name: Check Markdown Links\n\non:\n  push:\n    branches:\n      - main\n  workflow_dispatch:\n\njobs:\n  check-links:\n    runs-o"
  },
  {
    "path": ".gitignore",
    "chars": 97,
    "preview": "# gcc coverage testing tool files\n\n*.gcno\n*.gcda\n*.gcov\n~$warner-AZ500.pptx\naz500.code-workspace\n"
  },
  {
    "path": "AZ-500-Teaching-Punchlist.md",
    "chars": 1503,
    "preview": "# AZ-500 Teaching Punchlist\n\n## Segment 1: Identity and Access (10 AM - 11 AM)\n- **Manage Entra Identities**\n  - Users, "
  },
  {
    "path": "AZ-500-cert-study-resources.md",
    "chars": 3171,
    "preview": "# Exam AZ-500 Certification Study Resources\n\nLast updated: March 2024\n\n## Official Microsoft Learning Resources\n\n* [AZ-5"
  },
  {
    "path": "AZ-500-course-plan.md",
    "chars": 7266,
    "preview": "# AZ-500 Crash Course: Key Discussion and Demo Topics\n\n## Course Structure\n- **Duration:** 5 hours (4 segments of ~1 hou"
  },
  {
    "path": "GETTING-STARTED.md",
    "chars": 3425,
    "preview": "# Getting Started with AZ-500 Course Materials\n\nWelcome to the AZ-500 Microsoft Azure Security Technologies Crash Course"
  },
  {
    "path": "LICENSE",
    "chars": 1068,
    "preview": "MIT License\n\nCopyright (c) 2021, Tim Warner\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "README.md",
    "chars": 18097,
    "preview": "# Exam AZ-500: Microsoft Azure Security Technologies Crash Course\n\n<img src=\"images/az500-cover-slide-final.png\" alt=\"AZ"
  },
  {
    "path": "az104-README.md",
    "chars": 5572,
    "preview": "# Tim Warner's AZ-104 Study Resources\n\n<img src=\"az104-cover-slide.png\" alt=\"AZ-104 Course Cover\" width=\"800\"/>\n\nWelcome"
  },
  {
    "path": "az500-objective-domain.md",
    "chars": 8197,
    "preview": "# Exam AZ-500: Microsoft Azure Security Technologies\n\n![Microsoft Azure Security](images/az500-cover-slide-final.png)\n\n#"
  },
  {
    "path": "azure-cli.azcli",
    "chars": 4357,
    "preview": "#!/bin/bash\n# AZ-500 Security Implementation Example\n# Purpose: Demonstrates security hardening and auditing across mult"
  },
  {
    "path": "azure-policy.json",
    "chars": 3894,
    "preview": "{\n    \"mode\": \"Indexed\",\n    \"policyRule\": {\n        \"if\": {\n            \"allOf\": [\n                {\n                  "
  },
  {
    "path": "azure-powershell.ps1",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "code-samples/README.md",
    "chars": 1511,
    "preview": "# AZ-500 Code Samples\n\nThis directory contains code samples, templates, and scripts that demonstrate Azure security conc"
  },
  {
    "path": "code-samples/bicep/deployment.bicep",
    "chars": 6251,
    "preview": "// AZ-500 Security Implementation Example\n// Purpose: Demonstrates secure infrastructure deployment with multiple securi"
  },
  {
    "path": "code-samples/cli/azure-cli.azcli",
    "chars": 4357,
    "preview": "#!/bin/bash\n# AZ-500 Security Implementation Example\n# Purpose: Demonstrates security hardening and auditing across mult"
  },
  {
    "path": "code-samples/json/azure-policy.json",
    "chars": 3894,
    "preview": "{\n    \"mode\": \"Indexed\",\n    \"policyRule\": {\n        \"if\": {\n            \"allOf\": [\n                {\n                  "
  },
  {
    "path": "code-samples/json/custom-rbac-role.json",
    "chars": 1817,
    "preview": "{\n    \"Name\": \"Security Operations Analyst Custom Role\",\n    \"IsCustom\": true,\n    \"Description\": \"Allows security opera"
  },
  {
    "path": "code-samples/json/deployment.json",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "code-samples/kusto/kusto.kql",
    "chars": 3090,
    "preview": "// Security Investigation Query - Correlated Security Events Analysis\n// Purpose: Detect potential lateral movement atte"
  },
  {
    "path": "code-samples/powershell/azure-powershell.ps1",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "custom-rbac-role.json",
    "chars": 1817,
    "preview": "{\n    \"Name\": \"Security Operations Analyst Custom Role\",\n    \"IsCustom\": true,\n    \"Description\": \"Allows security opera"
  },
  {
    "path": "deployment.bicep",
    "chars": 6251,
    "preview": "// AZ-500 Security Implementation Example\n// Purpose: Demonstrates secure infrastructure deployment with multiple securi"
  },
  {
    "path": "deployment.json",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/CODE_OF_CONDUCT.md",
    "chars": 3420,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "docs/CONTRIBUTING.md",
    "chars": 1936,
    "preview": "# Contributing\n\nWhen contributing to this repository, please first discuss the change you wish to make via issue, email,"
  },
  {
    "path": "docs/SECURITY.md",
    "chars": 860,
    "preview": "# Security Policy\n\n## Reporting a Vulnerability\n\nIf there are any vulnerability in **Exam AZ-500: Microsoft Azure Securi"
  },
  {
    "path": "kusto.kql",
    "chars": 3090,
    "preview": "// Security Investigation Query - Correlated Security Events Analysis\n// Purpose: Detect potential lateral movement atte"
  },
  {
    "path": "labs/LAB-SETUP.md",
    "chars": 3863,
    "preview": "# AZ-500 Lab Environment Setup Guide\n\nThis guide will help you prepare your environment for the hands-on labs in this AZ"
  },
  {
    "path": "labs/README.md",
    "chars": 1967,
    "preview": "# AZ-500 Hands-on Labs\n\nThis directory contains hands-on labs and exercises to help you practice Azure security concepts"
  },
  {
    "path": "scripts/blueprints/basic-networking-blueprint/Artifacts/7ddd6a5f-4815-4526-aa69-40bbffd263d3.json",
    "chars": 367,
    "preview": "{\n  \"kind\": \"roleAssignment\",\n  \"properties\": {\n    \"displayName\": \"Melissa Gaughan (melissa@timw.info) : Contributor\",\n"
  },
  {
    "path": "scripts/blueprints/basic-networking-blueprint/Artifacts/7ddd6a5f-4815-4526-aa69-40bbffd26cc7.json",
    "chars": 377,
    "preview": "{\n  \"kind\": \"policyAssignment\",\n  \"properties\": {\n    \"displayName\": \"Inherit a tag from the resource group if missing\","
  },
  {
    "path": "scripts/blueprints/basic-networking-blueprint/Artifacts/nsg-template.json",
    "chars": 2875,
    "preview": "{\n  \"kind\": \"template\",\n  \"properties\": {\n    \"displayName\": \"NSG for new VNET\",\n    \"description\": \"\",\n    \"dependsOn\":"
  },
  {
    "path": "scripts/blueprints/basic-networking-blueprint/Artifacts/vnet-and-subnet-template.json",
    "chars": 1767,
    "preview": "{\n  \"kind\": \"template\",\n  \"properties\": {\n    \"displayName\": \"VNET and one subnet\",\n    \"dependsOn\": [],\n    \"template\":"
  },
  {
    "path": "scripts/blueprints/basic-networking-blueprint/Blueprint.json",
    "chars": 1102,
    "preview": "{\n  \"properties\": {\n    \"displayName\": \"Basic Networking (VNET)\",\n    \"description\": \"Configures a virtual network with "
  },
  {
    "path": "scripts/blueprints/blueprints-references.txt",
    "chars": 1313,
    "preview": "##### Azure Blueprints Learning Resources #####\n\nAzure Blueprints documentation\nhttps://docs.microsoft.com/en-us/azure/g"
  },
  {
    "path": "scripts/blueprints/blueprints.ps1",
    "chars": 1942,
    "preview": "<# Manage Azure Blueprints as code\n   Tim Warner (techtrainertim.com)\n   01-September-2020\n#>\n\n# Authenticate\nConnect-Az"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/policyStorageTags.json",
    "chars": 568,
    "preview": "{\n    \"kind\": \"policyAssignment\",\n    \"properties\": {\n        \"displayName\": \"Apply storage tag to resource group\",\n    "
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/policyTags.json",
    "chars": 555,
    "preview": "{\n    \"kind\": \"policyAssignment\",\n    \"properties\": {\n        \"displayName\": \"Apply tag and its default value to resourc"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/roleContributor.json",
    "chars": 233,
    "preview": "{\n    \"kind\": \"roleAssignment\",\n    \"properties\": {\n        \"roleDefinitionId\": \"/providers/Microsoft.Authorization/role"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/roleOwner.json",
    "chars": 265,
    "preview": "{\n    \"kind\": \"roleAssignment\",\n    \"properties\": {\n        \"resourceGroup\": \"storageRG\",\n        \"roleDefinitionId\": \"/"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/templateStorage.json",
    "chars": 1543,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "scripts/blueprints/sample-blueprint/artifacts/templateStorageParams.json",
    "chars": 440,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/blueprint.json",
    "chars": 2032,
    "preview": "{\n    \"properties\": {\n        \"description\": \"This blueprint sets tag policy and role assignment on the subscription, cr"
  },
  {
    "path": "scripts/blueprints/sample-blueprint/blueprintAssignment.json",
    "chars": 1102,
    "preview": "{\n    \"properties\": {\n        \"blueprintId\": \"/providers/Microsoft.Management/managementGroups/{YourMG}/providers/Micros"
  },
  {
    "path": "scripts/blueprints/warner-azure-blueprints.ps1",
    "chars": 1468,
    "preview": "# Getting Started with Azure Blueprints\n# Tim Warner (techtrainertim.com)\n\n# Ref: https://timw.info/f88be\n\n# Authenticat"
  },
  {
    "path": "scripts/key-vault.azcli",
    "chars": 801,
    "preview": "# Manage Key Vault with CLI\n\n# Ref: timw.info/1fg\n\n# Preliminary info\naz login\n\naz configure\n\naz account set --name \"Mic"
  },
  {
    "path": "scripts/powershell/Dockerfile.txt",
    "chars": 2229,
    "preview": "# Dockerfile needs that name with no extension in root of build folder.\n\n# Sample Dockerfile\n\n# Indicates that the windo"
  },
  {
    "path": "scripts/powershell/Update-AutomationAzureModulesForAccount.ps1",
    "chars": 19850,
    "preview": "<#\nCopyright (c) Microsoft Corporation. All rights reserved.\nLicensed under the MIT License.\n#>\n\n<#\n.SYNOPSIS\nUpdate Azu"
  },
  {
    "path": "scripts/powershell/aad-pim-powershell.ps1",
    "chars": 742,
    "preview": "# install Azure PowerShell\nInstall-Module -Name Az -Verbose\n\n# install Azure AD module\nInstall-Module -Name AzureADPrevi"
  },
  {
    "path": "scripts/powershell/app-gateway-e2e-tls.ps1",
    "chars": 1614,
    "preview": "<# End-to-End TLS for Application Gateway\n\nRef: timw.info/ys2\n\nNote: This is only a partial procedure\n\n#>\n\n# Configure t"
  },
  {
    "path": "scripts/powershell/application-security-groups.ps1",
    "chars": 542,
    "preview": "# create the ASGs\n$webAsg = New-AzApplicationSecurityGroup -ResourceGroupName 'Load-Balancer' -Name webASG -Location 'ea"
  },
  {
    "path": "scripts/powershell/azcopy.txt",
    "chars": 1242,
    "preview": "# Use AzCopy\n\n# Ref: https://timw.info/d0a73\n\n# Sign in (you can also use SAS tokens and managed identities)\nazcopy logi"
  },
  {
    "path": "scripts/powershell/azure-key-vault-powershell.ps1",
    "chars": 793,
    "preview": "<# Work with Azure Key Vault and PowerShell\n\n   Ref: https://docs.microsoft.com/en-us/azure/key-vault/quick-create-power"
  },
  {
    "path": "scripts/powershell/azuresql-database-tde.ps1",
    "chars": 1748,
    "preview": "# Set variables\n$resourceGroup = ''\n$dbServerName = ''\n$dbName = ''\n$keyVaultName = ''\n$keyVaultKeyId = (Get-AzureKeyVau"
  },
  {
    "path": "scripts/powershell/backup-key-vault.ps1",
    "chars": 133,
    "preview": "Get-Command -Module Az.KeyVault\n\nBackup-AzKeyVaultSecret -VaultName 'MyKeyVault' -Name 'MySecret' -OutputFile 'C:\\Backup"
  },
  {
    "path": "scripts/powershell/convert-vhd.ps1",
    "chars": 285,
    "preview": "# Convert VHDX to VHD \nConvert-VHD -Path 'C:\\users\\public\\Documents\\Hyper-V\\Virtual hard disks\\win16template.vhdx' -Dest"
  },
  {
    "path": "scripts/powershell/cosmos-container-rbac.ps1",
    "chars": 1927,
    "preview": "# Ref: https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac\n\n# Install PowerShell Core\nInstall-Module -Nam"
  },
  {
    "path": "scripts/powershell/create-aks-cluster.ps1",
    "chars": 1333,
    "preview": "Ref 1: https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough\n\n# Create resource group\naz group create --name"
  },
  {
    "path": "scripts/powershell/create-azure-bastion.ps1",
    "chars": 662,
    "preview": "# ref: https://timw.info/5ei\n# ref2: https://timw.info/p1c\n\n# Create delegated subnet\n$subnetName = \"AzureBastionSubnet\""
  },
  {
    "path": "scripts/powershell/create-key-vault.ps1",
    "chars": 856,
    "preview": "Get-AzContext | Format-List\n\nNew-AzResourceGroup -Name 'cs' -Location EastUS\n\nNew-AzKeyVault -Name 'cs-vault' -ResourceG"
  },
  {
    "path": "scripts/powershell/custom-azure-rbac-role.ps1",
    "chars": 796,
    "preview": "# Ref: https://docs.microsoft.com/en-us/azure/role-based-access-control/tutorial-custom-role-powershell\n\nGet-AzProviderO"
  },
  {
    "path": "scripts/powershell/custom-rbac-role.ps1",
    "chars": 912,
    "preview": "# Ref: https://docs.microsoft.com/en-us/azure/role-based-access-control/tutorial-custom-role-powershell\n\n# ARM REST API "
  },
  {
    "path": "scripts/powershell/customscriptextension.ps1",
    "chars": 854,
    "preview": "$fileUri = @(\"https://xxxxxxx.blob.core.windows.net/buildServer1/1_Add_Tools.ps1\",\n\"https://xxxxxxx.blob.core.windows.ne"
  },
  {
    "path": "scripts/powershell/enable-azuresql-database-tde.ps1",
    "chars": 502,
    "preview": "EXECUTE sp_set_database_firewall_rule N'my_db_rule';\n,'168.0.0.0'\n,'168.0.0.0'\n\n-- Enable Azure connections.\nEXECUTE sp_"
  },
  {
    "path": "scripts/powershell/enforce-tag-value-rg.json",
    "chars": 1242,
    "preview": "{\n    \"properties\": {\n        \"displayName\": \"Enforce tag and its value on resource groups\",\n        \"description\": \"Enf"
  },
  {
    "path": "scripts/powershell/installWebServer.ps1",
    "chars": 63,
    "preview": "Install-WindowsFeature -name Web-Server -IncludeManagementTools"
  },
  {
    "path": "scripts/powershell/linux-vm-ssh-keys.ps1",
    "chars": 3163,
    "preview": "# Linux VM / SSH Keys\n\n# Generate SSH key pair\nssh-keygen -t rsa -b 2048\n\n# Display your public key\ncat ~/.ssh/id_rsa.pu"
  },
  {
    "path": "scripts/powershell/managed-storage-account.ps1",
    "chars": 2132,
    "preview": "#Prefix for resources\n$prefix = \"tlw704\"\n\n#Basic variables\n$location = \"eastus\"\n$id = Get-Random -Minimum 1000 -Maximum "
  },
  {
    "path": "scripts/powershell/networking.ps1",
    "chars": 5996,
    "preview": "# Azure Networking\n\n###### CREATE NEW MULTI-TIER VNET ######\n# Variables for common values\n$rgName='MyResourceGroup'\n$lo"
  },
  {
    "path": "scripts/powershell/password-reset.ps1",
    "chars": 110,
    "preview": "net user tim P@$$w0rd123!\n\nNew-Item -Name 'extension.txt' -Path 'C:\\' -ItemType File -Value 'It works.' -Force"
  },
  {
    "path": "scripts/powershell/policy-enforce-tag-value-rg.json",
    "chars": 1242,
    "preview": "{\n    \"properties\": {\n        \"displayName\": \"Enforce tag and its value on resource groups\",\n        \"description\": \"Enf"
  },
  {
    "path": "scripts/powershell/powershell-key-vault.ps1",
    "chars": 485,
    "preview": "# PowerShell Key Vault (Ref: https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-powershell)\n\n# Conver"
  },
  {
    "path": "scripts/powershell/storage-account.ps1",
    "chars": 1380,
    "preview": "# Azure Storage Accounts\n\n# List storage accounts\nGet-AzStorageAccount | Select StorageAccountName, Location\n\n# Retrieve"
  },
  {
    "path": "scripts/powershell/taxonomic-tags.ps1",
    "chars": 1830,
    "preview": "# Resource Groups and Taxonomic Tags\n\n# See existing tags on a resource group\n(Get-AzResourceGroup -Name 'oreilly').Tags"
  },
  {
    "path": "scripts/powershell/validate-deploy-arm-template.ps1",
    "chars": 451,
    "preview": "Set-Location -Path '~\\azure-admin-crash-course\\101-storage-account-create'\n\ncode .\\azuredeploy.json\ncode .\\azuredeploy.p"
  },
  {
    "path": "scripts/powershell/vm-key-vault.parameters.json",
    "chars": 531,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "scripts/powershell/vm-key-vault.template.json",
    "chars": 7035,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "scripts/powershell/vnet-peering.ps1",
    "chars": 1539,
    "preview": "<# VNet Peering with Azure PowerShell\nRef: http://rb.gy/b2fonv\n#>\n\n# create a resource group\nNew-AzResourceGroup -Resour"
  },
  {
    "path": "scripts/powershell/webjob.ps1",
    "chars": 53,
    "preview": "New-Item -Path D:\\ -Name webjob.txt -Value \"Hi there\""
  },
  {
    "path": "scripts/sql/azure-sql-database-firewall-rules.sql",
    "chars": 502,
    "preview": "EXECUTE sp_set_database_firewall_rule N'my_db_rule';\n,'168.0.0.0'\n,'168.0.0.0'\n\n-- Enable Azure connections.\nEXECUTE sp_"
  },
  {
    "path": "scripts/sql/azure-sql-row-level-security.sql",
    "chars": 53,
    "preview": "-- Row-level security\n-- Ref: https://timw.info/zwx\n\n"
  },
  {
    "path": "scripts/sql/azuresql-database-firewall.sql",
    "chars": 502,
    "preview": "EXECUTE sp_set_database_firewall_rule N'my_db_rule';\n,'168.0.0.0'\n,'168.0.0.0'\n\n-- Enable Azure connections.\nEXECUTE sp_"
  },
  {
    "path": "study-resources/AZ-500-Teaching-Punchlist.md",
    "chars": 1503,
    "preview": "# AZ-500 Teaching Punchlist\n\n## Segment 1: Identity and Access (10 AM - 11 AM)\n- **Manage Entra Identities**\n  - Users, "
  },
  {
    "path": "study-resources/AZ-500-cert-study-resources.md",
    "chars": 3171,
    "preview": "# Exam AZ-500 Certification Study Resources\n\nLast updated: March 2024\n\n## Official Microsoft Learning Resources\n\n* [AZ-5"
  },
  {
    "path": "study-resources/AZ-500-course-plan.md",
    "chars": 7266,
    "preview": "# AZ-500 Crash Course: Key Discussion and Demo Topics\n\n## Course Structure\n- **Duration:** 5 hours (4 segments of ~1 hou"
  },
  {
    "path": "study-resources/README.md",
    "chars": 924,
    "preview": "# AZ-500 Study Resources\n\nThis directory contains supplementary study materials for the AZ-500 Microsoft Azure Security "
  },
  {
    "path": "templates/101-aci-vnet/README.md",
    "chars": 740,
    "preview": "# Create an Azure container group with VNet\n\n<a href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2"
  },
  {
    "path": "templates/101-aci-vnet/azuredeploy.json",
    "chars": 5461,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/101-aci-vnet/azuredeploy.parameters.json",
    "chars": 216,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/101-aci-vnet/metadata.json",
    "chars": 384,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/101-aks/.ci_skip",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "templates/101-aks/README.md",
    "chars": 1227,
    "preview": "# Azure Container Service (AKS)\n\n<a href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.gith"
  },
  {
    "path": "templates/101-aks/azuredeploy.json",
    "chars": 4842,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/101-aks/azuredeploy.parameters.json",
    "chars": 492,
    "preview": "{\n\t\"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n\t\"contentVersion\": \"1"
  },
  {
    "path": "templates/101-aks/metadata.json",
    "chars": 386,
    "preview": "{\n    \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n    \"type\": \"QuickStart\",\n    \"itemDispla"
  },
  {
    "path": "templates/101-application-gateway-v2-autoscale-create/README.md",
    "chars": 751,
    "preview": "# Create Application Gateway v2\n\n<a href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.gith"
  },
  {
    "path": "templates/101-application-gateway-v2-autoscale-create/azuredeploy.json",
    "chars": 7601,
    "preview": "{\n   \"$schema\":\"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n   \"contentVersion\":\"1"
  },
  {
    "path": "templates/101-application-gateway-v2-autoscale-create/azuredeploy.parameters.json",
    "chars": 245,
    "preview": "{\n  \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": \""
  },
  {
    "path": "templates/101-application-gateway-v2-autoscale-create/metadata.json",
    "chars": 450,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"itemDisplayName\": \"Create an Application"
  },
  {
    "path": "templates/101-functions-managed-identity/README.md",
    "chars": 2327,
    "preview": "# Provision a function app on a consumption plan with managed identity enabled\n\n[![Deploy to Azure](https://raw.githubus"
  },
  {
    "path": "templates/101-functions-managed-identity/azuredeploy.json",
    "chars": 12283,
    "preview": "{\n    \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n    \"contentVersion\":"
  },
  {
    "path": "templates/101-functions-managed-identity/azuredeploy.parameters.json",
    "chars": 235,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/101-functions-managed-identity/metadata.json",
    "chars": 466,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n    \"itemDisplayNam"
  },
  {
    "path": "templates/101-storage-account-create/README.md",
    "chars": 1318,
    "preview": "# Create a Standard Storage Account\n\nCreate a Standard Storage Account  - <a href=\"https://portal.azure.com/#create/Micr"
  },
  {
    "path": "templates/101-storage-account-create/azuredeploy.json",
    "chars": 1207,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/101-storage-account-create/azuredeploy.parameters.json",
    "chars": 154,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/101-storage-account-create/metadata.json",
    "chars": 347,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/101-vm-simple-windows/README.md",
    "chars": 1535,
    "preview": "# Very simple deployment of a Windows VM\n\n<a href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2"
  },
  {
    "path": "templates/101-vm-simple-windows/azuredeploy.json",
    "chars": 5698,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/101-vm-simple-windows/azuredeploy.parameters.json",
    "chars": 329,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/101-vm-simple-windows/metadata.json",
    "chars": 627,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/101-webapp-basic-windows/README.md",
    "chars": 804,
    "preview": "# Deploy a app service plan and a basic Windows web app\n\n<a href=\"https://portal.azure.com/#create/Microsoft.Template/ur"
  },
  {
    "path": "templates/101-webapp-basic-windows/azuredeploy.json",
    "chars": 1667,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/101-webapp-basic-windows/azuredeploy.parameters.json",
    "chars": 207,
    "preview": "{\n\t\"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n\t\"contentVersion\": \"1"
  },
  {
    "path": "templates/101-webapp-basic-windows/metadata.json",
    "chars": 425,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/201-2-vms-loadbalancer-lbrules/README.md",
    "chars": 989,
    "preview": "# Create 2 Virtual Machines under a Load balancer and configures Load Balancing rules for the VMs\n\n<a href=\"https://port"
  },
  {
    "path": "templates/201-2-vms-loadbalancer-lbrules/azuredeploy.json",
    "chars": 10090,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json\",\n  \"contentVersion\": \"1."
  },
  {
    "path": "templates/201-2-vms-loadbalancer-lbrules/azuredeploy.parameters.json",
    "chars": 390,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/201-2-vms-loadbalancer-lbrules/metadata.json",
    "chars": 681,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/201-sql-auditing-server-policy-to-blob-storage/README.md",
    "chars": 1113,
    "preview": "# Deploy an Azure SQL Server with Auditing enabled to write audit logs to Azure blob storage account\n\n<a href=\"https://p"
  },
  {
    "path": "templates/201-sql-auditing-server-policy-to-blob-storage/azuredeploy.json",
    "chars": 2846,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/201-sql-auditing-server-policy-to-blob-storage/azuredeploy.parameters.json",
    "chars": 294,
    "preview": "{\n  \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": \""
  },
  {
    "path": "templates/201-sql-auditing-server-policy-to-blob-storage/metadata.json",
    "chars": 479,
    "preview": "{\n\t\"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n\t\"type\": \"QuickStart\",\n\t\"itemDisplayName\": \""
  },
  {
    "path": "templates/AZ-300/AKS/AKS.deployproj",
    "chars": 1573,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/AKS/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/AKS/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/AKS/README.md",
    "chars": 1898,
    "preview": "# Azure Container Service (AKS)\n\n<IMG SRC=\"https://azurequickstartsservice.blob.core.windows.net/badges/101-aks/PublicLa"
  },
  {
    "path": "templates/AZ-300/AKS/azuredeploy.json",
    "chars": 4442,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/AZ-300/AKS/azuredeploy.parameters.json",
    "chars": 306,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/AZ-300/AZ-300.sln",
    "chars": 4000,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.2923"
  },
  {
    "path": "templates/AZ-300/App-Gateway/App-Gateway.deployproj",
    "chars": 1573,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/App-Gateway/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/App-Gateway/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/App-Gateway/README.md",
    "chars": 1653,
    "preview": "# Create an Application Gateway v2 with a Web Application Firewall (WAF) v2\n\n<IMG SRC=\"https://azurequickstartsservice.b"
  },
  {
    "path": "templates/AZ-300/App-Gateway/azuredeploy.json",
    "chars": 8294,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/AZ-300/App-Gateway/azuredeploy.parameters.json",
    "chars": 154,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/AZ-300/AppService+Container/AppService+Container.deployproj",
    "chars": 1573,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/AppService+Container/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/AppService+Container/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/AppService+Container/README.md",
    "chars": 1939,
    "preview": "# Deploy Sonarqube on a Linux web app with MySQL\n\n<IMG SRC=\"https://azurequickstartsservice.blob.core.windows.net/badges"
  },
  {
    "path": "templates/AZ-300/AppService+Container/azuredeploy.json",
    "chars": 8635,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json\",\n    \"contentVersion\":"
  },
  {
    "path": "templates/AZ-300/AppService+Container/azuredeploy.parameters.json",
    "chars": 253,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/AZ-300/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/KeyVault/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/KeyVault/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/KeyVault/KeyVault.deployproj",
    "chars": 1573,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/KeyVault/README.md",
    "chars": 3329,
    "preview": "# Create an Azure Key Vault and a list of secrets\n\n<IMG SRC=\"https://azurequickstartsservice.blob.core.windows.net/badge"
  },
  {
    "path": "templates/AZ-300/KeyVault/azuredeploy.json",
    "chars": 4958,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/AZ-300/KeyVault/azuredeploy.parameters.json",
    "chars": 247,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/AZ-300/README.md",
    "chars": 2042,
    "preview": "# Multi VM Template with Managed Disk \n\n<IMG SRC=\"https://azurequickstartsservice.blob.core.windows.net/badges/201-vm-co"
  },
  {
    "path": "templates/AZ-300/VM Copy Loops.deployproj",
    "chars": 1620,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/Deploy-AzureResourceGroup.ps1",
    "chars": 6929,
    "preview": "#Requires -Version 3.0\n\nParam(\n    [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,\n    [string] $ResourceG"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/Deployment.targets",
    "chars": 5694,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/README.md",
    "chars": 2285,
    "preview": "# Provision a web app with a SQL Database\n\n<IMG SRC=\"https://azurequickstartsservice.blob.core.windows.net/badges/201-we"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/WebApp+SQL.deployproj",
    "chars": 1573,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/azuredeploy.json",
    "chars": 5450,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/AZ-300/WebApp+SQL/azuredeploy.parameters.json",
    "chars": 256,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/AZ-300/azuredeploy.json",
    "chars": 10173,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/AZ-300/azuredeploy.parameters.json",
    "chars": 154,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/16985fcd-e84e-4310-8306-45c89bccc429.json",
    "chars": 394,
    "preview": "{\n  \"kind\": \"roleAssignment\",\n  \"properties\": {\n    \"displayName\": \"[User group or application name] : Contributor\",\n   "
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/31e3b372-1efb-42e8-ac45-d938d00212d6.json",
    "chars": 386,
    "preview": "{\n  \"kind\": \"roleAssignment\",\n  \"properties\": {\n    \"displayName\": \"[User group or application name] : AcrPull\",\n    \"de"
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/397ca67f-80f5-4da5-9484-f71ce2f58030.json",
    "chars": 390,
    "preview": "{\n  \"kind\": \"roleAssignment\",\n  \"properties\": {\n    \"displayName\": \"[User group or application name] : AcrDelete\",\n    \""
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/a369d0c9-ab75-42b2-8677-2adb34f2757c.json",
    "chars": 806,
    "preview": "{\n  \"kind\": \"policyAssignment\",\n  \"properties\": {\n    \"displayName\": \"Kubernetes cluster pod security baseline standards"
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/d8a78686-485d-4956-96a6-64f305a7f822.json",
    "chars": 4015,
    "preview": "{\n  \"kind\": \"template\",\n  \"properties\": {\n    \"displayName\": \"aks.json\",\n    \"description\": \"\",\n    \"dependsOn\": [],\n   "
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/d8c28060-2804-4421-bed1-f61a5f456183.json",
    "chars": 386,
    "preview": "{\n  \"kind\": \"roleAssignment\",\n  \"properties\": {\n    \"displayName\": \"[User group or application name] : AcrPush\",\n    \"de"
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Artifacts/f465a2a1-0e85-439b-a9ac-3dcf94e066cf.json",
    "chars": 2704,
    "preview": "{\n  \"kind\": \"template\",\n  \"properties\": {\n    \"displayName\": \"acr.json\",\n    \"description\": \"\",\n    \"dependsOn\": [],\n   "
  },
  {
    "path": "templates/Basic-ACR-AKS-Blueprint/Blueprint.json",
    "chars": 5826,
    "preview": "{\n  \"properties\": {\n    \"targetScope\": \"subscription\",\n    \"parameters\": {\n      \"aks.json_aksClusterName\": {\n        \"t"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/.gitignore",
    "chars": 33,
    "preview": "azuredeploy.parameters.local.json"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/DSC/ConfigureADBDC.ps1",
    "chars": 2087,
    "preview": "configuration ConfigureADBDC\n{\n   param\n    (\n        [Parameter(Mandatory)]\n        [String]$DomainName,\n\n        [Par"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/DSC/CreateADPDC.ps1",
    "chars": 3005,
    "preview": "configuration CreateADPDC\n{\n   param\n   (\n        [Parameter(Mandatory)]\n        [String]$DomainName,\n\n        [Paramet"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/DSC/PrepareADBDC.ps1",
    "chars": 1523,
    "preview": "configuration PrepareADBDC\n{\n   param\n    (\n        [Parameter(Mandatory)]\n        [String]$DNSServer,\n\n        [Int]$R"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/README.md",
    "chars": 1512,
    "preview": "# Create 2 new Windows VMs, create a new AD Forest, Domain and 2 DCs in an availability set\n\nThis template will deploy 2"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/azuredeploy.json",
    "chars": 26386,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/azuredeploy.parameters.json",
    "chars": 449,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/metadata.json",
    "chars": 417,
    "preview": "{\n  \"$schema\": \"https://aka.ms/azure-quickstart-templates-metadata-schema#\",\n  \"type\": \"QuickStart\",\n  \"itemDisplayName\""
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/nestedtemplates/configureADBDC.json",
    "chars": 1644,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/nestedtemplates/nic.json",
    "chars": 1137,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/nestedtemplates/vnet-with-dns-server.json",
    "chars": 1897,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/active-directory-new-domain-ha-2-dc/nestedtemplates/vnet.json",
    "chars": 1635,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/customscriptext.json",
    "chars": 9650,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/customscriptext.param.json",
    "chars": 625,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/docker-containers.azcli",
    "chars": 1091,
    "preview": "# ACR Trust\n\n# Create a container registry\naz acr create --resource-group az500-rg --name twaz500acr --sku Standard\n\n# S"
  },
  {
    "path": "templates/generative-ai/azurecli.azcli",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "templates/generative-ai/azuredeploy.json",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "templates/generative-ai/kusto.kql",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "templates/generative-ai/main.bicep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "templates/generative-ai/powershell.ps1",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "templates/virtual-network/azuredeploy.json",
    "chars": 6243,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/virtual-network/azuredeploy.parameters.json",
    "chars": 1193,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/virtual-network/hub-vnet.bicep",
    "chars": 2635,
    "preview": "@description('VNet name')\nparam vnetName string = 'spoke-vnet'\n\n@description('VNet address prefix')\nparam vnetAddressPre"
  },
  {
    "path": "templates/virtual-network/vnets-deploy.bicep",
    "chars": 465,
    "preview": "@allowed([\n  'hub'\n  'spoke1'\n  'spoke2'\n])\nparam vNetType string\n\nmodule hub './hub-vnet.bicep' = if (vNetType == 'hub'"
  },
  {
    "path": "templates/~arm-templates/S2S-VPN/azuredeploy.json",
    "chars": 5264,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n  \"contentVersion\": \"1"
  },
  {
    "path": "templates/~arm-templates/S2S-VPN/azuredeploy.parameters.json",
    "chars": 725,
    "preview": "{\n  \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\",\n  \"contentVersion\": "
  },
  {
    "path": "templates/~arm-templates/app service-cosmos/azuredeploy.json",
    "chars": 6211,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/~arm-templates/app service-cosmos/azuredeploy.parameters.json",
    "chars": 306,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/~arm-templates/application-gateway/azuredeploy.json",
    "chars": 14882,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  },
  {
    "path": "templates/~arm-templates/application-gateway/azuredeploy.parameters.json",
    "chars": 972,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#\",\n    \"contentVersio"
  },
  {
    "path": "templates/~arm-templates/azure-sql-aworks/azuredeploy.json",
    "chars": 5385,
    "preview": "{\n    \"$schema\": \"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#\",\n    \"contentVersion\""
  }
]

// ... and 35 more files (download for full content)

About this extraction

This page contains the full source code of the timothywarner/az500 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 235 files (11.4 MB), approximately 144.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!