SACRED.Util.Azure.psm1
<#
Copyright (c) 2023 Chris Clohosy 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. #> using module SACRED.Log Function Connect-SACREDToAzure ( [Parameter(Mandatory=$false)] [string] $AzureTenantId = '', [Parameter(Mandatory=$false)] [switch] $UseAzureManagedIdentity, [Parameter(Mandatory=$false)] [string] $AzureServicePrincipalClientId = '', [Parameter(Mandatory=$false)] [string] $AzureServicePrincipalClientSecret = '', [Parameter(Mandatory=$false)] [string] $AzureServicePrincipalClientCertificateThumbprint = '' ) { <# .SYNOPSIS Connects SACRED to Azure. .DESCRIPTION Connects SACRED to Azure. SACRED can connect to Azure using a managed identity, a service principal with a secret, or a service principal with a certificate. .PARAMETER AzureTenantId The ID of the Azure tenant to connect to. .PARAMETER UseAzureManagedIdentity Indicates that SACRED should connect to Azure using a managed identity. .PARAMETER AzureServicePrincipalClientId The ID of the Azure service principal to connect to Azure with. .PARAMETER AzureServicePrincipalClientSecret The secret of the Azure service principal to connect to Azure with. .PARAMETER AzureServicePrincipalClientCertificateThumbprint The thumbprint of the certificate of the Azure service principal to connect to Azure with. .INPUTS None .OUTPUTS None #> if($UseAzureManagedIdentity) { $global:SACREDLogger.Info("Connecting to Azure using a managed identity.") Connect-AzAccount -Identity -WarningAction SilentlyContinue | Out-Null } elseif($AzureServicePrincipalClientId -ne '') { if($AzureServicePrincipalClientSecret -ne '') { $global:SACREDLogger.Info("Connecting to Azure with a secret, using the client ID $AzureServicePrincipalClientId.") $secureAzureServicePrincipalClientSecret = ConvertTo-SecureString -String $AzureServicePrincipalClientSecret -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($AzureServicePrincipalClientId, $secureAzureServicePrincipalClientSecret) Connect-AzAccount -ServicePrincipal -TenantId $AzureTenantId -Credential $credential -WarningAction SilentlyContinue | Out-Null } elseif($AzureServicePrincipalClientCertificateThumbprint -ne '') { $global:SACREDLogger.Info("Connecting to Azure with certificate thumbprint $AzureServicePrincipalClientCertificateThumbprint, using the client ID $AzureServicePrincipalClientId.") Connect-AzAccount -CertificateThumbprint $AzureServicePrincipalClientCertificateThumbprint -ApplicationId $AzureServicePrincipalClientId -Tenant $AzureTenantId -ServicePrincipal -WarningAction SilentlyContinue | Out-Null } } else { $global:SACREDLogger.Info("Connecting to Azure using an interactive logon prompt.") Connect-AzAccount -WarningAction SilentlyContinue | Out-Null $global:SACREDLogger.Info("Connected to Azure as $((Get-AzContext).Account.Id).") } } Function Get-SACREDAzureContextForResource ( [Parameter(Mandatory=$true)] [string] $ResourceName, [Parameter(Mandatory=$false)] [string] $ResourceGroupName, [Parameter(Mandatory=$true)] [string] $ResourceType ) { <# .SYNOPSIS Gets the Azure context for a resource. .DESCRIPTION Gets the Azure context for a resource. This function will search all subscriptions for the resource and return the context for the subscription containing the resource. .PARAMETER ResourceName The name of the resource. .PARAMETER ResourceGroupName The name of the resource group containing the resource. .PARAMETER ResourceType The type of the resource. .INPUTS None .OUTPUTS None #> $global:SACREDLogger.Info("Locating correct Azure subscription for resource $ResourceName of type $ResourceType in resource group $ResourceGroupName.") $contextConverter = New-Object -TypeName Microsoft.Azure.Commands.Profile.Models.AzureContextConverter $subscriptions = Get-AzSubscription -WarningAction SilentlyContinue foreach($subscription in $subscriptions) { $subscriptionId = $subscription.SubscriptionId $tenantId = $subscription.TenantId $resourceContext = Set-AzContext -Scope Process -SubscriptionId $subscriptionId -TenantId $tenantId $resourceContextContainer = $contextConverter.ConvertFrom($resourceContext, [Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer], $null, $true) if(($ResourceGroupName -ne $null) -and ($ResourceGroupName -ne '')) { $desiredResource = Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroupName -ResourceType $ResourceType -DefaultProfile $resourceContextContainer -ErrorAction SilentlyContinue } else { $desiredResource = Get-AzResource -Name $ResourceName -ResourceType $ResourceType -DefaultProfile $resourceContextContainer -ErrorAction SilentlyContinue } if($desiredResource -ne $null) { $global:SACREDLogger.Info("Found resource $ResourceName in subscription $($resourceContext.Subscription.Name).") return $resourceContextContainer } } #If this point has been reached then resource was not found in any subscription $errorMessage = "No subscription found containing $ResourceName of type $ResourceType in group $ResourceGroupName" $global:SACREDLogger.Error($errorMessage) throw [System.Exception] $errorMessage } Function Connect-SACREDToMicrosoftGraph ( ) { <# .SYNOPSIS Connects SACRED to Microsoft Graph. .DESCRIPTION Connects SACRED to Microsoft Graph. SACRED will connect using the existing Az connection that has been established. .INPUTS None .OUTPUTS None #> $global:SACREDLogger.Info("Connecting to Microsoft Graph using existing Az connection.") Connect-MgGraph -AccessToken (Get-AzAccessToken -ResourceTypeName MSGraph).Token | Out-Null } |