AzureToolsBD09.psm1
<# Functions in this module
Get-AzVmAsgAssociation Get-AzPeeringType Find-AzRoleFromAction Get-AzAsgMembership #> function Get-AzVmAsgAssociation { <# .SYNOPSIS This command shows the association between the Azure VMs and any ASG they may be associated with .DESCRIPTION Because it is difficult to see which VMs are associated with ASGs in the Azure Portal, This command retrieves the inforation about which VMS are associated with which ASG and displays the information regarding ASG name, Network Interface Name, NIC Id and VM Name .PARAMETER AsgName You can specify which ASGs to match, if you do not select any, all ASGs will be assumed .NOTES Created By: Brent Denny Created On: 26-Jun-2024 .EXAMPLE Get-AzVmAsgAssociation -AsgName ASG1 This will display all Azure VMs that are associated with ASG1 .EXAMPLE Get-AzVmAsgAssociation This will display all Azure VMs that are associated all ASGs #> [CmdletBinding()] Param ([string]$AsgName = '') try { if ($AsgName -eq '') {$AllAzAsgs = Get-AzApplicationSecurityGroup} else {$AllAzAsgs = Get-AzApplicationSecurityGroup -Name $AsgName -ErrorAction Stop} } catch { Write-Warning "No ASG with the name of $AsgName can be found" break } $AllAzNics = Get-AzNetworkInterface $AllAzVms = Get-AzVm $Results = @() foreach ($Asg in $AllAzAsgs) { foreach ($Interface in $AllAzNics) { $InterfaceAssociatedAsgs = $Interface.IpConfigurations.ApplicationSecurityGroupstext | ConvertFrom-Json if ($Asg.Id -in $InterfaceAssociatedAsgs.Id) { $Results += [PSCustomObject]@{ AsgName = $Asg.Name NicName = $Interface.Name NicId = $Interface.Id VMName = ($AllAzVms | Where-Object { $_.NetworkProfile.NetworkInterfaces.id -contains $Interface.Id }).Name } } } } return $Results } function Get-AzPeeringType { <# .SYNOPSIS Lists all of the Azure virtual networks peerings and determines their type .DESCRIPTION This cmdlet finds all of the virtual networks that have peerings and determines if the peering is a global or regional type of peering. It will also show Virtual Networks that do not have any peerings as well. There are restrictions on what you can do with a global peering so it is important to know which peering is what type. This command will prompt you if you need to login to Azure via a Connect-AzAccount command You cannot use Global VNet peering to communicate with VIPs of load balancers in another region. VIP communication requires source IP to be on the same VNet as the LB IP: Resources in one virtual network cannot communicate with the IP address of an Azure internal load balancer in the peered virtual network. .EXAMPLE Get-AzPeeringType This will show all peerings (Global, Regional and NoPeering). .EXAMPLE Get-AzPeeringType -PeeringFilter Global This will only show peerings of a Global type .EXAMPLE Get-AzPeeringType -PeeringFilter NoPeering This will only show VNets that do not have any peering configured .PARAMETER PeeringFilter This will filter the peerings so that either a single peering type is shown or all are shown. The values for the PeeringFilter are: Regional - Shows only Regional Global - Shows only Global All - Shows all types of peering NoPeering - Shows only VNets with no peerings .NOTES General notes Created by: Brent Denny Created on: 6 May 2020 Last Modified: 1 Jul 2020 #> [cmdletbinding()] Param( [ValidateSet('Regional','Global','All','NoPeering')] [string]$PeeringFilter = 'All' ) try {Get-AzSubscription -ErrorAction Stop > $null} catch {Connect-AzAccount} try { $VNets = Get-AzVirtualNetwork -ErrorAction Stop foreach ($VNet in $VNets){ if ($VNet.VirtualNetworkPeerings.Count -ge 1) { $Peerings = $VNet.VirtualNetworkPeerings foreach ($Peering in $Peerings) { $PeerID = $Peering.remotevirtualnetwork.Id $PeerName = $PeerID -replace '.+\/(.+)$','$1' $PeerVNetInfo = $VNets | Where-Object {$_.Id -eq $PeerID} $PeerVNetLocation = $PeerVNetInfo.Location if ($VNet.Location -eq $PeerVNetLocation) {$PeerType = 'Regional'} else {$PeerType = 'Global'} if ($PeeringFilter -eq $PeerType -or $PeeringFilter -eq 'All') { $Hash = [ordered]@{ VNetName = $VNet.Name ResourceGroup = $VNet.ResourceGroupName VNetLocation = $VNet.Location PeeringVNet = $PeerName PeeringVNetLocation = $PeerVNetLocation PeeringType = $PeerType VNetID = $VNet.Id } New-Object -TypeName psobject -Property $Hash } } } else { if ($PeeringFilter -eq 'NoPeering' -or $PeeringFilter -eq 'All') { $Hash = [ordered]@{ VNetName = $VNet.Name ResourceGroup = $VNet.ResourceGroupName VNetLocation = $VNet.Location PeeringVNet = 'No Peerings' PeeringVNetLocation = 'N/A' PeeringType = 'N/A' VNetID = $VNet.Id } New-Object -TypeName psobject -Property $Hash } } } } catch { Write-Warning 'An error occured trying to access the Virtual Networks'} } function Find-AzRoleFromAction { <# .SYNOPSIS This command finds Azure Roles that contain an action or a devolved action .DESCRIPTION This command will find an Azure Role based on the Actions contained within it. It will also check the NotActions to make sure the requested action is not in this property. It will then devolve the action to include a wildcard and also a wildcard with the original action as follows: Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete Microsoft.Storage/storageAccounts/blobServices/containers/blobs/* Microsoft.Storage/storageAccounts/blobServices/containers/*/delete Microsoft.Storage/storageAccounts/blobServices/containers/* Microsoft.Storage/storageAccounts/blobServices/*/delete Microsoft.Storage/storageAccounts/blobServices/* Microsoft.Storage/storageAccounts/*/delete Microsoft.Storage/storageAccounts/* Microsoft.Storage/*/delete Microsoft.Storage/* It will then show all of the roles that contain any of these actions .EXAMPLE Find-AzRoleFromAction -Action 'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete' This will find all Roles that have this action and not have this action in the NotActions. If it cannot find the specific action, it will then devolove the action to be more broad in its search. Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete Microsoft.Storage/storageAccounts/blobServices/containers/blobs/* Microsoft.Storage/storageAccounts/blobServices/containers/*/delete Microsoft.Storage/storageAccounts/blobServices/containers/* Microsoft.Storage/storageAccounts/blobServices/*/delete Microsoft.Storage/storageAccounts/blobServices/* Microsoft.Storage/storageAccounts/*/delete Microsoft.Storage/storageAccounts/* Microsoft.Storage/*/delete Microsoft.Storage/* .EXAMPLE Find-AzRoleFromAction -Action 'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete' -DevolutionLevel 2 This will find all Roles that have this action and not have this action in the NotActions. If it cannot find the specific action, it will then devolove the action to be more broad in its search but it will only devolve two levels. Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete Microsoft.Storage/storageAccounts/blobServices/containers/blobs/* Microsoft.Storage/storageAccounts/blobServices/containers/*/delete Microsoft.Storage/storageAccounts/blobServices/containers/* .PARAMETER Action This is the action that needs to be found within an existing Azure Role. The Actions are in this format: Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete .PARAMETER DevolutionLevel This instructs the command to only devole the permission a certian number of times, shown in example 2 .NOTES Created By: Brent Denny Created on: 05-Aug-2024 #> [cmdletbinding()] Param ( [Parameter(Mandatory=$true)] [ValidatePattern('^[a-z]+(\.[a-z]+)+(\/.*)+$')] [string]$Action, [int]$DevolutionLevel = 0 ) function Resolve-Actions { Param ($ResolveAction) $DataArray = $ResolveAction -split '\/' $MaxIndex = $DataArray.Count - 2 $FirstPass = $true $Actions = foreach ($Index in ($MaxIndex..0)) { if ($FirstPass -eq $true) { $ResolveAction ($DataArray[0..$Index] -join '/') + '/*' $FirstPass = $false } else { ($DataArray[0..$Index] -join '/') + '/*' + "/$($DataArray[-1])" ($DataArray[0..$Index] -join '/') + '/*' } } return $Actions } $PossibleRoles = @() $DevolvedActions = Resolve-Actions -ResolveAction $Action $DevolutionCount = 0 foreach ($DevolvedAction in $DevolvedActions) { $DevolutionCount++ Write-Verbose $DevolvedAction $Role = Get-AzRoleDefinition | Where-Object {$_.Actions -contains $DevolvedAction -and $_.NotActions -notcontains $Action} if ($Role.Count -gt 0) {$PossibleRoles += $Role} if ($DevolutionLevel -ne 0 -and $DevolutionCount -eq ($DevolutionLevel * 2)) {break} } return $PossibleRoles } function Get-AzAsgMembership { <# .SYNOPSIS This lists the computers and their NICs that are in an ASG .DESCRIPTION Listing an ASG membership is difficult, the only way via the GUI is to visit each computer and check to see if it is a member of an ASG, if you had 100's of VMs this would be impractical. .NOTES Created By: Brent Denny Created On: 7-Nov-2023 .EXAMPLE Get-AzAsgMembership This command will list all of the ASGs and any VM that is a member of each ASG along with their NIC #> [CmdletBinding()] Param () try {Get-AzSubscription -ErrorAction Stop *> $null} catch { try {Connect-AzAccount -ErrorAction Stop *> $null} catch {Write-Warning "Please download the AZ module from PowerShell Gallery before running this again"; break} } $AzNics = Get-AzNetworkInterface $VMs = Get-AzVM $ASGs = Get-AzApplicationSecurityGroup foreach ($ASG in $ASGs) { $MatchingNics = $AzNics | Where-Object {($_.IpConfigurations.ApplicationSecurityGroupsText | ConvertFrom-Json).ID -eq $ASG.Id} foreach ($MatchingNic in $MatchingNics) { $MatchingVM = $VMs | Where-Object {$_.NetworkProfile.NetworkInterfaces.Id -contains $MatchingNic.Id} if ($MatchingVM) { [PSCustomObject][Ordered]@{ ASG = $ASG.Name VM = $MatchingVM.Name NIC = $MatchingNic.Name } } } } } |