Skip to main content

98 posts tagged with "PowerShell"

View All Tags

· 8 min read
Hasan Gural

Welcome back, Friend!

In Part 1, we introduced GitHub Copilot Agent Skills, what they are, why they are useful for Azure operations, and what problem we are trying to solve with the PIM Advisor. We also set up the project structure and walked through the two core components: the rolesMapping.psd1 data file that defines which subscriptions, roles, and principals are permitted, and the activateAzResourcePimRole.ps1 script that handles the actual PIM activation through the Azure Resource PIM API.

In this part, we will complete the setup by writing the SKILL.md definition that makes everything available to Copilot in agent mode, understand how Copilot resolves natural language to script parameters, and test the full activation flow from a Copilot chat prompt. Think about this as the workflow definition that is going to respect the logic we implemented in the script and the mapping file, but from a natural language interface.

SKILL

· 12 min read
Hasan Gural

Hello Friends,

In this two-part series, I want to share a practical use case for GitHub Copilot Agent Skills, and it is something I have been exploring recently and find genuinely useful for day-to-day Azure operations. The idea is simple and following: instead of navigating the Azure portal to raise a Privileged Identity Management (PIM) request to cover your day to day operation for overarching tasks, you just ask Copilot in plain language, and it takes care of the rest.

Before getting into the implementation, let me quickly explain what Copilot Agent Skills are and why they are worth your attention.

· 10 min read
Hasan Gural

Hello Friends,

Welcome back to the Part 4. In the first three parts of this series, we built a complete pipeline: Part 1 explained the security problem and why tenant visibility matters, Part 2 showed the PowerShell technique for resolving storage FQDNs to tenant IDs using the WWW-Authenticate header, and Part 3 connected Azure Firewall logs through KQL queries to feed that script automatically.

The pipeline we have so far produces a report with an FQDN, a tenant ID, and an IsOwnTenant flag. That is useful, but it leaves two practical gaps. First, tenant IDs are GUIDs: machine-readable, but not something a security team can act on. When a report tells you that eight storage accounts belong to an unknown tenant, you want a name, not a GUID. Second, the report is a manual one-time snapshot. In practice, you want something that flags new unknown tenants as they appear in your firewall traffic without anyone having to remember to run a script.

· 8 min read
Hasan Gural

Hello Friends, Welcome back to the Part 3. In Part 1, We covered the security concern behind broad outbound firewall rules and explained why tenant visibility matters. In Part 2, We have walked through the PowerShell script that takes a list of storage FQDNs and resolves each one to a tenant ID using the WWW-Authenticate header trick.

The script is ready. The missing piece is the list itself. In a real environment you are not going to type out FQDNs with your hands; you are going to pull them from Azure Firewall logs. That is what this part covers. I will walk through both Azure Firewall log formats, show the KQL queries I use to extract storage FQDNs from each, and then connect the output directly to the script so the full pipeline runs end to end.

· 10 min read
Hasan Gural

Hello Friends,

Welcome back to the Part 2 of this series. In Part 1, we walked through the security concern behind broad outbound firewall rules that allow access to any Azure Storage account, and explained why FQDNs visible in Azure Firewall logs do not tell you anything about tenant ownership. I also outlined the plan: extract storage FQDNs from your firewall logs, generate controlled traffic to each one, and use the HTTP response to extract a tenant ID that can be mapped to an owner.

In this part, we will go deeper into the actual mechanics. I will show you exactly how the tenant ID discovery technique works under the hood, walk through the PowerShell scripts that I have built, and then we will move into Azure Firewall logs with some KQL queries that will help you get from raw log data to a clean list of FQDNs ready for analysis.

· 6 min read
Hasan Gural

Hello Folks,

In this article, we will walk through a very serious problem that I have seen in multiple Azure environments in my customers: an Azure environment where outbound firewall rules allowed access to any Azure Storage account on the internet.

GlobalBootCamp2025

On the surface, the rule looked safe enough: outbound access was limited to Azure Storage endpoints. In reality, this meant that any storage account in any tenant was reachable, as long as it lived behind a standard *.blob.core.windows.net or *.dfs.core.windows.net style FQDN. From a data exfiltration perspective, this is a big red flag. Any workload that can send HTTPS traffic to arbitrary storage accounts can quietly move data out of your tenant, and that traffic is almost indistinguishable from normal storage operations.

· 9 min read
Hasan Gural

Hello Friends,

Welcome to the final part of this series. In Part 1 we covered why Premium SSD creates the oversizing problem in the first place, how the pricing model for Premium SSD v2 actually works, and how to identify which disks in your environment are worth migrating. In Part 2 we went through the snapshot-based migration itself, built a PowerShell script that handles the full workflow with a WhatIf mode, and looked at a Bicep pattern for new deployments with zone alignment done correctly from the start.

Now that the disks are running on Premium SSD v2, there is one more thing I want to address, because this is where I see most teams leave money on the table. When you create a Premium SSD v2 disk, you have to decide on IOPS and throughput values at that moment. Most people base that decision on what the old Premium SSD tier was delivering, which was itself a number that came from disk size, not from any measurement of what the workload actually needed. So you migrate, and you carry the same inflated numbers across to the new SKU.

In this part we will look at how to use real utilization data to right-size those values, how to write KQL queries that show you what the disk is actually doing, and how to set up Azure Monitor alerts that surface problems before they affect anything.

· 7 min read
Hasan Gural

Hello Friends,

Welcome back to Part 2. In Part 1 we covered why Premium SSD creates the oversizing problem, how Premium SSD v2 changes the pricing model, the constraints that shape migration planning, and a PowerShell script to identify candidate disks across a subscription. If you have not read that yet, start there because the zone requirement in particular will come up again here.

In this part we go through the actual migration. The good news is that the process is more direct than most people expect: you deallocate the VM, update the disk SKU in place, and restart. There is no new disk to create, no data to copy, and no disk swap. The existing disk is converted to Premium SSD v2 with the same name and resource ID it always had.

· 10 min read
Hasan Gural

Hello Friends,

One of the projects I was recently involved in brought something to my mind that I have been wanting to write about for a while. The team had a solid Azure footprint, a mature DevOps practice, and a FinOps initiative that was starting to ask the right questions about where the money was actually going. When we pulled the disk inventory, the answer was staring back at us: disk after disk on Premium SSD, sized at 2,048 GiB to reach 7,500 IOPS, running workloads that were using 300 GiB of actual storage. The performance need was driving the disk size, not the other way around, and the team had no idea because that is just how Premium SSD works.

This is exactly the kind of spend that FinOps conversations surface once you get past the shiny dashboards and start looking at the actual resource configuration. You are not paying for something wasteful, you are paying for the model. The billing is working exactly as designed. The problem is the design itself, and Premium SSD v2 changes it entirely. Storage, IOPS, and throughput become three independent dimensions you configure and pay for separately. If you only need 300 GiB and 4,000 IOPS, that is precisely what you provision and precisely what you pay for.

In this three-part series I want to walk through the full picture: why the old model creates this pattern, how to identify which disks in your environment are worth migrating, how the migration itself works, and what to do after migration to keep the economics working in your favour. In Part 2 we go through the direct in-place conversion with PowerShell and Bicep. In Part 3 we cover right-sizing, monitoring, and cost governance after migration.

· One min read
Hasan Gural

I had a fantastic time speaking at Global Azure 2025 in Istanbul (May 8–10). The session was recorded and I published the video on YouTube. I am sharing the recording of my talk, "Automating Azure PIM Role Assignments with Terraform". Whether you attended live or couldn’t make it, you can now watch the full session at your convenience.

GlobalBootCamp2025